Webhooks reference

A great feature about Kindly is the ability to connect to third-party applications. This is achieved using webhooks. Webhooks can be added to any dialogue or fallback, and are simply sent by HTTP POST by the Kindly backend to a specific URL.

For a step by step introduction to webhooks, checkout the getting started with webhooks article.

See this page for an example of a webhook app.

Request payload

The POST request payload from Kindly to your webhook endpoint is a JSON serialized object containing multiple fields.

Here are the most important payload fields and what they represent:

  • chat_id - The chat ID is a UUID that defines the chat the message belongs to. This ID can be found in the inbox, in the URL of the page.

  • user_id - The user ID is a string, provided by the chat client that defines the user who triggered the webhook.

  • exchange - The dialogue (exchange) object that Kindly found and replied with when triggered by the webhook.

    • exchange_id - The exchange id is a UUID that defines the dialogue that triggered the webhook. It can be found in the URL of the build section, when editing the desired dialogue.

    • language_code - The language code indicating the dialogue language.

  • message - The exact phrase that the user wrote to trigger the webhook.

  • attachments - List of file attachments that user or agent has uploaded to a chat. Read more about it here

  • context- The collected chat context of the conversation. Read more about context here.

  • _links - Linked REST resources object (f.ex. chat logs).

    • chat - If your webhook service requires more information about the chat or the previous messages, this can be fetched from the Chat Log API with a GET request to the url in _links.chat. Read more about the Chat Log API.

  • source - Source is the name of the chat client that triggered the webhook. It can be one of the following web (chat bubble in the browser), facebook (Facebook Messenger), slack (Slack), app (Application API) or test (app.kindly.ai test chat bubble).

  • web_path - The current URL path for Kindly Chat web clients, which is useful if you are implementing search and want to bias it towards documents related to the current page.

  • web_host - The current URL host for Kindly Chat web clients.

  • web_url - The current URL for Kindly Chat web clients.

Response

An incoming webhook should be answered with a 200 OK JSON response.

Example

Here is an example response showing some of the most common fields.

{
  "reply": "Hello from server!",
  "buttons": [
    {
      "button_type": "quick_reply",
      "label": "Hello",
      "value": "Hi server!"
    }
  ],
  "image": "https://via.placeholder.com/640x360",
  "image_alt_text": "Optional alternative text for image",
  "new_context": {
    "user_email": "user@example.com"
  }
}

Reply

A string of text that will be displayed as a message from the bot.

{
  "reply": "Text that the bot will answer"
}

To split the message into paragraphs (seperate bubbles) use two consecutive new lines, i.e. \n.

{
  "reply": "Text that the bot will say\n\nText on new line"
}

Buttons

You can attach buttons to the reply. You can define the same types of buttons as you can in the platform.

It's important to note that the button object needs to be wrapped in an array, even if you only send a single button.

{
  "reply": "Text that the bot will say",
  "buttons": [
    {
      "button_type": "quick_reply",
      "label": "Hello",
      "value": "Hi"
    },
    {
      "button_type": "link",
      "label": "example.com",
      "value": "https://example.com/"
    },
    {
      "button_type": "email",
      "label": "Email name@example.com",
      "value": "name@example.com"
    },
    {
      "button_type": "phone",
      "label": "Phone 123 456 789",
      "value": "123 456 789"
    }
  ]
}

Image

You can also send a single image combined with a reply.

{
  "image": "https://via.placeholder.com/640x360",
  "image_alt_text": "Optional alternative text for image"
}

The image in the object needs to be a valid image URL. The alt text is the text Kindly will show if the image is unavailable.

New context

If your webhook service computes some new value that you want the chatbot to remember, you can send it as JSON in new_context.

If the key you are adding already exists in the bot's context memory, the value will be overwritten.

{
  "new_context": {
    "some_key": "some value"
  }
}

Trigger dialogue

Instead of sending a reply defined by the webhook server, you can also trigger a dialogue that you have defined in the Kindly platform.

{
  "exchange_id": "Dialogue ID"
}

or

{
  "exchange_slug": "Dialogue slug"
}

The dialogue ID is a UUID, and can be found on the page where you edit the dialogue, or in the URL of the page.

The dialogue slug is an optional value picked by you that can be used in place of the dialogue UUID. You can set the dialogue slug on dialogues with the trigger type.

Attachments

The list consists of Attachment objects that include a temporary signed url which is available for 30 minutes after the webhook payload is sent. This means that if you want to keep these attachments you need to download them from the given url and store them somewhere.

Here is an example

type Attachment = {
  created: string;
  name: string;
  url: string;
  size_kb: number;
  status: string;
  type: string;
};

const removeExpiredAttachment = (attachment: Attachment) =>
  new Date(attachment.created) >
  new Date(Date.now() - ATTACHMENT_LIFETIME_MINUTES * 60 * 1000);

async function downloadAndStoreAttachment(attachment: Attachment) {
  const data = await downloadFile(attachment.url); // your own implementation
  await storeFile(data); // your own implementation
}

async function processAttachments(attachments: Attachment[]) {
  return await Promise.allSettled(
    (attachments || [])
      .filter(removeExpiredAttachment)
      .map((attachment) => downloadAndStoreAttachment(attachment))
  );
}

Last updated