In order to clarify exactly what is being built, I'd like to explain the lifecycle of an event handled by both the chatops.ai router and DialogFlow. For any event to occur, the service-specific agent is deployed. A service is defined as a communication platform than can host chatbots, i.e. Slack, HipChat, Skype. For example, Slack defines custom bots as "Apps" even though chatops.ai bots take advantage of webhooks, their multiple API's via their API client (node.js?). In this example, Gunter, along with his Slack plugin, would be deployed onto slack and send out a ackPOST request to the event router.
The Agent is composed of both the service-specific deployment configurations (plugins) and their event router.
Via communication with the service-specific Agent, the even router will receive POSTed payload from Slack based on triggered events, webhooks, and any other configuration setup for service-specific use.
Once the event router has parsed the JSON, it stores (?) relevant information into the store; a library built to around an interface that allows multiple backends to be switch in and out without conflict. Google's DataStore k:v NoSQL service is the preferred store backend. Once complete, the event router parses the data into the correct format for POSTing to /query in DialogFlow, in order to retrieve a response from the users message. An example request and response is below.
POST https://api.dialogflow.com/v1/query?v=20150910
Headers:
Authorization: Bearer YOUR_CLIENT_ACCESS_TOKEN
Content-Type: application/json
POST body:
{
"contexts": [
"shop"
],
"lang": "en",
"query": "I need apples",
"sessionId": "12345",
"timezone": "America/New_York"
}
Response:
{
"id": "3622be70-cb49-4796-a4fa-71f16f7b5600",
"lang": "en",
"result": {
"action": "pickFruit",
"actionIncomplete": false,
"contexts": [
"shop"
],
"fulfillment": {
"messages": [
{
"platform": "google",
"textToSpeech": "Okay how many apples?",
"type": "simple_response"
},
{
"platform": "google",
"textToSpeech": "Okay. How many apples?",
"type": "simple_response"
},
{
"speech": "Okay how many apples?",
"type": 0
}
],
"speech": "Okay how many apples?"
},
"metadata": {
"intentId": "21478be9-bea6-449b-bcca-c5f009c0a5a1",
"intentName": "add-to-list",
"webhookForSlotFillingUsed": "false",
"webhookUsed": "false"
},
"parameters": {
"fruit": [
"apples"
]
},
"resolvedQuery": "I need apples",
"score": 1,
"source": "agent"
},
"sessionId": "12345",
"status": {
"code": 200,
"errorType": "success"
},
"timestamp": "2017-09-19T21:16:44.832Z"
}
It is not handed off for preparation for an API called to the integration router. This is where integration's, not services, communicate via API requests from the integration router. A plugin consists of a few parts:
The API client
The DialogParser, which runs on the integration router (proposal PR linked)
An intents/ folder with DialogFlow intents
An entities/ folder with DialogFlow entities
A data/ folder with .txt files containing train data; one sentence per line.
Once the API client returns the appropriate data, the DialogFlow parser returns it to DialogFlow, and takes the same JSON payload from earlier, posting it to slack via DialogFlow's slack integration. The following is an example of a robust slack rich message response, which would be populated with data from the DialogParser:
{
"text": "New comic book alert!",
"attachments": [
{
"title": "The Further Adventures of Slackbot",
"fields": [
{
"title": "Volume",
"value": "1",
"short": true
},
{
"title": "Issue",
"value": "3",
"short": true
}
],
"author_name": "Stanford S. Strickland",
"author_icon": "http://a.slack-edge.com/7f18/img/api/homepage_custom_integrations-2x.png",
"image_url": "http://i.imgur.com/OJkaVOI.jpg?1"
},
{
"title": "Synopsis",
"text": "After @episod pushed exciting changes to a devious new branch back in Issue 1, Slackbot notifies @don about an unexpected deploy..."
},
{
"fallback": "Would you recommend it to customers?",
"title": "Would you recommend it to customers?",
"callback_id": "comic_1234_xyz",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "recommend",
"text": "Recommend",
"type": "button",
"value": "recommend"
},
{
"name": "no",
"text": "No",
"type": "button",
"value": "bad"
}
]
}
]
}
And that is the lifecycle of an event. I will give a more detailed example, later.
In order to clarify exactly what is being built, I'd like to explain the lifecycle of an event handled by both the chatops.ai router and DialogFlow. For any event to occur, the service-specific agent is deployed. A service is defined as a communication platform than can host chatbots, i.e. Slack, HipChat, Skype. For example, Slack defines custom bots as "Apps" even though chatops.ai bots take advantage of webhooks, their multiple API's via their API client (node.js?). In this example, Gunter, along with his Slack plugin, would be deployed onto slack and send out a
ack
POST
request to the event router.The Agent is composed of both the service-specific deployment configurations (plugins) and their event router.
Via communication with the service-specific Agent, the even router will receive
POST
ed payload from Slack based on triggered events, webhooks, and any other configuration setup for service-specific use.Once the event router has parsed the JSON, it stores (?) relevant information into the
store
; a library built to around an interface that allows multiple backends to be switch in and out without conflict. Google's DataStore k:v NoSQL service is the preferredstore
backend. Once complete, the event router parses the data into the correct format forPOST
ing to/query
in DialogFlow, in order to retrieve a response from the users message. An example request and response is below.Response:
It is not handed off for preparation for an API called to the integration router. This is where integration's, not services, communicate via API requests from the integration router. A plugin consists of a few parts:
And that is the lifecycle of an event. I will give a more detailed example, later.