This feature will allow you to integrate eddi with a backend server to monitor the messages with a chatbot.
The callback can be invoked by multiple actions that you define in the package , you will receive in the post body a conversationMemorySnapshot
which is the model that has all information about the current conversation that invoked this callback, we will go through a step by step example to show you how callbacks work.
In order to enable and configure callbacks in a chatbot you will have to add this into one of the packages used by the chatbot:
{ "type": "eddi://ai.labs.callback", "config": { "callbackUri": "String", "action": "String", "callOnActions":"String", "timeoutInMillis": Long } } |
type | Must be eddi://ai.labs.callback to activate a callback. |
---|---|
config.callbackUri | (String) this is the URI that will be invoked; a POST request will be sent to that URI alongside |
config.action | (String) if you have one action that will invoke the callback use this property. |
config.callOnActions | (String) if you have multiple actions that will invoke the callback use this property, it should coma separated values. e.g("action1,action2,..."). |
config.timeoutInMillis | (Long) a duration of time in millisecond before timeout occurs. |
Here is the model for conversationMemorySnapshot :
"conversationMemorySnapshot": { "id": "String", "botId": "String", "botVersion": Integer, "environment": "String", "conversationState": "String", "conversationSteps": [array of conversationSteps], "redoCache": [] } |
id | (String) id of the conversation |
---|---|
botId | (String) id of the bot |
botVersion | (String) version of the chatbot |
environment | (String) bot environment e.g: restricted, unrestricted |
conversationState | (String) enumeration values : READY, |
conversationSteps | (Array of conversationStep) History of the conversation |
Callbacks does not have a store like the other extensions e.g : httpCalls, behaviorSet, regularDictionaries,etc.. |
We will do a step by step example from scratch (chatbot creation to a simple conversation that uses a callback)
For the sake of simplicity we will use a simple nodejs http server to intercept the callback and get the conversation snapshot.
More about regular dictionaries can be found here .
Request URL POST http://localhost:7070/regulardictionarystore/regulardictionaries Request Body { "language" : "en", "words" : [ { "word" : "callback", "exp" : "callback(*)", "frequency" : 0 } ], "phrases" : [ { "phrase" : "callback", "exp" : "callback" } ] } Response Body no content Response Code 201 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 16:40:58 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "location": "eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/5af86a9aba31c023bcb9ef2b?version=1", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
More about behaviorSets can be found here.
Request URL POST http://localhost:7070/behaviorstore/behaviorsets Response Body no content Response Code 201 Request Body { "behaviorGroups": [ { "name": "Smalltalk", "behaviorRules": [ { "name": "callback", "actions": [ "callback" ], "children": [ { "type": "inputmatcher", "values": { "expressions": "callback" } } ] } ] } ] } Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 16:45:52 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "location": "eddi://ai.labs.behavior/behaviorstore/behaviorsets/5af86bc0ba31c023bcb9ef2c?version=1", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
More about outputSet can be found here.
Request URL POST http://localhost:7070/outputstore/outputsets Request Body { "outputSet": [ { "action": "callback", "timesOccurred": 0, "outputs": [ { "type": "text", "valueAlternatives": [ "callback is done please check you nodejs server log" ] } ] } ] } Response Body no content Response Code 201 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 16:48:37 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "location": "eddi://ai.labs.output/outputstore/outputsets/5af86c65ba31c023bcb9ef2d?version=1", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
at this step we will create a simple nodejs http server to intercept the callback.
Copy this code into a file named app.js and then run the command : node app.js
You should get as output in the console : Server running at http://127.0.0.1:3333/ if you successfully ran the file.
var http = require('http'); var qs = require('querystring'); http.createServer(function (request, response) { if (request.method == 'POST') { var body = ''; request.on('data', function (data) { body += data; if (body.length > 1e6){ request.connection.destroy(); } }); request.on('end', function () { var postData = qs.parse(body); console.log(postData); }); } response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('This can be viewed in browser'); }).listen(3333, '127.0.0.1'); console.log('Server running at http://127.0.0.1:3333/'); |
More about packages can be found here.
Request URL POST http://localhost:7070/packagestore/packages Request Body { "packageExtensions": [ { "type": "eddi://ai.labs.parser", "extensions": { "dictionaries": [ { "type": "eddi://ai.labs.parser.dictionaries.integer" }, { "type": "eddi://ai.labs.parser.dictionaries.decimal" }, { "type": "eddi://ai.labs.parser.dictionaries.punctuation" }, { "type": "eddi://ai.labs.parser.dictionaries.email" }, { "type": "eddi://ai.labs.parser.dictionaries.time" }, { "type": "eddi://ai.labs.parser.dictionaries.ordinalNumber" }, { "type": "eddi://ai.labs.parser.dictionaries.regular", "config": { "uri": "eddi://ai.labs.regulardictionary/regulardictionarystore/regulardictionaries/{{dictionary_id}}?version=1" } } ], "corrections": [ { "type": "eddi://ai.labs.parser.corrections.stemming", "config": { "language": "english", "lookupIfKnown": "false" } }, { "type": "eddi://ai.labs.parser.corrections.levenshtein", "config": { "distance": "2" } }, { "type": "eddi://ai.labs.parser.corrections.mergedTerms" } ] }, "config": {} }, { "type": "eddi://ai.labs.behavior", "config": { "uri": "eddi://ai.labs.behavior/behaviorstore/behaviorsets/{{behaviourset_id}}?version=1" } }, { "type": "eddi://ai.labs.output", "config": { "uri": "eddi://ai.labs.output/outputstore/outputsets/{{outputset_id}}?version=1" } }, { "type": "eddi://ai.labs.callback", "config": { "callbackUri": "http://127.0.0.1:3333/", "action": "callback", "callOnActions":"", "timeoutInMillis": 10000 } } ] } Response Body no content Response Code 201 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 19:26:36 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "location": "eddi://ai.labs.package/packagestore/packages/5af8916cba31c023bcb9ef2f?version=1", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
Request URL POST http://localhost:7070/botstore/bots Request Body { "packages" : [ "eddi://ai.labs.package/packagestore/packages/{{package_id}}?version=1" ], "channels" : [] } Response Body no content Response Code 201 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 21:18:16 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "location": "eddi://ai.labs.bot/botstore/bots/5af8ab98ba31c023bcb9ef32?version=1", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
Request URL POST http://localhost:7070/administration/restricted/deploy/<bot_id>?version=1&autoDeploy=true Response Body no content Response Code 202 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 21:21:54 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
Request URL POST http://localhost:7070/bots/<env>/<bot_id> Response Body no content Response Code 201 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 21:30:45 GMT", "access-control-allow-headers": "authorization, Content-Type", "content-length": "0", "location": "eddi://ai.labs.conversation/conversationstore/conversations/5af8ae85ba31c023bcb9ef35", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location", "content-type": null } |
Request URL POST http://localhost:7070/bots/<env>/<bot_id>/<conversation_id>?returnDetailed=false&returnCurrentStepOnly=true Request Body { "input":"callback" } Response Body { "botId": "5af8b075ba31c023bcb9ef3b", "botVersion": 1, "environment": "unrestricted", "conversationState": "READY", "redoCacheSize": 0, "conversationSteps": [ { "conversationStep": [ { "key": "input:initial", "value": "weather" }, { "key": "actions", "value": [ "ask_for_city" ] }, { "key": "output:text:ask_for_city", "value": "Which City would you like to know the weather of?" } ], "timestamp": 1526247548410 } ] } Response Code 200 Response Headers { "access-control-allow-origin": "*", "date": "Sun, 13 May 2018 21:35:15 GMT", "content-type": "application/json;resteasy-server-has-produces=true", "access-control-allow-headers": "authorization, Content-Type", "content-length": "325", "access-control-allow-methods": "GET, PUT, POST, DELETE, PATCH, OPTIONS", "access-control-expose-headers": "location" } |
We will find in the nodjs console something similar to this :
{ "conversationMemorySnapshot": { "id": "5b01a9e1ba31c030b4c461ed", "botId": "5b01a9d5ba31c030b4c461eb", "botVersion": 1, "environment": null, "conversationState": "IN_PROGRESS", "conversationSteps": [ { "packages": [ { "context": "", "lifecycleTasks": [ { "key": "behavior_rules:fail", "result": [ "callback" ], "possibleResults": [ [ "callback" ] ], "timestamp": 1526835681004, "public": false } ] } ] }, { "packages": [ { "context": "", "lifecycleTasks": [ { "key": "input:initial", "result": "callback", "possibleResults": [ "callback" ], "timestamp": 1526835683768, "public": true }, { "key": "input:formatted", "result": "callback", "possibleResults": [ "callback" ], "timestamp": 1526835683768, "public": false }, { "key": "input:normalized", "result": "callback", "possibleResults": [ "callback" ], "timestamp": 1526835683768, "public": false }, { "key": "expressions:parsed", "result": "callback", "possibleResults": [ "callback" ], "timestamp": 1526835683768, "public": false }, { "key": "behavior_rules:success", "result": [ "callback" ], "possibleResults": [ [ "callback" ] ], "timestamp": 1526835683768, "public": false }, { "key": "actions", "result": [ "callback" ], "possibleResults": [ [ "callback" ] ], "timestamp": 1526835683769, "public": true }, { "key": "output:text:callback", "result": "callback is done please check you nodejs server log", "possibleResults": [ "callback is done please check you nodejs server log" ], "timestamp": 1526835683769, "public": true } ] } ] } ], "redoCache": [] } } |
If you would like to run the full example through postman , you can download and import the collection below.
Additional information:
How to import a postman collection?