Skip to content

Commit

Permalink
Add Wit.ai Bot sample along with HTTP calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonio Pintus committed Feb 16, 2018
1 parent 64ae63d commit 4bc1387
Show file tree
Hide file tree
Showing 4 changed files with 483 additions and 1 deletion.
117 changes: 117 additions & 0 deletions examples/http-requests/sample-wit.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Examples of HTTP calls to Vivocha Bot API
// related to the Simple Wit.ai Bot
// implemented in file: examples/sample-wit

// N.B. Replace the token property in the following
// requests body with the real token of your Wit.ai App.


// Send start event
POST http://localhost:8888/bot/message
Content-Type: application/json

{
"language": "en",
"event": "start",
"settings": {
"engine": {
"type": "WitAi",
"settings": {
"token": "<YOUR_WIT_APP_YOKEN>"
}
}
},
"context": {
}
}

###
// Send name
POST http://localhost:8888/bot/message
Content-Type: application/json

{
"language": "en",
"event": "continue",
"message": {
"code": "message",
"type": "text",
"body": "Antonio Watson"
},
"settings": {
"engine": {
"type": "WitAi",
"settings": {
"token": "<YOUR_WIT_APP_YOKEN>"
}
}
},
"context": {
"contexts": [
"ask_for_name"
]
}
}

###
// Send "I prefer by phone"
POST http://localhost:8888/bot/message
Content-Type: application/json

{
"language": "en",
"event": "continue",
"message": {
"code": "message",
"type": "text",
"body": "meglio per telefono, grazie"
},
"settings": {
"engine": {
"type": "WitAi",
"settings": {
"token": "<YOUR_WIT_APP_YOKEN>"
}
}
},
"data": {
"name": "Antonio Watson"
},
"context": {
"contexts": [
"recontact_by_email_or_phone"
]
}
}

###
// Send phone number
POST http://localhost:8888/bot/message
Content-Type: application/json

{
"language": "en",
"event": "continue",
"message": {
"code": "message",
"type": "text",
"body": "3391111111"
},
"settings": {
"engine": {
"type": "WitAi",
"settings": {
"token": "<YOUR_WIT_APP_YOKEN>"
}
}
},
"data": {
"name": "Antonio Watson"
},
"context": {
"contexts": [
"recontact_by_email_or_phone",
"ask_for_phone"
]
}
}
180 changes: 180 additions & 0 deletions examples/sample-wit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
"use strict";
/**
* This is a sample bot built using Wit.ai NLP.
* In order to use this bot you need to create and train
* a Wit.ai app able to collect: names, phone numbers and email addresses
* and to understand users preferring to be contacted by email or phone.
* The Wit.ai App should be trained to detect the intents mapped in the following
* intents property in SimpleWitBot class.
* See comments in the code below.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("../dist/index");
const _ = require("lodash");
// WitAiBot is an abstract class, so we need to:
// - set the intents property
// - implement the getStartMessage() method
class SimpleWitBot extends index_1.WitAiBot {
constructor() {
super(...arguments);
// intents mappings bound to specific Wit.ai Bot, the intent names MUST match
// the intents as defined in Wit.ai Console.
this.intents = {
provide_name: (data, request) => this.askEmailorPhone(data.entities, request),
by_email: (data, request) => this.contactMeByEmail(data, request),
by_phone: (data, request) => this.contactMeByPhone(data, request),
provide_phone: (data, request) => this.providePhoneNumber(data.entities, request),
provide_email: (data, request) => this.provideEmailAddress(data.entities, request),
unknown: (data, request) => this.unknown(data, request)
};
}
// The following method is invoked only for a start event, sent by Vivocha at the very beginning
// of the conversation (in other words it wakes-up the bot)
async getStartMessage(request) {
const res = {
event: 'continue',
messages: [prepareBotMessage("Hello, I'm a Vivocha Wit Bot, what's your name?")],
data: request.data,
settings: request.settings,
//Please note how contexts are set (and checked in each intent handler)
context: _.merge(request.context, { contexts: ['ask_for_name'] })
};
return res;
}
// user provided her name, then the Wit.ai 'provide_name' was detected
async askEmailorPhone(entities, request) {
let name = '';
if (entities.contact) {
name = entities.contact.map(v => v.value).join(' ');
}
const pre = `Thank you ${name}, `;
let response = {
event: 'continue',
messages: [prepareBotMessage(`${pre}do you prefer to be contacted by email or by phone?`)],
data: { name },
contexts: ['recontact_by_email_or_phone']
};
return response;
}
;
// user said she prefers to be contacted by email...
async contactMeByEmail(data, request) {
let response = {};
if (this.inContext(request.context.contexts, ['recontact_by_email_or_phone'])) {
response = {
messages: [prepareBotMessage('Good, send me your email address, please')],
contexts: [...request.context.contexts, 'ask_for_email'],
event: 'continue',
data: request.data
};
}
else {
response = {
messages: [prepareBotMessage('ERROR')],
contexts: ['end'],
data: request.data || {},
event: 'end'
};
}
return response;
}
// user chose to be contacted by phone
async contactMeByPhone(data, request) {
let response = {};
if (this.inContext(request.context.contexts, ['recontact_by_email_or_phone'])) {
response = {
messages: [prepareBotMessage(`OK ${request.data.name}, text me your phone number, please`)],
contexts: [...request.context.contexts, 'ask_for_phone'],
event: 'continue',
data: request.data
};
}
else {
response = {
messages: [prepareBotMessage('ERROR')],
contexts: ['end'],
data: request.data || {},
event: 'end'
};
}
return response;
}
// user sent her phone number and the correponding intent was detected by the Wit.ai NLP engine
async providePhoneNumber(data, request) {
let response = {};
if (this.inContext(request.context.contexts, ['ask_for_phone', 'recontact_by_email_or_phone'])) {
response = {
messages: [prepareBotMessage(`Perfect, ${request.data.name}. We will call you as soon as possible. Thank you and bye! :)`)],
contexts: ['end'],
// collect phone number entity
data: { phone: data.phone_number[0].value },
// Bot sends the 'end' event to communicate to Vivocha to close the contact, conversation finished.
event: 'end'
};
}
else {
response = {
messages: [prepareBotMessage('ERROR')],
contexts: ['end'],
data: request.data || {},
event: 'end'
};
}
return response;
}
// user chose to be recontacted by email and provided the related address
async provideEmailAddress(data, request) {
let response = {};
if (this.inContext(request.context.contexts, ['ask_for_email', 'recontact_by_email_or_phone'])) {
response = {
messages: [prepareBotMessage(`Perfect, ${request.data.name}. We will send soon an email to the provided address. Thank you and goodbye! :)`)],
contexts: ['end'],
// collect email address
data: { email: data.email[0].value },
event: 'end'
};
}
else {
response = {
messages: [prepareBotMessage('ERROR')],
contexts: ['end'],
data: request.data || {},
event: 'end'
};
}
return response;
}
// when Wit.ai is not able to detect an intent, WitAiBot class maps an 'unknown' intent, here's the handler
async unknown(data, request) {
let response = {
event: 'continue',
messages: [prepareBotMessage("Sorry, I didn't get that. Can you say it again?")],
contexts: request.context.contexts,
data: request.data || {}
};
return response;
}
}
exports.SimpleWitBot = SimpleWitBot;
// just prepares a complete Vivocha TextMessage
function prepareBotMessage(body) {
return {
code: 'message',
type: 'text',
body
};
}
// Create a BotManager and register the Wit.ai Bot Agent
const manager = new index_1.BotAgentManager();
manager.registerAgent('WitAi', async (req) => {
const bot = new SimpleWitBot(req.settings.engine.settings.token);
return bot.sendMessage(req);
});
const port = process.env.PORT ? parseInt(process.env.PORT || '') : 8888;
// run the Bot
manager.listen(port);
console.log(`SimpleWitBot listening at port: ${port}`);
process.on('SIGTERM', () => process.exit(0));
process.on('SIGINT', () => process.exit(0));
// RUN this with: node sample-wit
// If you need to change the default 8888 port, run: PORT=<port-number> node sample-wit
Loading

0 comments on commit 4bc1387

Please sign in to comment.