You can reply to a thread using the replyToThread mutation, as long as the thread’s communication channel is either EMAIL or SLACK. This information is available in the thread as the channel field.

If it is not possible to reply to a thread, you will get the mutation error code cannot_reply_to_thread and a message indicating why.

This operation requires the following permission:

  • thread:reply
import { PlainClient } from '@team-plain/typescript-sdk';

const client = new PlainClient({ apiKey: 'plainApiKey_xxx' });

const res = await client.replyToThread({
  threadId: 'th_01HD1G6649R1DK061W27VBT7QB',
  textContent: 'The plain text version of your reply goes here.',
  markdownContent: 'The markdown **version** of your _reply_ goes here.',
});

if (res.error) {
  console.error(res.error);
} else {
  console.log(res.data);
}

Where res.data is:

{}

Impersonation

Impersonation is exclusively available in our Scale plan. You can see all available plans in our pricing page.

This feature allows you to bring native messaging between your customers and Plain, straight into your own product.

With impersonation, you can reply to a thread on behalf of one of your customers: impersonated messages will show up as if they were sent by the customers themselves.

In order to impersonate a customer, provide the impersonation parameter in the replyToThread mutation, specifying the identifier of the customer you want to impersonate. You can pick any of the available customer identifiers (emailAddress, customerId or externalId)

{
  "impersonation": {
    "asCustomer": {
      "customerIdentifier": {
        "emailAddress": "blanca@example.com"
      }
    }
  }
}

The customer message will be processed differently based on the thread’s channel:

  • SLACK: a new Slack message will be sent to the thread, using the customer’s details
  • EMAIL: an email will be sent to the thread, where the sender will be your customer

When replying to an EMAIL thread, you can optionally add ‘CC’ and ‘BCC’ recipients by using the channelSpecificOptions parameter:

{
  "channelSpecificOptions": {
    "email": {
      // For CC'd recipients
      "additionalRecipients": [
        {
          "email": "peter@example.com",
          "name": "Peter"
        },
      ],
      // For BCC'd recipients
      "hiddenRecipients": [
        {
          "email": "finance@example.com"
        }
      ]
    }
  }
}

This operation requires the following permissions:

  • thread:reply
  • customer:impersonate
import { PlainClient } from '@team-plain/typescript-sdk';

const client = new PlainClient({ apiKey: 'plainApiKey_xxx' });

const res = await client.replyToThread({
  threadId: 'th_01HD1G6649R1DK061W27VBT7QB',
  textContent: 'Hi, I ran out of compute credits, how can I top them up?',
  markdownContent: 'Hi, I ran out of compute credits, how can I top them up?',
  impersonation: {
    asCustomer: {
      customerIdentifier: {
        emailAddress: 'blanca@example.com',
      },
    },
  },
  additionalChannelOptions: {
    email: {
      hiddenRecipients: [
        {
          email: 'customer-success@company.org',
        },
      ],
    },
  },
});

if (res.error) {
  console.error(res.error);
} else {
  console.log(res.data);
}