Creating a Custom Timeline Entry

This page is intended for a technical audience that will be creating a Custom Timeline Entry. Check out the Custom Timeline Entry page for an overview.

When completed, this will create a timeline entry that looks like this:

A Custom Timeline Entry in a customer's timeline

Getting started

Before making any API calls, we need to decide what we want the Custom Timeline Entry to look like. You can use the Custom Timeline Entry playground (opens in a new tab) to prototype an entry.

In this example, we'll use the "Refund processed" template but the complete list of components that you can use in the Custom Timeline Entry is documented in Plain UI Components.

We'll use the upsertCustomTimelineEntry mutation, which allows us to create a new Custom Timeline Entry or update one if it exists. This mutation requires the following permissions:

  • timeline:create
  • timeline:edit

Creating a Custom Timeline Entry

This is important: remember to replace c_xxx with an existing customer's id. You can get a customer ID by upserting a customer

import { PlainClient } from '@team-plain/typescript-sdk';
 
const client = new PlainClient({
    apiKey: 'plainApiKey_xxx',
});
 
const res = await client.upsertCustomTimelineEntry({
    customerId: 'c_xxx',
    title: 'Refund processed',
    components: [
        {
            componentText: {
                text: 'Invoice **#1301** was refunded to customer',
            },
        },
        {
            componentSpacer: {
                spacerSize: 'XS',
            },
        },
        {
            componentText: {
                textSize: 'L',
                textColor: 'SUCCESS',
                text: '**+ $413.20**',
            },
        },
        {
            componentDivider: {
                spacingSize: 'M',
            },
        },
        {
            componentLinkButton: {
                url: 'https://stripe.com',
                label: 'View in Stripe',
            },
        },
    ],
});
 
if (res.error) {
    console.error(res.error);
} else {
    console.log(res.data);
}

Which will console.log:

{
    result: 'CREATED',
    timelineEntry: {
        id: 't_01H4BKTDKC1KBXTD5GB3M2NJBZ',
        customerId: 'c_01H418FYZWR7VZZG3MWBZQ0Q0Z',
        timestamp: {
            iso8601: '2023-07-02T15:33:54.924Z'
        },
        actor: {
            __typename: 'MachineUserActor',
            machineUserId: 'mu_01H04VKVPA1CBBZC059F6M33DB'
        },
        entry: {
            __typename: 'CustomEntry'
        }
    }
}

Side effects of Custom Timeline Entries

When upserting a Custom Timeline Entry, you can also optionally specify any side effects which allow you to control what happens after you create a new Custom Timeline Entry.

This is to support different kinds of entries. For example, when a significant error happens in your backend, and you create a Custom Timeline Entry, you might want to proactively reach out to the customer. Alternatively, if the customer makes a change to their account, you probably don't need to do anything.

changeCustomerStatusToActive

If set to true, the customer's state will change to ACTIVE, which will move them to the Waiting for Help queue. A notification will be sent (depending on notification settings) exactly as if a customer got in touch via email.

sendCustomTimelineEntryCreatedNotification

If set to true, a notification will be sent to the user assigned to the customer, if they have the corresponding setting enabled in their notification settings.

💁‍♂️

It's perfectly valid to set both of these fields to true at the same time. If you do this, the customer's state will move to ACTIVE and a notification will be sent to the assigned user and/or every other user in the workspace.