Skip to content

Commit d5469e7

Browse files
patapizzafacebook-github-bot
authored andcommitted
Basic /speech integration
Summary: * Basic `POST /speech` integration * `!speech` support for `interactive`, using `mic` (3s) * Kaizens. Reviewed By: ruoyipu Differential Revision: D34931521 fbshipit-source-id: db3d7ea3d2c5f1a6df5492c4ed1aade21d7adc4e
1 parent 8782944 commit d5469e7

8 files changed

Lines changed: 201 additions & 2953 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
node_modules
33
.DS_Store
44
package-lock.json
5+
yarn.lock

CHANGES.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
1+
## v6.1.1
2+
3+
- Basic `POST /speech` integration.
4+
- `!speech` support for interactive.
5+
16
## v6.1.0
7+
28
Bumped API version to `20210928`.
39
Moved API version from `Accept` header to `v` HTTP parameter.
410
Kaizens.
511

612
## v6.0.1
13+
714
Removed unused `request` dependency
815
Updated various dependencies.
916

1017
## v6.0.0
18+
1119
Updated API version to latest: `20200513`.
1220
Browse the latest HTTP API documentation [here](https://wit.ai/docs/http/20200513#get__message_link).
1321

1422
## v5.0.0
23+
1524
The most important change is the removal of `.converse()` and `.runActions()`. Follow the migration tutorial [here](https://github.com/wit-ai/wit-stories-migration-tutorial), or [read more here](https://wit.ai/blog/2017/07/27/sunsetting-stories).
1625

1726
### Breaking changes
@@ -21,6 +30,7 @@ The most important change is the removal of `.converse()` and `.runActions()`. F
2130
- updated wit-ai-basic-app-for-tests.zip for testing
2231

2332
## v4.3.0
33+
2434
- `converse` and `runActions` are deprecated
2535
- `interactive` now calls `message`
2636

@@ -51,7 +61,6 @@ We moved to a Promise-based API, instead of callbacks. This makes the code simpl
5161

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

54-
5564
### Breaking changes
5665

5766
- `say` renamed to `send` to reflect that it deals with more than just text
@@ -66,6 +75,7 @@ See `./examples` to see how to use the new API.
6675
- allows for overriding API version, by setting `WIT_API_VERSION`
6776

6877
## v3.3.1
78+
6979
- adding API versioning (defaults to `20160516`)
7080
- warns instead of throwing when validating actions
7181
- fixing null values when cloning context

README.md

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,64 +30,86 @@ See `examples/messenger.js` for a thoroughly documented tutorial.
3030
### Overview
3131

3232
The Wit module provides a Wit class with the following methods:
33-
* `message` - the Wit [message](https://wit.ai/docs/http/20200513#get__message_link) API
3433

35-
You can also require a library function to test out your bot in the terminal. `require('node-wit').interactive`
34+
- `message` - the Wit [message](https://wit.ai/docs/http#get__message_link) API;
35+
- `speech` - the Wit [speech](https://wit.ai/docs/http#post__speech_link) API.
36+
37+
You can also require a library function to test out your Wit app in the terminal. `require('node-wit').interactive`
3638

3739
### Wit class
3840

3941
The Wit constructor takes the following parameters:
40-
* `accessToken` - the access token of your Wit instance
41-
* `logger` - (optional) the object handling the logging.
42-
* `apiVersion` - (optional) the API version to use instead of the recommended one
42+
43+
- `accessToken` - the access token of your Wit instance
44+
- `logger` - (optional) the object handling the logging.
45+
- `apiVersion` - (optional) the API version to use instead of the recommended one
4346

4447
The `logger` object should implement the methods `debug`, `info`, `warn` and `error`.
4548
They can receive an arbitrary number of parameters to log.
4649
For convenience, we provide a `Logger` class, taking a log level parameter
4750

4851
Example:
52+
4953
```js
5054
const {Wit, log} = require('node-wit');
5155

5256
const client = new Wit({
5357
accessToken: MY_TOKEN,
54-
logger: new log.Logger(log.DEBUG) // optional
58+
logger: new log.Logger(log.DEBUG), // optional
5559
});
5660

5761
console.log(client.message('set an alarm tomorrow at 7am'));
5862
```
5963

6064
### .message()
6165

62-
The Wit [message](https://wit.ai/docs/http/20200513#get__message_link) API.
66+
The Wit [message](https://wit.ai/docs/http/#get__message_link) API.
6367

6468
Takes the following parameters:
65-
* `message` - the text you want Wit.ai to extract the information from
66-
* `context` - (optional) the object representing the session state
69+
70+
- `q` - the text input you want Wit.ai to extract the information from
71+
- `context` - (optional) the [Context](https://wit.ai/docs/http/#context_link) object
72+
- `n` - (optional) the max number of intents and traits to get back
6773

6874
Example:
75+
6976
```js
7077
const client = new Wit({accessToken: 'MY_TOKEN'});
71-
client.message('what is the weather in London?', {})
72-
.then((data) => {
73-
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
74-
})
75-
.catch(console.error);
78+
client
79+
.message('what is the weather in London?', {})
80+
.then(data => {
81+
console.log('Yay, got Wit.ai response: ' + JSON.stringify(data));
82+
})
83+
.catch(console.error);
7684
```
7785

86+
### .speech()
87+
88+
The Wit [speech](https://wit.ai/docs/http#post__speech_link) API.
89+
90+
Takes the following paramters:
91+
92+
- `contentType` - the Content-Type header
93+
- `body` - the audio `Readable` stream
94+
- `context` - (optional) the [Context](https://wit.ai/docs/http/#context_link) object
95+
- `n` - (optional) the max number of intents and traits to get back
96+
97+
See `lib/interactive.js` for an example.
98+
7899
### interactive
79100

80-
Starts an interactive conversation with your bot.
101+
Starts an interactive conversation with your Wit app.
102+
Use `!speech` to send an audio request from the microphone, or enter any text input.
81103

82104
Example:
105+
83106
```js
84107
const {interactive} = require('node-wit');
85108
interactive(client);
86109
```
87110

88111
See the [docs](https://wit.ai/docs) for more information.
89112

90-
91113
## Changing the API version
92114

93115
On May 13th, 2020, the `GET /message` API was updated to reflect the new data model: intents, traits and entities are now distinct.
@@ -97,11 +119,13 @@ You can target a specific version by passing the `apiVersion` parameter when cre
97119
```json
98120
{
99121
"text": "hello",
100-
"intents": [ {
101-
"id": "1353535345345",
102-
"name": "greet",
103-
"confidence": 0.9753
104-
} ],
122+
"intents": [
123+
{
124+
"id": "1353535345345",
125+
"name": "greet",
126+
"confidence": 0.9753
127+
}
128+
],
105129
"entities": [],
106130
"traits": []
107131
}

lib/interactive.js

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,79 @@
44

55
'use strict';
66

7+
const fs = require('fs');
8+
const mic = require('mic');
79
const readline = require('readline');
810

9-
module.exports = (wit, handleMessage, context) => {
11+
const AUDIO_PATH = '/tmp/output.raw';
12+
const MIC_TIMEOUT_MS = 3000;
13+
14+
module.exports = (wit, handleResponse, context) => {
1015
const rl = readline.createInterface({
1116
input: process.stdin,
1217
output: process.stdout,
1318
});
1419
rl.setPrompt('> ');
20+
1521
const prompt = () => {
1622
rl.prompt();
1723
rl.write(null, {ctrl: true, name: 'e'});
1824
};
1925
prompt();
26+
27+
const makeResponseHandler = rsp => {
28+
if (handleResponse) {
29+
handleResponse(rsp);
30+
} else {
31+
console.log(JSON.stringify(rsp));
32+
}
33+
prompt();
34+
};
35+
2036
rl.on('line', line => {
2137
line = line.trim();
2238
if (!line) {
2339
return prompt();
2440
}
25-
wit
26-
.message(line, context)
27-
.then(rsp => {
28-
if (handleMessage) {
29-
handleMessage(rsp);
30-
} else {
31-
console.log(JSON.stringify(rsp));
32-
}
33-
prompt();
34-
})
35-
.catch(err => console.error(err));
41+
42+
// POST /speech
43+
if (line === '!speech') {
44+
const microphone = mic({
45+
bitwidth: '16',
46+
channels: '1',
47+
encoding: 'signed-integer',
48+
endian: 'little',
49+
fileType: 'raw',
50+
rate: '16000',
51+
});
52+
53+
const inputAudioStream = microphone.getAudioStream();
54+
const outputFileStream = fs.WriteStream(AUDIO_PATH);
55+
inputAudioStream.pipe(outputFileStream);
56+
57+
inputAudioStream.on('startComplete', () => {
58+
setTimeout(() => {
59+
microphone.stop();
60+
}, MIC_TIMEOUT_MS);
61+
});
62+
inputAudioStream.on('stopComplete', () => {
63+
const stream = fs.ReadStream(AUDIO_PATH);
64+
wit
65+
.speech(
66+
'audio/raw;encoding=signed-integer;bits=16;rate=16000;endian=little',
67+
stream,
68+
context,
69+
)
70+
.then(makeResponseHandler)
71+
.catch(console.error);
72+
});
73+
74+
microphone.start();
75+
76+
return;
77+
}
78+
79+
// GET /message
80+
wit.message(line, context).then(makeResponseHandler).catch(console.error);
3681
});
3782
};

0 commit comments

Comments
 (0)