Custom connections require an endpoint to access. This can be in your application or in one of your backend services. When setting up an endpoint for this connection, there are a few things to keep in mind:
- The service will need to accept a
GET
request from Yetto with a hashed signature in theX_YETTO_SIGNATURE
header. - The service will need to be validate the request with a signing secret. We'll give you the signing secret when you first set up the connection.
- Your service will use the signing secret to decrypt the request parameter containing the payload from Yetto.
- The service will need to respond to all requests within three seconds. Yetto will only display data that comes back within that time.
- The service will need to respond to the request with valid JSON in the response body.
- The service will need to respond to a test request during setup.
- Yetto sends hashed data as a path parameter in the
GET
request. The path is appended to the URL path you set up in the webhook.
Let's walk through some of those items together.
Accepting and validating Yetto's request
When you first set up a customer connection, we'll share a signing secret with you. The signing secret will not be available on that page in the future, so be sure to copy and save it when first setting up the connection. That secret will be used to encode the payload of the GET
request, the result of which can be compared to the X_YETTO_SIGNATURE
header to confirm that the request came from us.
To validate the request:
- Get the signature value in the
X_YETTO_SIGNATURE
header of the YettoGET
request. - Remove the beginning characters "sha256=" from the signature value; the rest of the value is the signature string you'll compare against later.
- Get the path parameter string of the
GET
request and hash it, using the signing secret as the key. - Take the hex digest of the resulting hash, using the
HMAC-SHA256
algorithm. - Compare the hex digest you calculated to the signature value in the
X_YETTO_SIGNATURE
header of the request. If they match, the request is a legitimate Yetto customer connection request.
An example in Ruby on Rails might look like this:
# Get the Yetto header signature value
+yetto_signature = request.headers.fetch("X_YETTO_SIGNATURE", "")
+hmac_header = yetto_signature.split("sha256=").last
+
+# Calculate the hmac authentication digest using your signing secret
+encoded_yetto_payload = params['splat'].first
+calculated_hmac = OpenSSL::HMAC.hexdigest(SHA256_DIGEST, SIGNING_SECRET, encoded_yetto_payload)
+
+# Compare the calculated digest to the signature value in the header
+return true if ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, hmac_header)
+
Accept and respond to a Yetto request
Once you've validated that the request has come from Yetto, you can use the signing secret to decrypt Yetto's conversation payload. The payload is encrypted with the aes-256-gcm
OpenSSL Cipher. Many languages have native implementations for decrypting these types of messages. For example, in Ruby on Rails, one can use:
ActiveSupport::MessageEncryptor.new(SIGNING_SECRET, url_safe: true, serializer: :json).decrypt_and_verify(encoded_yetto_payload)
+
The GET
request parameter that Yetto sends will have data that looks like this:
{
+ "yetto": {
+ "conversation": {
+ "author": {
+ "name": "user@example.com",
+ },
+ "inbox": "ibx_01J3RB6WMJDPE5R84X0JVX3YX9",
+ },
+ }
+}
+
Use that to assemble data that you want to display in the conversation sidebar. You have three seconds to respond to Yetto's request with valid JSON. Yetto's customer connections accept JSON responses that look like this:
{
+ "version": "2024-03-06",
+ "customer": {
+ "id": "customer_12345",
+ "last_active": "10/15/2015"
+ "name": "Kelly Customer",
+ "plan_type": "Business"
+ },
+ "sections": [
+ {
+ "type": "link",
+ "title": "Link to customer details",
+ "description": "Application data",
+ "href": "https://example.com/customer/{{ data.customer.id }}"
+ },
+ {
+ "type": list,
+ "title": "List section",
+ "items": [
+ {
+ "description": "Name",
+ "value": "{{ data.customer.name }}"
+ },
+ {
+ "description": "Plan type",
+ "value": "{{ data.customer.plan_type }}"
+ },
+ {
+ "description": "Last active",
+ "value": "{{ data.customer.last_active }}"
+ }
+ ]
+ }
+ ]
+}
+
The version
string, customer
object, and sections
array are required fields.
The version
string is 2023-03-06
. We will update our documentation if and when this changes.
The customer
object can contain data to be used in the sections
fields. We use Liquid templating to populate fields, so you can store data here if you want to use it across more than one section
fields.
The sections
array contains the data you want displayed in the conversation sidebar in Yetto. It must be an array of valid objects, with a maximum of three sections.
Currently, the section
types we accept are link
and list
.
Section links
A link
can contain any URL that you want your Support team to have access to in the Yetto conversation. This could be a link to an admin page in your system or a link to a third-party billing tool that you use. This section has the following fields:
Field | Data type | Required |
---|---|---|
description | string | no |
href | string | yes |
title | string | no |
type | string | yes |
Section lists
A list
is an array of objects showing data that you want to see when viewing the conversation. Lists have the following fields:
Field | Data type | Required |
---|---|---|
items | array | yes |
title | string | no |
type | string | yes |
The items
objects have following fields:
Field | Data type | Required |
---|---|---|
description | string | no |
value | string | yes |
Using the customer
object
The customer
object is available for you to populate and use however you need it. When referencing customer
values, make sure to format them like this:
{{ data.customer.key }}
+
Pay attention to the double braces and the data.customer
structure.
Responding to a test request during setup
During the initial setup of a customer connection, Yetto will send a test request to your endpoint. That request can be validated using the signing secret as all other Yetto requests will be. This test request, however, will contain a X_YETTO_RECORD_TYPE
header with a value of verification
. The body will be encrypted with the same aes-256-gcm
OpenSSL cipher, and when decrypted, looks like this:
{
+ "yetto": {
+ "challenge": "39e34f256caed94513592cad6a89fce498da6aa1"
+ }
+}
+
Your system will need to return this challenge string to Yetto within three seconds. The test response should look like this:
{
+ "challenge": "39e34f256caed94513592cad6a89fce498da6aa1"
+}
+
Once we receive the correct challenge response from your endpoint, you'll be able to complete the [setup process](link to other doc).