Introduction
Webhooks reference
a great feature of 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 https //developer mozilla org/en us/docs/web/http/methods/post by the kindly backend to a specific url for a step by step introduction to webhooks, check out the getting started with webhooks docid 6arn mwe7wuxvx0f8tpaq see example chat transcript webhook docid\ tcfg52zbqm7 oyque5raj 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 organization id the id of the organization to which the chat belongs bot id the id of the bot to which the chat belongs 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 chat labels the labels associated with this chat 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 https //docs kindly ai/webhooks#wjkhj context the collected chat context of the conversation read more about context context memory docid\ pajwnqixpwkcl7iktikt0 links linked rest resources object (f ex chat transcripts) chat if your webhook service requires more information about the chat or the previous messages, this can be fetched from the chat transcript api with a get request to the url in links chat chat transcript api docid 8m952znxllj5btmb976ui 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 payload 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" }, "labels" \["label name 1", "label name 2"] } 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\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 do 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/", "open in new tab" false, }, { "button type" "email", "label" "email name\@example com", "value" "name\@example com" }, { "button type" "phone", "label" "phone 123 456 789", "value" "123 456 789" }, { "button type" "dialogue trigger", "label" "read more", "value" "\<dialogue id> or \<dialogue slug>" } ] } you can also automatically define additional context when a button is clicked, using the context key on any button { "reply" "what kind of ice cream do you prefer", "buttons" \[ { "button type" "dialogue trigger", "label" "chocolate", "value" "\<dialogue id> or \<dialogue slug>", "context" { "favorite ice cream" "chocolate" } }, { "button type" "dialogue trigger", "label" "vanilla", "value" "\<dialogue id> or \<dialogue slug>", "context" { "favorite ice cream" "vanilla" } }, ] } image carousel you can send one or multiple images { 	"image carousel" \[ 	 { 	 "id" "id1", 	 "title" "carousel title", 	 "description" "this is a nice carousel", 	 "imageurl" "https //via placeholder com/640x360", 	 "linkurl" "example com", 	 "buttons" \[ 	 { 	 "id" "id1", 	 "value" "example com", 	 "label" "open link", 	 "button type" "link" 	 }, 	 { 	 "id" "id2", 	 "value" "dialogue id of the dialogue to trigger", 	 "label" "trigger dialogue", 	 "button type" "trigger dialogue" 	 } 	 ] 	 } 	] } the image carousel field must be an array of image objects every object must contain metadata for a single image you can attach buttons to specific images in the carousel we currently support trigger dialogue link quick reply form you can integrate a form into the bot reply you can include up to 5 fields per form { "form" { "language code" "en", "texts" { "title" "form title", "submit button text" "send", "cancel button text" "cancel", "cancel text" "formwasexited", "error text" "anerroroccurred", "unanswered text" "formwasnotanswered" }, "fields" \[ { "input type" "text", "required" false, "order" 0, "slug" "name", "texts" { "label" "name", "placeholder text" "name" } } ] } } language code specifies the language used in the form texts contains text elements for various parts of the form title title of the form submit button text text for the submit button cancel button text text for the cancel button cancel text message when the form is exited error text message when an error occurs unanswered text message when the form is left unanswered fields array of objects, each representing a field in the form required indicates if the field is mandatory ( true or false ) order numerical order of the field in the form slug (optional) a unique identifier for the field affix (optional) text or value affixed to the input field input type defines the type of the field, options include text for text input email for email addresses number for numerical values range for range values select for selection checkbox for checkboxes radio for radio buttons file for file uploads texts contains the following attributes for field text customization label the primary label text for the field help text (optional) additional help text for the field placeholder text (optional) placeholder text displayed inside the field required text (optional) text displayed for required fields affix value (optional) affixed text or value associated with the field validators (optional) list of objects defining validation rules for the field, which may include min length minimum length requirement max length maximum length limit maximum upper numerical limit minimum lower numerical limit pattern regex pattern for validation preset predefined validation type texts custom messages for validation feedback attributes (optional) additional properties for the field, including default value default value of the field step step size for numerical inputs options list of options value value of the option label display label of the option 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 labels you can attach some labels to the chat by passing a labels field { "labels" \["label name 1", "label name 2"] } you have to use label names the labels need to exist within the workspace to be attached, so if they can't be found they won't get triggered but they will not cause any error (i e they will just be omitted) 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 the supported file types are raw text, documents, images, and pdf 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)) ); } settings you can also pass some chat settings chatbubble hide input field to disable the chat input field make sure the user has a way to continue the conversation, for example by providing a button that triggers another dialogue { "chatbubble hide input field" true } smart webhooks this feature is currently in beta any feedback you might have can be sent on email directly to gjermund\@kindly ai and davide briano\@kindly ai you can utilize our smart webhooks docid\ vif7nnd7hv4c22oftenvw functionality by passing some data as aireply data you can find an example below { "aireply" { "data" { "id" "tshirt001", "name" "classic cotton t shirt", "description" "high quality, comfortable, 100% cotton t shirt perfect for everyday wear ", "categories" \["clothing", "tops", "casualwear"], "sizes" \["s", "m", "l", "xl"], "colors" \["red","blue","green"], } } } in this scenario, the reply field (if passed) will be ignored because the ai will generate the reply based on the data you provide in the field image (deprecated in favor of "image carousel") you can also send a single image { "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