Getting Started: A Quickstart Guide to the Automation Framework
Learn about prerequisites, API gateways, IP ranges, and bot registration required to work with the Automation Framework.
Understand what your bot can do
Review this list for ideas on what your bot can do via the Automation Framework.
Request Automation Framework enablement
Do this once, the first time that you use the Automation Framework.
Before you can use the Automation Framework, you must file a ticket with Khoros Support .
In your ticket:
- Request Support to enable the Automation Framework
- Request the Bot API access permission be given to one or more user accounts and provide the username(s) associated with the account(s). Preferably this is a dedicated service account, not an account associated with a specific user. Learn more about required user accounts and permissions for API access in this guide.
Note
Requests to the Automation Framework use Bot API v3, which requires a JWT access token for authentication; however, your request to generate the JWT is authenticated with Basic Auth. Once you have your JWT, all requests to Bot API V3 are authenticated with that JWT access token. We will walk you through token generation in the next section.
Once completed, you are ready to get started.
Get a unique access token for each bot
Do this one time for every unique bot that will use the Automation Framework.
To use the Automation Framework, you need an access token, and that access token is tied to an appId
that you specify for that bot. The access token you create is specific to that appId
and will work for that appId
only (across all the pages/handles that bot is registered with). You'll use this same appId
later when you register your bot.
A single bot can service multiple channels, but you can have as many bots as you want.
Important
There can only be one active access token for a given
appId
.
To generate an access token, make a POST request to https://[YOUR SERVER].response.lithium.com/api/v2/tokens/khorosapi/ownerId/ with a Basic Auth header (for a user that has Bot API access).
curl -u <username>:<password> -X POST \
https://[YOUR SERVER].response.lithium.com/api/v2/tokens/khorosapi/ownerId/{appId} \
If there is already a valid access token for this appId
, you will get an error, but you can retrieve the current token with a GET request to that same address. Otherwise, the response will contain an access token that will be valid for 90 days.
{
"status":"success",
"data":{
"token":<token>,
"expiresAtMillis":<epochMillis>
}
}
Use the access token for all subsequent interactions with the Automation Framework including refreshing the token before it expires 90 days after it is generated.
Refresh an Existing Access Token
Access tokens generally expire in 90 days: they must be refreshed or your integration will cease to operate.
Best Practice
We recommend refreshing the access token weekly to give yourself plenty of time to fix a problem with the access token if one occurs. Your bot should store this access token and have a job that refreshes storing the new version of the access token.
To refresh the access token, make a PUT request to:
- https://api.app.lithium.com/bots/v3/tokens/appId/{appId} for US-hosted customers
- https://api-eu.app.lithium.com/bots/v3/tokens/appId/{appId} for EU-hosted customers.
- https://api-ap.app.lithium.com/bots/v3/tokens/appId/{appId} for APAC-hosted customers.
curl -X PUT \
https://api.app.lithium.com/bots/v3/tokens/appId/{appId} \
-H "Authorization: Bearer [TOKEN TO BE REFRESHED]"
curl -X PUT \
https://api-eu.app.lithium.com/bots/v3/tokens/{appId} \
-H "Authorization: Bearer [TOKEN TO BE REFRESHED]"
curl -X PUT \
https://api-ap.app.lithium.com/bots/v3/tokens/{appId} \
-H "Authorization: Bearer [TOKEN TO BE REFRESHED]"
At this point, you have a token to call the Automation Framework API and you are ready to register your bot for a page/handle.
Register your bot
Do this once for every unique page/handle that you want your bot to be aware of.
Now that you have an access token for your appId
, separately register the appId
for every page/handle that you want the bot to be aware of. This only needs to be done once, but you will update the registration if you ever want to turn off your bot on the particular page/handle.
From here on, you will make API calls to an API gateway that differs depending on whether you are calling an environment hosted in the US or the EU. If you have a development environment, it is hosted in the US). The gateways are:
- US hosted environments: https://api.app.lithium.com
- EU hosted environments: https://api-eu.app.lithium.com
- APAC hosted environments: https://api-ap.app.lithium.com
Tip
If you do not know where your Care instance is hosted and you see your first API calls fail, try the other gateway. If you still have issues making calls, contact Khoros Support .
To register an appId
for a specific page/handle, make a POST request to:
https://api.app.lithium.com/bots/v3/registrations (for US hosted customers), or [https://api-eu.app.lithium.com/bots/v3/registrations] (ref:registrations-post) (for EU hosted customers), or [https://api-ap.app.lithium.com/bots/v3/registrations] (ref:registrations-post) (for APAC hosted customers) with a bot registration payload .
{
"companyKey": "<companyKey>",
"platform": "LITHIUM",
"networkKey": "twitter",
"externalId": "<externalId>",
"appId": "<botId>",
"name": "<botName>",
"avatarUrl": "<optional avatar url>",
"contact": { "email": "<email to notify of problems>" },
"mode": "LIVE",
"publicFilter": {
"includeTargeted": true
},
"callbackUrl": "<url of your endpoint>",
"credentials": {
"type": "BASIC_AUTH",
"identity": "<username>",
"secret": "<secret>"
}
}
Here is a CURL example of registering an appId
for a specific page/handle using the json
payload in a payload.json
file in the same directory:
curl -X POST \
https://api.app.lithium.com/bots/v3/registrations \
--data @payload.json \
-H "Content-type: application/json; charset=utf-8" \
-H "Authorization: Bearer [TOKEN]"
curl -X POST \
https://api-eu.app.lithium.com/bots/v3/registrations \
--data @payload.json \
-H "Content-type: application/json; charset=utf-8" \
-H "Authorization: Bearer [TOKEN]"
curl -X POST \
https://api-ap.app.lithium.com/bots/v3/registrations \
--data @payload.json \
-H "Content-type: application/json; charset=utf-8" \
-H "Authorization: Bearer [TOKEN]"
We provide more details in Register a bot, but here are a few quick points about registration:
- To find your company key, log into Khoros Care and go to Account Admin > General Settings > Analytics API Settings.
- If you are registering for a Facebook page, the
networkKey
isfacebook
and theexternalId
is thepageId
of the Facebook page. - If you are registering for a Twitter handle, the
networkKey
istwitter
and theexternalId
is thehandleId
of the twitter handle. - For other channels, contact Khoros Support for the appropriate
networkKey
andexternalId
to use (networkKeys are simple -sms
,whatsapp
,wechat
. TheexternalId
will be specific to your social integration in Khoros Care) - The page/handle you are registering must already be configured in Khoros Care.
- For Twitter and Facebook, we recommend including
publicFilter.includeTargeted
set totrue
to get notifications about public posts. (As outlined later in Processing events, this will help identify someone who is already interacting with an agent publicly and is transitioning to a private conversation). - The
credentials
provided are for when we deliver events to thecallbackUrl
you specify. Your endpoint might ignore it, but you must provide values. - We strongly recommend registering your bot in production with the bot registration
mode
flag set to MAINTENANCE as early as possible in your production environment. See Bot operating modes for more information and best practices. - Your bot registration must also include a
contact
email address. This email address is used to receive notifications of changes in your bot's health. - In addition to Basic Auth, HMAC is another option for authenticating calls to your webhook.
- Events delivered to your endpoint will always come from the same IP Addresses. This is an added level of security you can use (and you might use it exclusively).
- For US-hosted customers, the IP addresses are:
- 52.24.77.39,
- 52.34.1.188
- 52.34.219.148
- For all EU hosted customers, the IP addresses are:
- 52.31.195.192
- 52.19.24.192
- 52.48.77.241
- For all APAC hosted customers, the IP addresses are:
- 3.24.0.209
- 13.238.214.164
- 3.104.161.16
Additional Notes:
- To get all registration, make a GET request to [API GATEWAY]/bots/v3/registrations/network/{networkKey}/externalId/{externalId} (with the bearer token Authorization header).
- To update a bot registration, you can make exactly the same call (we allow a POST to update an existing registration, but you could also do a PUT.
- To delete a registration, make a DELETE request with [API GATEWAY]/bots/v3/registrations/network/{networkKey}/externalId/{externalId}/appId/{appId} (with the bearer token Authorization header).
At this point, you have a registered bot (woo hoo!) and will receive events at the endpoint you specified in the callback URL.
Processing Events
This section highlights a few important points about event processing. Find more details about the information presented in this section in Working with webhooks.
Here is an example of an event of type message for FB that your endpoint will receive. You'll note there is a type
(in this case "message"), a coordinate
object that where the event is from, an "author" that indicates who the event is for, and an owner
object which indicated the current owner of this author.
{
"coordinate": {
"companyKey": "<companyKey>",
"networkKey": "<networkKey>",
"externalId": "<externalId>",
"messageId": "<messageId>",
"botId": "<botId>",
"scope": "<PUBLIC|PRIVATE>"<private|public>
},
"author": {
"id": "<authorId>"
},
"owner": {
"type": "<AGENT|BOT><bot|agent>",
"appId": "<botId>"
},
"publishedTS": <published epoch millis>,
"receivedTS": <received epoch millis>,
"type": "message"
"text": "<text>"
}
For all of these API calls, you will use the corresponding API gateway for your environment:
- https://api.app.lithium.com (for US-hosted customers), or
- https://api-eu.app.lithium.com (for EU-hosted customers), or
- https://api-ap.app.lithium.com (for APAC-hosted customers)
Below are some key introductory points:
- The bot receives all events even if it is not the owner. However, the bot can only send a message to the author if it is the owner. It can take all other actions.
- When you receive an event, you need to acknowledge it immediately with a 202 (or 200) response code. After that, you can process the event. Failure to acknowledge receipt of the event will result in Khoros believing the bot is unavailable and we'll do notifications and handoff occurring if appropriate.
If you are implementing a chat-bot, the two (2) most relevant actions are to respond and pass control to an agent.
- To respond, you make a POST request to [API GATEWAY]/bots/v3/respond with a response payload. The response payload for an event will be of the form:
{
coordinate: event.coordinate,
author: event.author,
type: "message",
text: "my bot response"
}
Learn more advanced message response options in the /bots/v3/respond API reference. You'll find examples of sending postback, quick replies, and structured messages.
- To handover to an agent, make a PUT request to [API GATEWAY]/bots/v3/control with a control payload. The control payload for an event to pass control to an agent will be of the form:
{
coordinate: event.coordinate,
author: event.author,
type: "control",
owner: {
type: "AGENT"
}
}
- Passing control to an AGENT adds a Bot Handoff tag to the conversation in Khoros Care. Be sure to configure of the routing in Khoros Care such that bot conversations are not routed to a queue that Agents belong to until the conversation has a bot handoff tag.
- Your bot will receive all events. Be explicit in processing the ones relevant to your use case.
- Ensure that a bot does not interrupt a conversation started in public, has an agent engaged, and has moved private. The simplest way to do this is to have public events delivered to you and pass control to AGENT if you ever see an agent response event.
An agent response event will be of type
= update
, operation
=AGENT_RESPONSE
with an agentResponse
object.
{
"coordinate": {
"scope": "PUBLIC",
...
},
"author": {...},
"type": "update",
"operation": "AGENT_RESPONSE",
"agentResponse": {
"publishDate": ,
"text": ""
},
"conversation": {...},
}
If your bot ever receives this event, the bot should always issue a control event to pass control to an agent (see control example above). It is ok to call pass control even if AGENT is the current owner. An if statement would look like this:
if (
event.type == "update" &&
event.operation == "AGENT_RESPONSE" &&
event.coordinate.scope == "PUBLIC"
)
{
//Pass control to agent
...
}
Twitter and the Automation Framework
As noted in the documentation, Twitter’s Developer Terms of Service (TOS) Section F.2 only allows us to distribute the IDs of Twitter messages systemically - and specifically not the content of the tweet. Other vendors may not be as adherent, but Khoros respects our partnership with Twitter.
In terms of the Automation Framework, this means that when you receive events from Khoros for Twitter, the event only contains the ID of the message and not the Tweet content itself.
If you need the content of the Twitter message, you will need to get the content from Twitter. For many chat-bot use cases, you only care about private Direct Messages (and not public Twitter messages). In any event, there are two designs for how to get the content of the IDs our events provide.
Refer to this article for more details and to ask questions.
Updated almost 4 years ago
Learn more about the Automation Framework in these guides