Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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 month ago
JSON representation

Flow.ai JavaScript SDK

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](/media/unique-threadid.png)

### 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.

![Unique sessionIds](/media/unique-sessionid.png)

### 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.

![Unique sessions and threadids](/media/unique-sessionid-threadid.png)

# 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)
})

client.send(message)
```

## 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
})

client.send(message)
```

### *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 |