Intent Tracking

Intents are an optional, advanced feature.

With Intents, you can roll up similar messages your bot sends to quickly see the combined metrics.

Here is how we define an intent:

  • intent – object – (optional)
    • name – string
    • inputs – array
      • input – object
        • name – string
        • value – string

Intents can be sent for either inbound or outbound messages. Place the intent object at the root level of the JSON that you send for each inbound or outbound message.

Adding an Intent for an inbound message

Example: “What is the weather in San Francisco?”

{
  "object": "page",
  "entry": [
    {
      "id": "943703799078240",
      "time": 1610433415282,
      "messaging": [
        {
          "sender": {
            "id": "1018952661536494"
          },
          "recipient": {
            "id": "943703799078240"
          },
          "timestamp": 1610433415282,
          "message": {
            "mid": "mid.1468531733396:9242db91fea253e355",
            "seq": 978,
            "text": "What is the weather in San Francisco?"
          }
        }
      ]
    }
  ]
}

Define Intent

The message “What is the weather in San Francisco?” maps to the WEATHER_QUERY Intent with the “city” entity “San Francisco”

{
  "name": "WEATHER_QUERY",
  "inputs": [
    {
      "name": "city",
      "value": "San Francisco"
    }
  ]
}

Append the Intent JSON to the original message

{
  "object": "page",
  "entry": [
    {
      "id": "943703799078240",
      "time": 1610433415282,
      "messaging": [
        {
          "sender": {
            "id": "1018952661536494"
          },
          "recipient": {
            "id": "943703799078240"
          },
          "timestamp": 1610433415282,
          "message": {
            "mid": "mid.1468531733396:9242db91fea253e355",
            "seq": 978,
            "text": "What is the weather in San Francisco?"
          },
          "intent": {
            "name": "WEATHER_QUERY",
            "inputs": [
              {
                "name": "city",
                "value": "San Francisco"
              }
            ]
          }
        }
      ]
    }
  ]
}

Post the complete message to Dimension

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=incoming&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"object":"page","entry":[{"id":"943703799078240","time": 1610470160394,"messaging":[{"sender":{"id":"1018952661536494"},"recipient":{"id":"943703799078240"},"timestamp": 1610470160394,"message":{"mid":"mid.1468531733396:9242db91fea253e355","seq":978,"text":"What is the weather in San Francisco?"},"intent":{"name":"WEATHER_QUERY","inputs":[{"name":"city","value":"San Francisco"}]}}]}]}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=incoming&apiKey=API_KEY_HERE

Notice, you must replace the placeholder API_KEY_HERE above with your api key.

Note
Notice that the Intent object is for each message in the array of messages (which is inside the entries array).

Adding an Intent for an outbound message

Example: “The weather is 68 degrees and sunny.”

{
  "qs": {
    "access_token": "<YOUR ACCESS TOKEN>"
  },
  "uri": "https://graph.facebook.com/v2.6/me/messages",
  "json": {
    "message": {
      "text": "The weather is 68 degrees and sunny."
    },
    "recipient": {
      "id": "1018952661536494"
    }
  },
  "method": "POST",
  "responseBody": {
    "recipient_id": "1018952661536494",
    "message_id": "mid.1470371655004:4727480467538e9450"
  }
}

Define Intent

The message “The weather is 68 degrees and sunny.” maps to the WEATHER_RESPONSE Intent with the “forecast” entity “68 and sunny”

{
  "name": "WEATHER_RESPONSE",
  "inputs": [
    {
      "name": "forecast",
      "value": "68 and sunny"
    }
  ]
}

Append the Intent JSON to the original message

{
  "qs": {
    "access_token": "<YOUR ACCESS TOKEN>"
  },
  "uri": "https://graph.facebook.com/v2.6/me/messages",
  "json": {
    "message": {
      "text": "The weather is 68 degrees and sunny."
    },
    "recipient": {
      "id": "1018952661536494"
    }
  },
  "method": "POST",
  "responseBody": {
    "recipient_id": "1018952661536494",
    "message_id": "mid.1470371655004:4727480467538e9450"
  },
  "intent": {
    "name": "WEATHER_RESPONSE",
    "inputs": [
      {
        "name": "forecast",
        "value": "68 and sunny"
      }
    ]
  }
}

Post the complete message to Dimension

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=outgoing&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"qs":{"access_token":""},"uri":"https://graph.facebook.com/v2.6/me/messages","json":{"message":{"text":"The weather is 68 degrees and sunny."},"recipient":{"id":"1018952661536494"}},"method":"POST","responseBody":{"recipient_id":"1018952661536494","message_id":"mid.1470371655004:4727480467538e9450"},"intent":{"name":"WEATHER_RESPONSE","inputs":[{"name":"forecast","value":"68 and sunny"}]}}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=outgoing&apiKey=API_KEY_HERE'

Notice, you must replace the placeholder API_KEY_HERE above with your api key.

Note
Notice that the Intent object is for each message in the array of messages (which is inside the entries array).

NotHandled Intent

It is very important to understand when a user says something to your bot that it does not understand.

By passing Dimension the NotHandled Intent, you can take advantage of the Not Handled report. There are two ways to set the NotHandled Intent:

Adding a NotHandled Intent

Prior to the dimension.logIncoming(request.body) call, add this line:

dimension.setNotHandled();

REST Integration: Adding a NotHandled Intent

If you are using the REST integration, set the intent name to NotHandled to make use of the special NotHandled reports.

Example: For Incoming Messages

{
  "object": "page",
  "entry": [
    {
      "id": "943703799078240",
      "time": 1610433652560,
      "messaging": [
        {
          "sender": {
            "id": "1018952661536494"
          },
          "recipient": {
            "id": "943703799078240"
          },
          "timestamp": 1610433652560,
          "message": {
            "mid": "mid.1468531733396:9242db91fea253e355",
            "seq": 978,
            "text": "This is a message that is not handled."
          }
        }
      ]
    }
  ]
}

Attach the NotHandled Intent

{
  "name": "NotHandled"
}

Append the Intent JSON to the original message

{
  "object": "page",
  "entry": [
    {
      "id": "943703799078240",
      "time": 1610433652560,
      "messaging": [
        {
          "sender": {
            "id": "1018952661536494"
          },
          "recipient": {
            "id": "943703799078240"
          },
          "timestamp": 1610433652560.
          "message": {
            "mid": "mid.1468531733396:9242db91fea253e355",
            "seq": 978,
            "text": "This is a message that is not handled."
          },
          "intent": {
            "name": "NotHandled"
          }
        }
      ]
    }
  ]
}

Post the complete message to Dimension

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=incoming&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"object":"page","entry":[{"id":"943703799078240","time":1610433652560,"messaging":[{"sender":{"id":"1018952661536494"},"recipient":{"id":"943703799078240"},"timestamp": 1610433652560,"message":{"mid":"mid.1468531733396:9242db91fea253e355","seq":978,"text":"This is a message that is not handled."},"intent":{"name":"NotHandled"}}]}]}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=incoming&apiKey=API_KEY_HERE

Notice, you must replace the placeholder API_KEY_HERE above with your api key.

Note
Notice that the Intent object is for each message in the array of messages (which is inside the entries array).

Tracking Events in a Conversation

Events

You may wish to track certain events in conversations, such as:

  • External URL Clicks
  • Social Shares
  • Revenue
  • Anything else…

JSON Format

The JSON that you can send to track an event is:

  • name – string (required)
  • userId – string (required)
  • conversationId – string (optional)
  • type – enum (required)
    • customEvent
    • revenueEvent
    • shareEvent
    • pageLaunchEvent

For each event type, you can pass additional properties:
customEvent

  • extraInfo – object (optional)

revenueEvent

  • amount – number (required)
  • referenceNumber – string (optional)
  • metadata – object (optional)

pageLaunchEvent

  • extraInfo – object (optional)

shareEvent

  • sharedMessage – object (optional)

referralEvent

  • name – string (required)
  • ref – string the referral tag (optional)
  • source – string the referral source (eg. ADS, WEB) (optional)
  • adid – _string an ID to identify the ad (optional)
  • refereruri – _string the URI that sent the referer(optional)

Tracking Custom Events

Post to the endpoint

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

The data to POST should pass the following data:

{
  "name": "trackMeEvent",
  "type": "customEvent",
  "userId": "967295313370594",
  "extraInfo": {
    "start": 1500504070512,
    "difference": 374,
    "end": 1500504070886
  }
}

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"name":"trackMeEvent","type":"customEvent","userId":"967295313370594","extraInfo":{"start":1500504070512,"difference":374,"end":1500504070886}}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE'

Tracking Revenue Events

Post to the endpoint

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

The data to POST should pass the following data:

{
  "name": "boughtSandwich",
  "type": "revenueEvent",
  "userId": "967295313370594",
  "amount": 17.45,
  "metadata": {
    "productName": "Ham Sandwich",
    "sku": "abc123123"
  }
}

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"name":"boughtSandwich","type":"revenueEvent","userId":"967295313370594","amount":17.45,"metadata":{"productName":"Ham Sandwich","sku":"abc123123"}}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE'

Notice, you must replace the placeholder API_KEY_HERE above with your api key.

Tracking Page Launch Events

Post to the endpoint

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

The data to POST should pass the following data:

{
  "name": "Launched Detail Page",
  "type": "pageLaunchEvent",
  "userId": "967295313370594",
  "extraInfo": {
    "url": "https://www.dimensionlabs.io/"
  }
}

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"name":"Launched Detail Page","type":"pageLaunchEvent","userId":"967295313370594","extraInfo":{"url":"https://www.dimensionlabs.io/"}}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE'

Notice, you must replace the placeholder API_KEY_HERE above with your api key.

Tracking Share Events

Post to the endpoint

https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE

Make sure to set the ‘Content-Type’ header to ‘application/json’ and to replace API_KEY_HERE with your api key.

The data to POST should pass the following data:

{
  "name": "sharedLink",
  "type": "shareEvent",
  "userId": "967295313370594",
  "sharedMessage": {
    "text": "come check out this bot"
  }
}

Sample cURL

curl -X POST -H "Content-Type: application/json"
     -d '{"name":"sharedLink","type":"shareEvent","userId":"967295313370594","sharedMessage":{"text":"come check out this bot"}}'
     'https://tracker.dimensionlabs.io/track?platform=facebook&v=11.1.0-rest&type=event&apiKey=API_KEY_HERE'

Notice, you must replace the placeholder API_KEY_HERE above with your api key.

Live Person Takeover Integration

Overview

Dimension enables Live Person Takeover of bots to insert a real person into a session stream, improving engagement and increasing conversions.

When viewing a live session from the Transcripts report, you can send messages as if they are coming from the bot.

In order to take over the session, you need to pause the bot, otherwise the bot will continue to respond to subsequent messages from the user.

Create a Webhook

The first step is to create a webhook for your bot that handles pausing the bot.

Facebook Messenger Pause Webhook

Your webhook will recieve two fields in the body:

  • userId
    • the facebook user id of the session to pause
  • paused
    • true = pause the bot
    • false = unpause the bot

While the details of the implementation may vary, at a high level, your webhook should keep track of which user sessions are paused. Whenever a new message is received, check if the session is paused for that user, and if so, stop the bot from responding.

Example

This is basic example that maintains state in memory. For a more robust solution, save the state in a database or other persistent memory store.

const pausedUsers = {}
app.post('/pause', jsonParser, (req, res) => {
    const { paused, userId } = req.body
    pausedUsers[userId] = paused
    res.send('ok')
})

And then, check the status after receiving a message:

app.post('/webhook/', jsonParser, (req, res) => {
  dimension.logIncoming(req.body);
  if (req.body.entry){
    req.body.entry.forEach((entry) => {
      if (entry.messaging) {
        entry.messaging.forEach((event) => {
          const recipientId = event.sender.id;
          if (!pausedUsers[recipientId]) {
            // handle message if session is not paused for this userId
            [...]
          }
        }
      }
    }
  }
}

Add the Webhook URL to your Account

Go to your Account page and select ‘edit’ next to the bot you want to add a pause webhook to.

Enter the URL in the field and click ‘save’.

http://mycoolnewbot.io/pause

All requests to your webhook will be signed with the Dimension Secret Key, if provided.

Try it out

Start a new session with your bot and open the session from the Live Transcripts report.

Click the ‘pause’ button to stop the bot from responding.

Type a message in the form. The message will be sent as if coming from the bot.

Try typing a message to the bot as a user. The bot should not respond after the pause button has been selected.

Click ‘unpause’ to unpause the bot and return it to normal functionality.

Now if you type a message to the bot as a user, the bot should respond.

Tracking Custom User Metadata

You can send any custom user metadata to build detailed audience segments.

Custom user metadata can be sent for both incoming and outgoing messages.

Examples of metadata that you might send:

  • Your own User ID
  • Experiment Group, for A/B Testing
  • Favorite Book
  • Location

Incoming Messages

Define and add custom user parameters inside the message field.

 {
 "object": "page",
 "entry": [
  {
   "id": "1761187137541529",
   "time": 1529364165626,
   "messaging": [{
      "sender": {
        "id": "967295313370594"
      },
      "recipient": {
        "id": "1761187137541529"
      },
      "timestamp": 1529364165301,
      "message": {
        "mid": "mid.$cAAZBymTGuo5qRnp6tVkFTUyjOOfm",
        "seq": 20809,
        "text": "add user info"
      },
      "platformUserJson": {
        "favoriteBook": "Harry Potter and the Goblet of Fire",
        "ABTestGroup": "A"
      }
   }]
  }
 ]
}

Outgoing Messages

{
 "url": "https://graph.facebook.com/v2.6/me/messages",
 "qs": {
  "access_token": "EAADUlFUZBhlMBAOD5EUf8YErqZBppwsrblZAfWZA3N9ATYlh7fVKLHimoHcbT1KUyHrBGDtknTxmNP65ZCXc9pkjTxnZAWwZBWB4WxFKtiDR2u7LLrdrHU39Y2SB6VJAHpv2130skUpV0MXCAp4VJaI40DgBc59E2c3zsSTE0O4dAZDZD"
 },
 "method": "POST",
 "json": {
  "recipient": {
   "id": "967295313370594"
  },
  "message": {
   "text": "You are right when say: add user info"
  }
 },
 "platformUserJson": {
    "favoriteBook": "Harry Potter and the Goblet of Fire",
    "ABTestGroup": "A"
 },
 "responseBody": {
  "recipient_id": "967295313370594",
  "message_id": "mid.$cAAZBymTGuo5qRnp-nFkFTU2Blcaf"
 }
}