https://github.com/flow-ai/flowai-js
Flow.ai JavaScript SDK
https://github.com/flow-ai/flowai-js
api-client chatbot flowai nodejs sdk socket
Last synced: about 1 year ago
JSON representation
Flow.ai JavaScript SDK
- Host: GitHub
- URL: https://github.com/flow-ai/flowai-js
- Owner: flow-ai
- Created: 2016-11-22T22:33:01.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2025-01-06T07:59:48.000Z (over 1 year ago)
- Last Synced: 2025-06-11T21:11:33.994Z (about 1 year ago)
- Topics: api-client, chatbot, flowai, nodejs, sdk, socket
- Language: JavaScript
- Homepage: https://flow.ai
- Size: 1.8 MB
- Stars: 17
- Watchers: 1
- Forks: 5
- Open Issues: 27
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# The flow.ai Javascript SDK
Access the [flow.ai](https://flow.ai) platform from your Node.js or javascript app. This library lets you build on the flow.ai Webclient API.
## What can you do?
* A simple way to connect with [flow.ai](https://flow.ai)
* Auto reconnect and event binding
* Send and receive messages
* Trigger actions and interact with AI bots
## Usage
### Installation
Run `npm install --save flowai-js`
### Simple Node.js example
```js
const {
LiveClient,
Message,
Originator
} = require("flowai-js")
// Create a new live client
const client = new LiveClient({
clientId: 'YOUR CLIENT ID HERE',
origin: 'https://my.site'
})
// Fired whenever the client connects
client.on(LiveClient.CONNECTED, () => {
console.log('--> Connected')
// Create the originator of the message
const originator = new Originator({
name: "Boss"
})
// Create a Message
const message = new Message({
// Thread Id limits the message just to John
threadId: 'john',
// The text to send
speech: "Behold, I'm pure awesomeness!",
// Person or system sending the message
originator
})
// Send
client.send(message)
})
// Start the connection
client.start()
```
### Advanced Node.js example
In this example you'll notice all events that are available
```js
const {
LiveClient,
Message,
Originator
} = require("flowai-js")
// Create a new live client
const client = new LiveClient({
// Unique clientId copy & paste from Flow.ai dashboard
clientId: 'YOUR CLIENT ID HERE',
// When limiting to whitelisted domains, specify this
origin: 'https://my.site'
})
client.on(LiveClient.CONNECTED, () => {
const originator = new Originator({
name: "Boss"
})
const message = new Message({
// Thread Id limits the message just to John
threadId: 'john',
// Use the traceId to identify message
// being marked as delivered
traceId: 1,
speech: "Behold, I'm pure awesomeness!",
originator
})
client.send(message)
})
client.on(LiveClient.MESSAGE_DELIVERED, message => {
// The message we have send has been delivered
// check the traceId to see what message has been
// delivered since it's an async method
})
client.on(LiveClient.REPLY_RECEIVED, message => {
// Called when a bot or human operator
// sends a message or reply
if(message.threadId === 'john') {
// Incoming message for John
} else {
// Incoming message for another user
}
})
client.on(LiveClient.ERROR, err => {
// This handler will be fired whenever an error
// occurs during the connection
console.error('Something bad happened', err)
})
client.on(LiveClient.DISCONNECTED, () => {
// The client has been disconnected
})
client.on(LiveClient.MESSAGE_SEND, message => {
// Called whenever the client sends a message
})
client.on(LiveClient.RECONNECTING, () => {
// Called when the client tries to reconnect
})
client.start()
```
### Simple browser example
Using the library within the browser is pretty much the same as the Node.js examples.
There is one notable difference, all classes live inside a `Flowai` object.
#### Include the script
```html
```
#### Usage
```js
var client = new Flowai.LiveClient('YOUR CLIENT ID HERE');
client.on(LiveClient.CONNECTED, function(){
var originator = new Flowai.Originator({ fullName: "John Doo" });
var message = new Flowai.Message({
threadId: 'john',
traceId: 1,
speech: "Behold, I'm pure awesomeness!",
originator
});
client.send(message);
})
client.start();
```
### Notes on using with webpack
The library can be easily used with webpack. You'll probably receive an error though involving `fs`.
Add the following to your webpack config file:
```
node: {
fs: 'empty'
},
```
## Identifying messages
The SDK is pretty flexible with regard to how messages are delivered and grouped. To do this we use two unique keys: sessionId and threadId.

### threadId
A threadId is a unique key representing a channel, room, or user. If you have a single connection running for multiple clients, all using the same threadId, they will all receive the same messages.

### sessionId
The sessionId is used to identify connections from different devices like browsers or Node.js servers. Each connection is partly identified on our end using this key.

# Full API Reference
## Classes
- EventAttachment
-
Trigger events
- Exception
-
Exception
- FileAttachment
-
Send a file as attachment
- FlowAttachment
-
Trigger flows
- LiveClient
-
Live streaming websocket client extends EventEmitter
- Message
-
Message you send to Flow.ai
- Metadata
-
Additional Message data
- OpeningAttachment
-
Trigger opening events
- OpeningFlowAttachment
-
Trigger flow as opening events
- Originator
-
Originator of a Message
- Reply
-
Reply you receive from Flow.ai
- StepAttachment
-
Trigger steps
## Functions
- _setCookie(name, value)
-
_getCookie(name) ⇒string
## EventAttachment
Trigger events
### new EventAttachment(name, [label])
| Param | Type | Description |
| --- | --- | --- |
| name | string | Name of the event to trigger |
| [label] | string | Optional human readable label for the triggered event |
Constructor
**Example**
```js
// Event without any label
const message = new Message({
attachment: new EventAttachment('BUY')
})
```
**Example**
```js
// Event with label to display user
const message = new Message({
attachment: new EventAttachment('BUY', 'Buy dress')
})
```
## Exception
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| message | string | Human friendly message |
| type | string | Kind of error |
| innerException | [Exception](#Exception) | Inner exception |
| isFinal | boolean | Prevent further execution |
Exception
### new Exception(message, type, innerException, isFinal)
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| message | string | | message - Human friendly message |
| type | string | | Kind of error |
| innerException | [Exception](#Exception) | | Optional inner exception |
| isFinal | boolean | false | Indicates if this exception prevents further execution |
Constructor
## FileAttachment
Send a file as attachment
### new FileAttachment(data)
| Param | Type | Description |
| --- | --- | --- |
| data | File \| ReadStream | File or Blob in the browser, ReadStream in Nodejs |
Constructor
**Example**
```js
// Web example
var originator = new Originator({
name: 'Jane'
})
var file = fileInputElement.files[0]
const message = new Message({
attachment: new FileAttachment(file)
})
client.send(message)
```
**Example**
```js
// Nodejs example
import { createReadStream } from 'fs'
const originator = new Originator({
name: 'Jane'
})
// Load ReadStream from file on disk
const data = fs.createReadStream('/foo/bar.jpg')
const message = new Message({
attachment: new FileAttachment(data)
})
## FlowAttachment
Trigger flows
### new FlowAttachment(flowImmutableId)
| Param | Type | Description |
| --- | --- | --- |
| flowImmutableId | string | Immutable flowId of the flow to trigger |
Constructor
**Example**
```js
const message = new Message({
attachment: new FlowAttachment(flowImmutableId)
})
```
## LiveClient
Live streaming websocket client extends EventEmitter
* [LiveClient](#LiveClient)
* [new LiveClient(opts)](#new_LiveClient_new)
* _instance_
* [.sessionId](#LiveClient+sessionId)
* [.threadId](#LiveClient+threadId)
* [.threadId](#LiveClient+threadId)
* [.secret](#LiveClient+secret)
* [.secret](#LiveClient+secret)
* [.isConnected](#LiveClient+isConnected)
* [.sessionId()](#LiveClient+sessionId)
* [.start(threadId, sessionId)](#LiveClient+start)
* [.stop()](#LiveClient+stop)
* [.destroy()](#LiveClient+destroy)
* [.send(message)](#LiveClient+send)
* [.merger(mergerKey, threadId, sessionId)](#LiveClient+merger)
* [.history(threadId)](#LiveClient+history)
* [.noticed(threadId, instantly)](#LiveClient+noticed)
* [.checkUnnoticed(threadId)](#LiveClient+checkUnnoticed)
* [.log(text)](#LiveClient+log)
* _static_
* [.ERROR](#LiveClient.ERROR)
* [.CONNECTED](#LiveClient.CONNECTED)
* [.RECONNECTING](#LiveClient.RECONNECTING)
* [.DISCONNECTED](#LiveClient.DISCONNECTED)
* [.REPLY_RECEIVED](#LiveClient.REPLY_RECEIVED)
* [.AGENT_TYPING_RECEIVED](#LiveClient.AGENT_TYPING_RECEIVED)
* [.MESSAGE_SEND](#LiveClient.MESSAGE_SEND)
* [.MESSAGE_DELIVERED](#LiveClient.MESSAGE_DELIVERED)
* [.REQUESTING_HISTORY](#LiveClient.REQUESTING_HISTORY)
* [.NO_HISTORY](#LiveClient.NO_HISTORY)
* [.RECEIVED_HISTORY](#LiveClient.RECEIVED_HISTORY)
* [.CHECKED_UNNOTICED_MESSAGES](#LiveClient.CHECKED_UNNOTICED_MESSAGES)
* [.INTERRUPTION_OCCURRED](#LiveClient.INTERRUPTION_OCCURRED)
### new LiveClient(opts)
| Param | Type | Description |
| --- | --- | --- |
| opts | object \| string | Configuration options or shorthand for just clientId |
| opts.clientId | string | Mandatory Client token |
| opts.storage | string | Optional, 'session' for using sessionStorage, 'local' for localStorage or `memory` for a simple memory store |
| opts.endpoint | string | Optional, only for testing purposes |
| opts.origin | string | When running on Nodejs you MUST set the origin |
| opts.silent | boolean | Optional, console.errors will not be shown |
| opts.ott | string | Optional, console.errors will not be shown |
Constructor
**Example**
```js
// Node.js
const client = new LiveClient({
clientId: 'MY CLIENT ID',
origin: 'https://my.website'
})
// Web
const client = new LiveClient({
clientId: 'MY CLIENT ID',
storage: 'session'
})
// Lambda function
const client = new LiveClient({
clientId: 'MY CLIENT ID',
storage: 'memory'
})
```
### *liveClient*.sessionId
| Param | Type | Description |
| --- | --- | --- |
| value | string | Change the session ID |
Session Id of the connection
### *liveClient*.threadId
Default Thread Id to be used for any messages being send
**Returns**: string - Null if no connection is active
### *liveClient*.threadId
| Param | Type | Description |
| --- | --- | --- |
| value | string | Change the thread ID |
Session Id of the connection
### *liveClient*.secret
Secret
### *liveClient*.secret
| Param | Type | Description |
| --- | --- | --- |
| value | string | Change the Secret |
Secret
### *liveClient*.isConnected
Check if the connection is active
**Returns**: boolean - True if the connection is active
**Example**
```js
if(client.isConnected) {
// Do something awesome
}
```
### *liveClient*.sessionId()
Session Id of the connection
**Returns**: string - Null if no connection is active
### *liveClient*.start(threadId, sessionId)
| Param | Type | Description |
| --- | --- | --- |
| threadId | string | Optional. When assigned, this is the default threadId for all messages that are send |
| sessionId | string | Optional. Must be unique for every connection |
Start the client
**Example**
```js
// Start, will generate thread and sessionId
client.start()
```
**Example**
```js
// Start with your own custom threadId
client.start('UNIQUE THREADID FOR USER')
```
### *liveClient*.stop()
Use this method to temp disconnect a client
**Example**
```js
// Close the connection
client.stop()
```
### *liveClient*.destroy()
Close the connection and completely reset the client
**Example**
```js
// Close the connection and reset the client
client.destroy()
```
### *liveClient*.send(message)
| Param | Type | Description |
| --- | --- | --- |
| message | object | Message you want to send |
This method triggers a `LiveClient.MESSAGE_SEND` event
**Returns**: object - Message that was send
**Example**
```js
const originator = new Originator({
name: "Jane"
})
const message = new Message({
speech: "Hi!",
originator
})
### *liveClient*.merger(mergerKey, threadId, sessionId)
| Param | Type | Description |
| --- | --- | --- |
| mergerKey | string | Unique token representing merge Request |
| threadId | string | Optional. The threadId to merge |
| sessionId | string | Optional. The sessionId to assign to the thread |
Merge two threads from different channels.
This methods is not yet publicy supported since we don't have a way yet to provide a mergerKey.
### *liveClient*.history(threadId)
| Param | Type | Description |
| --- | --- | --- |
| threadId | string | Optional. Specify the threadId to retreive historic messages |
Request historic messages
**Example**
```js
// Load any messages if there is a threadId
// usefull when using with JS in the browser
client.history()
// Load messages using a custom threadId
client.history('MY CUSTOM THREAD ID')
```
### *liveClient*.noticed(threadId, instantly)
| Param | Type | Description |
| --- | --- | --- |
| threadId | string | Optional. Specify the thread that is noticed |
| instantly | boolean | Optional. Instantly send notice. Default is false |
Call to mark a thread as noticed.
The library automatically throttles the number of calls
**Example**
```js
// Call that the client has seen all messages for the auto clientId
client.noticed()
// Mark messages based on a custom threadId
client.noticed('MY CUSTOM THREAD ID')
```
### *liveClient*.checkUnnoticed(threadId)
| Param | Type | Description |
| --- | --- | --- |
| threadId | string | Optional. Specify the thread to check unnoticed messags for |
Did we miss any messages?
### *liveClient*.log(text)
| Param | Type |
| --- | --- |
| text | string |
### *LiveClient*.ERROR
Event that triggers when an error is received from the flow.ai platform
### *LiveClient*.CONNECTED
Event that triggers when client is connected with platform
### *LiveClient*.RECONNECTING
Event that triggers when client tries to reconnect
### *LiveClient*.DISCONNECTED
Event that triggers when the client gets disconnected
### *LiveClient*.REPLY_RECEIVED
Event that triggers when a new message is received from the platform
### *LiveClient*.AGENT_TYPING_RECEIVED
Event that triggers when start busy typing received from the platform
### *LiveClient*.MESSAGE_SEND
Event that triggers when the client is sending a message to the platform
### *LiveClient*.MESSAGE_DELIVERED
Event that triggers when the send message has been received by the platform
### *LiveClient*.REQUESTING_HISTORY
Event that triggers when a request is made to load historic messages
### *LiveClient*.NO_HISTORY
Event that triggers when a request is made to load historic messages
### *LiveClient*.RECEIVED_HISTORY
Event that triggers when historic messages are received
### *LiveClient*.CHECKED_UNNOTICED_MESSAGES
Event that triggers when there are unnoticed messages
### *LiveClient*.INTERRUPTION_OCCURRED
Event that triggers when there are unnoticed messages
## Message
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| speech | string | Text representing the Message |
| originator | [Originator](#Originator) | Originator |
| meta | [Metadata](#Metadata) | Meta data |
| attachment | [Attachment](#new_Attachment_new) | Optional attachment |
Message you send to Flow.ai
* [Message](#Message)
* [new Message(opts)](#new_Message_new)
* [.build(opts)](#Message.build)
### new Message(opts)
| Param | Type | Description |
| --- | --- | --- |
| opts | Object | |
| opts.traceId | number | Optional unique integer you can match messages with |
| opts.threadId | string | Optional unique id specific to this chat |
| opts.speech | string | Text representing the Message |
| opts.originator | [Originator](#Originator) | Originator |
| opts.metadata | [Metadata](#Metadata) | Meta data |
| opts.attachment | [Attachment](#new_Attachment_new) | Attachment (optional) |
Constructor
### *Message*.build(opts)
| Param | Type |
| --- | --- |
| opts | object |
| opts.threadId | string |
| opts.traceId | string |
| opts.speech | string |
| opts.originator | object |
| opts.metadata | object |
| opts.attachment | object |
Factory method
## Metadata
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| language | string | Language the message is ib |
| timezone | number | UTC time offset in hours |
| params | Object | Parameters to send with the message |
| domain | Object | Browser or server environment variables like origin |
Additional Message data
* [Metadata](#Metadata)
* [new Metadata(language, timezone, params)](#new_Metadata_new)
* _instance_
* ~~[.addContext()](#Metadata+addContext)
~~
* _static_
* [.build(metadata)](#Metadata.build)
### new Metadata(language, timezone, params)
| Param | Type | Description |
| --- | --- | --- |
| language | string | Specify the language of the message |
| timezone | number | Specify the timezone of the message |
| params | Object | Additional data to be send |
Constructor
### ~~*metadata*.addContext()~~
***Deprecated***
### *Metadata*.build(metadata)
| Param | Type |
| --- | --- |
| metadata | Object |
Create a Metadata object from raw data
## OpeningAttachment
Trigger opening events
### new OpeningAttachment(name, [label])
| Param | Type | Description |
| --- | --- | --- |
| name | string | Name of the event to trigger |
| [label] | string | Optional human readable label for the triggered event |
Constructor
**Example**
```js
// Opening event without any label
const message = new Message({
attachment: new OpeningAttachment('BUY')
})
```
**Example**
```js
// Opening event with label to display user
const message = new Message({
attachment: new OpeningAttachment('BUY', 'Buy dress')
})
```
## OpeningFlowAttachment
Trigger flow as opening events
### new OpeningFlowAttachment(flowImmutableId, [label])
| Param | Type | Description |
| --- | --- | --- |
| flowImmutableId | string | FlowImmutableId of the flow to trigger |
| [label] | string | Optional human readable label for the triggered event |
Constructor
**Example**
```js
// Opening event without any label
const message = new Message({
attachment: new OpeningFlowAttachment(flowImmutableId)
})
```
## Originator
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| name | string | Name of a person or system originating the Message, default is Anonymous |
| role | string | The role of the person. You cannot set this, default is external |
| profile | Object | Contains profile info |
| profile.fullName | string | First and surname combined |
| profile.firstName | string | First name of the person |
| profile.lastName | string | Last name of the person |
| profile.email | string | E-mail address |
| profile.description | string | Description of this user |
| profile.picture | string | Profile picture (url) |
| profile.locale | string | ISO code describing language and country (en-US) |
| profile.timezone | number | Hours from GMT |
| profile.location | string | Location of the user |
| profile.gender | string | M for male, F for female or U for unknown / other |
| metadata | object | Optional object with custom metadata |
Originator of a Message
### new Originator(opts)
| Param | Type | Description |
| --- | --- | --- |
| opts | Object | |
| opts.name | string | Name of a person or system originating the Message, default is Anonymous |
| opts.role | string | The role of the person. You cannot set this, default is external |
| opts.profile | Object | Contains profile info |
| opts.profile.fullName | string | First and surname combined |
| opts.profile.firstName | string | First name of the person |
| opts.profile.lastName | string | Last name of the person |
| opts.profile.email | string | E-mail address |
| opts.profile.description | string | Description of this user |
| opts.profile.picture | string | Profile picture (url) |
| opts.profile.locale | string | ISO code describing language and country (en-US) |
| opts.profile.timezone | number | Hours from GMT |
| opts.profile.location | string | Location of the user |
| opts.profile.gender | string | M for male, F for female or U for unknown / other |
| opts.metadata | object | Optional object with custom metadata |
## Reply
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| threadId | string | Unique id specific to this chat |
| originator | [Originator](#Originator) | Originator |
| messages | [ 'Array' ].<ReplyMessage> | List of messages |
| messages[].fallback | string | Textual representation of any responses |
| messages[].replyTo | string | Optional replying to query |
| messages[].contexts | array | Optional List of context names |
| messages[].params | array | Optional key value pair of parameters |
| messages[].intents | array | Optional list of intent names determined |
| messages[].responses | [ 'Array' ].<Response> | List of response templates |
| messages[].responses[].type | string | Template type |
| messages[].responses[].payload | Object | Template payload |
| messages[].responses[].delay | Number | Number of seconds the response is delayed |
Reply you receive from Flow.ai
### new Reply()
Constructor
## StepAttachment
Trigger steps
### new StepAttachment(stepId)
| Param | Type | Description |
| --- | --- | --- |
| stepId | string | Immutable stepId of the step to trigger |
Constructor
**Example**
```js
const message = new Message({
attachment: new StepAttachment(stepId)
})
```
## _setCookie(name, value)
| Param | Type |
| --- | --- |
| name | string |
| value | string |
## _getCookie(name)
| Param | Type |
| --- | --- |
| name | string |