Skip to content

Commit

Permalink
upgrade for bot engine v1
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Raison committed Jun 28, 2016
1 parent 39b2b9f commit 3cd2327
Show file tree
Hide file tree
Showing 12 changed files with 625 additions and 675 deletions.
18 changes: 17 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
- INFO level as an alias for LOG
## v4.0.0

After a lot of internal dogfooding and bot building, we decided to change the API in a backwards-incompatible way. The changes are described below and aim to simplify user code and accommodate upcoming features.

We moved to a Promise-based API, instead of callbacks. This makes the code simpler and the error-handling more straight-forward. It's also inline with where JS is going with standards like `fetch()` and `async/await` that are based on Promises.

See `./examples` to see how to use the new API.


### Breaking changes

- `say` renamed to `send` to reflect that it deals with more than just text
- Removed built-in actions `merge` and `error`
- Actions signature simplified with `request` and `response` arguments
- Actions need to return promises and do not receive the `cb` parameter anymore
- INFO level replaces LOG level
- configuration is now done when instantiating the `Wit` object, instead of using env vars

## v3.3.2

Expand Down
248 changes: 102 additions & 146 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,52 +15,17 @@ npm install --save node-wit
Run in your terminal:

```bash
node examples/template.js <your_token>
# Node.js <= 6.x.x, add the flag --harmony_destructuring
node --harmony_destructuring examples/basic.js <MY_TOKEN>
# Node.js >= v6.x.x
node examples/basic.js <MY_TOKEN>
```

See `examples` folder for more examples.

## API
### Messenger integration example

### Version change

On 2016, May 11th, the /message API was updated to reflect the new Bot Engine model: intent are now entities.
We updated the SDK to the latest version: 20160516.
You can target a specific version by setting the env variable `WIT_API_VERSION`.

```json
{
"msg_id" : "e86468e5-b9e8-4645-95ce-b41a66fda88d",
"_text" : "hello",
"entities" : {
"intent" : [ {
"confidence" : 0.9753469589149633,
"value" : "greetings"
} ]
}
}
```

Version prior to 20160511 will return the old format:

```json
{
"msg_id" : "722fc79b-725c-4ca1-8029-b7f57ff88f54",
"_text" : "hello",
"outcomes" : [ {
"_text" : "hello",
"confidence" : null,
"intent" : "default_intent",
"entities" : {
"intent" : [ {
"confidence" : 0.9753469589149633,
"value" : "greetings"
} ]
}
} ],
"WARNING" : "DEPRECATED"
}
```
See `examples/messenger.js` for a thoroughly documented tutorial.

### Overview

Expand All @@ -73,54 +38,54 @@ The Wit module provides a Wit class with the following methods:
### Wit class

The Wit constructor takes the following parameters:
* `token` - the access token of your Wit instance
* `actions` - the object with your actions
* `accessToken` - the access token of your Wit instance
* `actions` - (optional if only using `.message()`) the object with your actions
* `logger` - (optional) the object handling the logging.
* `apiVersion` - (optional) the API version to use instead of the recommended one

The `actions` object has action names as properties, and action implementations as values.
You need to provide at least an implementation for the special actions `say`, `merge` and `error`.

A minimal `actions` object looks like this:
```js
const actions = {
say(sessionId, context, message, cb) {
console.log(message);
cb();
},
merge(sessionId, context, entities, message, cb) {
cb(context);
},
error(sessionId, context, error) {
console.log(error.message);
},
};
```
The `actions` object has action names as properties, and action functions as values.
Action implementations must return Promises (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
You must provide at least an implementation for the special action `send`.

A custom action takes the following parameters:
* `sessionId` - a unique identifier describing the user session
* `context` - the object representing the session state
* `cb(context)` - a callback function to fire at the end of your action with the updated context.
* `send` takes 2 parameters: `request` and `response`
* custom actions take 1 parameter: `request`

Example:
```js
const Wit = require('node-wit').Wit;
const client = new Wit(token, actions);
```
#### Request
* `sessionId` (string) - a unique identifier describing the user session
* `context` (object) - the object representing the session state
* `text` (string) - the text message sent by your end-user
* `entities` (object) - the entities extracted by Wit's NLU

The `logger` object should implement the methods `debug`, `log`/`info`, `warn` and `error`.
All methods take a single parameter `message`.
#### Response
* `text` (string) - The text your bot needs to send to the user (as described in your Wit.ai Stories)
* `quickreplies`

For convenience, we provide a `Logger`, taking a log level parameter (provided as `logLevels`).
The following levels are defined: `DEBUG`, `LOG`/`INFO`, `WARN`, `ERROR`.
The `logger` object should implement the methods `debug`, `info`, `warn` and `error`.
They can receive an arbitrary number of parameters to log.
For convenience, we provide a `Logger` class, taking a log level parameter

Example:
```js
const Logger = require('node-wit').Logger;
const levels = require('node-wit').logLevels;
const Wit = require('node-wit').Wit;

const logger = new Logger(levels.DEBUG);
const client = new Wit(token, actions, logger);
const {Wit, log} = require('node-wit');

const client = new Wit({
accessToken: MY_TOKEN,
actions: {
send(request, response) {
return new Promise(function(resolve, reject) {
console.log(JSON.stringify(response));
return resolve();
});
},
myAction({sessionId, context, text, entities}) {
console.log(`Session ${sessionId} received ${text}`);
console.log(`The current context is ${JSON.stringify(context)}`);
console.log(`Wit extracted ${JSON.stringify(entities)}`);
return Promise.resolve(context);
}
},
logger: new log.Logger(log.DEBUG) // optional
});
```

### message
Expand All @@ -130,18 +95,15 @@ The Wit [message](https://wit.ai/docs/http/20160330#get-intent-via-text-link) AP
Takes the following parameters:
* `message` - the text you want Wit.ai to extract the information from
* `context` - (optional) the object representing the session state
* `cb(error, data)` - a callback function with the JSON response

Example:
```js
const context = {};
client.message('what is the weather in London?', context, (error, data) => {
if (error) {
console.log('Oops! Got an error: ' + error);
} else {
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
}
});
const client = new Wit({accessToken: 'MY_TOKEN'});
client.message('what is the weather in London?', {})
.then((data) => {
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
})
.catch(console.error);
```

### runActions
Expand All @@ -152,29 +114,28 @@ Takes the following parameters:
* `sessionId` - a unique identifier describing the user session
* `message` - the text received from the user
* `context` - the object representing the session state
* `cb(error, context)` - a callback function with the updated context
* `maxSteps` - (optional) the maximum number of actions to execute (defaults to 5)

Example:

```js
const session = 'my-user-session-42';
const sessionId = 'my-user-session-42';
const context0 = {};
client.runActions(session, 'what is the weather in London?', context0, (e, context1) => {
if (e) {
console.log('Oops! Got an error: ' + e);
return;
}
client.runActions(sessionId, 'what is the weather in London?', context0)
.then((context1) => {
console.log('The session state is now: ' + JSON.stringify(context1));
client.runActions(session, 'and in Brussels?', context1, (e, context2) => {
if (e) {
console.log('Oops! Got an error: ' + e);
return;
}
console.log('The session state is now: ' + JSON.stringify(context2));
});
return client.runActions(sessionId, 'and in Brussels?', context1);
})
.then((context2) => {
console.log('The session state is now: ' + JSON.stringify(context2));
})
.catch((e) => {
console.log('Oops! Got an error: ' + e);
});
```

See `./examples/messenger.js` for a full-fledged example

### converse

The low-level Wit [converse](https://wit.ai/docs/http/20160330#converse-link) API.
Expand All @@ -183,17 +144,14 @@ Takes the following parameters:
* `sessionId` - a unique identifier describing the user session
* `message` - the text received from the user
* `context` - the object representing the session state
* `cb(error, data)` - a callback function with the JSON response

Example:
```js
client.converse('my-user-session-42', 'what is the weather in London?', {}, (error, data) => {
if (error) {
console.log('Oops! Got an error: ' + error);
} else {
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
}
});
client.converse('my-user-session-42', 'what is the weather in London?', {})
.then((data) => {
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
})
.catch(console.error);
```

### interactive
Expand All @@ -208,44 +166,42 @@ client.interactive();
See the [docs](https://wit.ai/docs) for more information.


## Messenger integration example

This quickstart assumes that you have:
* a [Wit.ai bot setup](https://wit.ai/docs/quickstart);
* a [Messenger Platform setup](https://developers.facebook.com/docs/messenger-platform/quickstart).

### Install dependencies

```bash
npm install body-parser express node-fetch
```

### Download and install ngrok

From [here](https://ngrok.com/download).
## Changing the API version

### Run ngrok
On 2016, May 11th, the /message API was updated to reflect the new Bot Engine model: intent are now entities.
We updated the SDK to the latest version: 20160516.
You can target a specific version by passing the `apiVersion` parameter when creating the `Wit` object.

```bash
./ngrok http 8445
```json
{
"msg_id" : "e86468e5-b9e8-4645-95ce-b41a66fda88d",
"_text" : "hello",
"entities" : {
"intent" : [ {
"confidence" : 0.9753469589149633,
"value" : "greetings"
} ]
}
}
```

This will provide `your_ngrok_domain` (the `Forwarding` line).

### Run the example
Version prior to 20160511 will return the old format:

```bash
export WIT_TOKEN=your_access_token
export FB_PAGE_ID=your_page_id
export FB_PAGE_TOKEN=your_page_token
export FB_VERIFY_TOKEN=any_token
node examples/messenger.js
```json
{
"msg_id" : "722fc79b-725c-4ca1-8029-b7f57ff88f54",
"_text" : "hello",
"outcomes" : [ {
"_text" : "hello",
"confidence" : null,
"intent" : "default_intent",
"entities" : {
"intent" : [ {
"confidence" : 0.9753469589149633,
"value" : "greetings"
} ]
}
} ],
"WARNING" : "DEPRECATED"
}
```

### Subscribe your page to Messenger Webhooks

Using your `FB_VERIFY_TOKEN` and `https://<your_ngrok_domain>/fb` as callback URL.

See the [Messenger Platform docs](https://developers.facebook.com/docs/messenger-platform/quickstart).

### Talk to your bot on Messenger!
32 changes: 32 additions & 0 deletions examples/basic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

let Wit = null;
try {
// if running from repo
Wit = require('../').Wit;
} catch (e) {
Wit = require('node-wit').Wit;
}

const accessToken = (() => {
if (process.argv.length !== 3) {
console.log('usage: node examples/basic.js <wit-access-token>');
process.exit(1);
}
return process.argv[2];
})();

const actions = {
send(request, response) {
const {sessionId, context, entities} = request;
const {text, quickreplies} = response;
return new Promise(function(resolve, reject) {
console.log('user said...', request.text);
console.log('sending...', JSON.stringify(response));
return resolve();
});
},
};

const client = new Wit({accessToken, actions});
client.interactive();
Loading

0 comments on commit 3cd2327

Please sign in to comment.