Skip to content
Plain Help Center home
Plain Help Center home

Custom Channels

Plains API first infrastructure means that you never need to wait for an official integration to bring all of your customer channels and communications into your Support platform.

Custom Channels.png

Until we launch an official integration for a channel that you need. You can start bringing your customer messages in using custom middleware that accepts webhooks and makes POST requests.

Creating Customers

To make sure that all messages received through your channel are ingested into Plain, you should make sure that your middleware is able to create customers if they don't already exist, and match existing customers if they do.

Plains customer object requires an email address.

  • Find out what identifiers are passed from your custom channel message received events

  • Map relevant identifiers to Plain

  • Make sure that the middleware tries to match existing customers first, and creates them as a fallback instead of by default.

Sending Messages

  1. Messages created in Plain trigger a webhook

  2. Your middleware accepts that webhook

  3. Parse the required information out of it (message body, customerId, etc.)

  4. Then make a request to send that message into your new channel of choice

Receiving Messages

Accepting messages from your custom channel and writing them into Plain works the exact same way, but in reverse.

  • You’ll need to accept messages from your custom channel, often this is also done via webhooks (for example, with Whatsapp)

  • Then your middleware will need to parse that message and use the Plain GraphQL API to create a new thread or create a new message in an existing thread.

Matching Plain message authors to your Custom Channel

  • In order to match up the author / person info from Plain → your new channel, we recommend querying Plain on startup of your middleware for all of your Plain workspace users and save out their userId and name and along with else you might need.

    • GraphQL query users

    • This is necessary because once you receive our webhook when a message in Plain has been created, threads.chat_sent, there will be a field like payload.chat.createdBy.userId which will simply contain the userId of the user who authored the message in Plain. You will then be able to look up that userId in the list of users you grabbed earlier to get their name / email / whatever in order to use them in your next step, creating the message payload you’ll send to your custom channel’s API to create the message there.

Matching messages from your Custom Channel to Plain Threads

If your customers start conversations from your custom channel, you'll need to make sure that you're passing the custom channels customer identifier as a Customer externalID when upserting the customer. Which will need to be done before creating the thread. This is usually the customer's identifier in the channel, like their WhatsApp userId or similar.

For example, if you identify customers in a channel like Whatsapp by their phone number. You would upsert the Customer with their phone number as their ExternalID, then create the thread in Plain passing in that external ID.

Considerations

  • Custom channels will not look like 1st party channels and do not come with all the native features of first party channels like Email or Slack.

  • If you don't have a way of pairing a customer with their real email address on creation, you will need to add a temporary email address. Such as: channelidentifier@temp-yourcompany.com. If this is the case, use sendChat for replies instead of replyToThread.

  • Custom channels will simply show up as threads in the "API" channel in the "channel" selector across the app, and in filters (Custom views, Insights.etc).

  • You can't set custom icons. So if you built a Whatsapp integration you wouldn't be able to set a logo, or have a Whatsapp entry listed in any channel filtering and dropdowns.

  • We recommend using a label to always tag your custom channel's threads when they're created by your Middleware. That way you can filter / sort / report on your custom channel threads via that Label.

Examples:

Discourse

With Plain you can connect your Discourse community and automatically keep track of support requests via Plain.

This works by deploying a small node service which uses Plain and Discourse’s APIs. You can either self-host this little node service or we can deploy this for you.

Check out the example on Github →

This integration can be customised depending on the structure of your Discourse community and ideal support workflow. For example you could customise the priority, labels and assignee of support requests from Discourse based on their category, author and content.

Hubspot

This functionality is now supported by our first party Hubspot integration. It's provided here only as an architecture example

This integration automatically creates Hubspot tickets when threads are created in Plain.

  1. Receives thread.thread_created webhook from Plain

  2. Fetches thread details to get tenant ID

  3. Fetches tenant details to get HubSpot company ID (externalId)

  4. Creates HubSpot ticket associated with the company

  5. Automatically refreshes HubSpot token if expired

Check out the example on Github →