Webhooks

If the messaging channel that you want to use is not supported out of the box in Oracle Digital Assistant, you can use a webhook to manually integrate that channel.

To create a webhook channel, you need the following:
  • A publicly accessible HTTP messaging server that relays messages between the user device and your digital assistant (or skill) using a webhook.

    You implement this webhook with:

    • A POST call that enables the server to receive messages from your digital assistant.

    • A POST call that enables the server to send messages to your digital assistant.

  • The URI of the webhook call that receives your digital assistant’s messages (so the digital assistant knows where to send the messages).

  • The Webhook URL that’s generated for your digital assistant after you complete the Create Channel dialog (so that the message server can access your digital assistant).

To assemble these pieces into a webhook:
  1. Set up the server.

  2. To receive messages from your digital assistant, publish the POST call on the server.

  3. In the Create Channel dialog, enter a name and then:
    • Choose Webhook as the channel type.

    • Set Platform Version to 1.1 (Conversation Model).

    • Register the server as the recipient of your digital assistant’s messages by entering the URI to this POST call in the Outgoing Webhook URI field.

    • If needed, enter the session expiry and switch on Channel Enabled.


    Description of create_webhook_channel.png follows

  4. Click Create.

    Digital Assistant generates the webhook URL for your digital assistant and its Secret Key for encrypting messages. Keep the webhook URL handy, because it’s the pointer that your messaging server needs to send messages back to your digital assistant.
    Description of webhook_channel_config.png follows

  5. On your server, publish the second POST API, one that sends messages to your digital assistant using the webhook URL.

  6. Switch the Channel Enabled option on.

You can use the Digital Assistant's Node.js SDK to set up the sending of messages to and from your digital assistant.

Inbound Messages

The WebhookClient library in Oracle Digital Assistant's Node.js SDK simplifies the setting up of sending and receiving messages in Webhook channels. If you aren't using the SDK, here's what you need to know about creating inbound messages.

The call for sending messages to your digital assistant (or skill) must have:

  1. An X-Hub-Signature header containing the SHA256 value of the payload. The call includes functions that create this hash using Secret Key as the key.
    const body = Buffer.from(JSON.stringify(messageToBot), 'utf8');
        const headers = {};
        headers['Content-Type'] = 'application/json; charset=utf-8';
        headers['X-Hub-Signature'] = buildSignatureHeader(body, channelSecretKey);
    
    ...
    
    function buildSignatureHeader(buf, channelSecretKey) {
        return 'sha256=' + buildSignature(buf, channelSecretKey);
    }
    
    function buildSignature(buf, channelSecretKey) {
        const hmac = crypto.createHmac('sha256', Buffer.from(channelSecretKey, 'utf8'));
        hmac.update(buf);
        return hmac.digest('hex');
    }

    BOT_WEBHOOK_URL and BOT_WEBHOOK_SECRET are environment variables that you set on the Node server. Using these environment variables enables you to avoid hard-coding sensitive information directly in the webhook

  2. A JSON object with userId, profile, and messagePayload properties:
    {
     "userId": "33c0bcBc8e-378c-4496-bc2a-b2b9647de2317",
     "profile": {
        "firstName": "Bob",
        "lastName": "Franklin",
        "age": 45
       },
     "messagePayload": {....}
    }
    Property Description Type Required?
    userId A unique identifier for the user. This ID is specific to the caller. String Yes
    profile Properties that represent the user, like firstName and LastName. JSON object No
    messagePayload The messagePayload can be text, postback, attachment, and location. JSON object Yes
    Note

    If your skill or digital assistant needs to detect the user language, be sure that profile.locale and profile.languageTag are set to null in the Webhook messages.

Example Payloads: Inbound Messages

Message Type Example Payload
text
{
    "type": "text",
    "text": "hello, world!"
}
postback
{
  "type": "postback",
  "postback": {
    "state": "orderPizza",
    "action": "deliverPizza",
    "variables": {
      "pizzaSize": "Large",
      "pizzaCrust": "Thin",
      "pizzaType": "Hawaiian"
    }
  }
}
attachment
{
  "type": "attachment",
  "attachment": {
    "type": "image",
    "url": "https://image.freepik.com/free-icon/attachment-tool-ios-7-interface-symbol_318-35539.jpg"
  }
}
location
{
  "type": "location",
  "location": {
    "longitude": -122.265987,
    "latitude": 37.529818
  }
}

Outbound Messages

The WebhookClient library in Oracle Digital Assistant's Node.js SDK simplifies the setting up of sending and receiving messages in Webhook channels. If you aren't using the SDK, here's what you need to know about creating outbound messages.

You need to publish the calls in the JSON format that Digital Assistant expects, along with the authorization header.

The call for your digital assistant’s outbound messages includes:
  1. An X-Hub-Signature header containing the SHA256 value of the payload, calculated using the Secret Key as the key.
    Note

    Digital Assistant uses the X-Hub-Signature header to allow the recipient to authenticate your digital assistant as the sender and validate the integrity of the payload.
  2. A JSON payload containing the userID, a unique identifier that’s specified by the inbound message, the type, which can be text,attachment, and card. As shown in the following examples, both the text and card response types can have associated actions. Any of the response types can also include global actions.
    Response Type Example Payload
    text
    {
     "userId":"22343248763458761287
     "messagePayload": {
        "type": "text",
        "text": "Hello, how are you?"
         }
    }
    The following snippet show a text response with actions:
    {
     "userId":"22343248763458761287
     "messagePayload": {
        "type": "text",
        "text": "What do you want to do?",
        "actions": [
          {
            "type": "postback",
            "label": "Order Pizza",
            "postback": {
              "state": "askAction",
              "action": "orderPizza"
            }
          },
          {
            "type": "postback",
            "label": "Cancel A Previous Order",
            "postback": {
              "state": "askAction",
              "action": "cancelOrder"
          }
        ]
      }
    }
    card
    
    ...
    {
     "type": "card",
      "layout": "horiztonal",
      "cards": [
        {
          "title": "Hawaiian Pizza",
          "description": "Ham and pineapple on thin crust",
          "actions": [
            {
              "type": "postback",
              "label": "Order Small",
              "postback": {
                "state": "GetOrder",
                "variables": {
                  "pizzaType": "hawaiian",
                  "pizzaCrust": "thin",
                  "pizzaSize": "small"
                }
              }
            },
            {
              "type": "postback",
              "label": "Order Large",
              "postback": {
                "state": "GetOrder",
                "variables": {
                  "pizzaType": "hawaiian",
                  "pizzaCrust": "thin",
                  "pizzaSize": "large"
                }
              }
            }
          ]
        },
        {
          "title": "Cheese Pizza",
          "description": "Cheese pizza (i.e. pizza with NO toppings) on thick crust",
          "actions": [
            {
              "type": "postback",
              "label": "Order Small",
              "postback": {
                "state": "GetOrder",
                "variables": {
                  "pizzaType": "cheese",
                  "pizzaCrust": "thick",
                  "pizzaSize": "small"
                }
              }
            },
            {
              "type": "postback",
              "label": "Order Large",
              "postback": {
                "state": "GetOrder",
                "variables": {
                  "pizzaType": "cheese",
                  "pizzaCrust": "thick",
                  "pizzaSize": "large"
                }
              }
            }
          ]
        }
      ],
      "globalActions": [
        {
          "type": "call",
          "label": "Call for Help",
          "phoneNumber": "123456789"
        }
      ]
    }
    attachment The attachment response type can an image, audio file, or a video:
    
    ...
    {
      "type": "attachment",
      "attachment": {
        "type": "video",
        "url": "https://www.youtube.com/watch?v=CMNry4PE93Y"
      }
    }