Overview
The Engagement API utilizes WebSockets to create a bidirectional communication channel between the user's browser and the server. WebSockets enable sending messages to the server and receiving event-driven responses without the need for polling the server for a reply.
Steps
- Create a user: Before establishing a WebSocket connection, make sure to create a user using the appropriate API method.
- Establish a WebSocket connection: After the user has been created, establish a WebSocket connection as demonstrated in the example below.
- Join the chat channel: Use the join function of the Elixir/Channels library (e.g., Phoenix Channels JavaScript client) to join the chat channel chat:{CHAT_ID}. This step is necessary to receive messages from Pypestream and to send and receive heartbeat protocol messages, which maintain the connection. Join the chat channel before starting the engagement to ensure receipt of initial messages from the microapp.
- Wait for the chat:ready event: After sending the request to start the engagement, wait for the chat:ready event to be received via WebSocket. This event signifies that it is safe to proceed with using other endpoints, such as sending messages. If a request is sent before receiving the chat:ready event, the API will return a 428 error.
- Receive responses: When a response arrives, the incoming:msg event will be received through the WebSocket, allowing further processing or interaction.
URLs
Environment | URL |
---|---|
Sandbox | wss://engagement-api-sandbox.pypestream.com/socket/websocket |
Live | wss://engagement-api.pypestream.com/socket/websocket |
Connection Variables
To establish a sample WebSocket connection, you will need the following variables:
Variable | Description |
---|---|
token | The access token, which is returned in the Create User request. Using the Phoenix Channels JavaScript client, a WebSocket connection can be established as shown in the example below. Replace {URL} with the WebSocket URL and {MY_TOKEN} with the token retrieved from the Create User request: |
A WebSocket connection using the Phoenix Channels JavaScript client would look like this, where MY_TOKEN
is the token retrieved through the Create User:
let socket = new Socket("wss://{URL}/socket/websocket", {params: {token: {MY_TOKEN}}})
socket.connect()
Joining a Channel
To join a channel, use the .join()
function. Make sure to include the topic (see the definition of "topic" below) you're connecting to and the authorization information for that channel.
What is a topic?
A topic represents a chat. It is always a string in the format
chat:{ChatID}
, such as "chat:42c6a240-1bf9-4164-8d75-9a608f1117c9". Before sending or receiving any messages, join the "topic" using the join function from the library you're using.
After connecting to the WebSocket with the Phoenix Channels JavaScript client, establish a connection on the channel variable. This step would appear as follows:
let channel = socket.channel("chat:{ChatID}", {user_id: "{UserID}", access_token: "{AccessToken}"})
channel.join()
.receive("ok", ({messages}) => {YourSuccessFunction} )
.receive("error", ({reason}) => {YourFailureFunction} )
.receive("timeout", () => {YourTimeoutFunction})
Replace the {ChatID}, {UserID} and {AccessToken} with their respective value.
Events
The following messages can be sent through the WebSocket connection:
Event | Source | Description |
---|---|---|
chat:start | Client | Starts the engagement. After sending this event, the client must wait for the chat:ready event that will indicate that everything is ready to receive messages. |
chat:ready | Pypestream | Informs the Client that the chat is ready to receive send_message requests, if a message is received before getting this event it will be rejected with a 428 status. |
new:ping | Client | Resets the connection counter timeout. This is used to keep the connection from timing out and disconnecting. A ping message should be sent every 20 seconds to prevent disconnection. |
new:pong | Pypestream | This is sent from Pypestream back to the client as a response to the ping message. |
msg:send | Client | A message transmitted from the end-user to the microapp. |
incoming:msg | Pypestream | A message transmitted from the microapp to the end-user. |
incoming:notice | Pypestream | Enable a microapp to send a notice to the end-user of the chat. |
chat:end | Client | Terminates the chat established between the end-user and the microapp. |
chat:snapshot | Client | A request for a snapchat of the engagement as it currently stands. |
chat:snapshot_response | Pypestream | An object with all the relevant information of the engagement at the moment the request was done. |
chat:start
The chat:start
message payload has the following fields:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
app_id | string | Y | The ID of the interface this engagement is associated with. |
consumer | string | Y | The ID of the consumer interacting in this engagement. |
gateway | string | Y | Gateway type. Possible value(s): pypestream_widget |
pype_id | string | Y | The ID of the internal Pypestream environment to which the microapp is deployed. |
stream_id | string | Y | The ID of the internal "stream" that the microapp is connected to within the Pypestream environment. Multiple streams are allowed to live within one singular environment ("pype"). |
user_id | string | Y | The ID of the user interacting in this engagement. |
version | string | Y | Internal message version. Possible value(s): 1 . |
access_token | string | Y | The access token received in the Create User response. |
chat:ready
The chat:ready
message payload has the following fields:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
chat_ID | string | Y | The engagement ID. |
new:ping
The new:ping
message payload has the following fields:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
seq | number | Y | The sequential identifier. |
user_id | string | Y | ID of the user submitting the message. |
access_token | string | Y | The access token received in the Create User response. |
new:pong
The new:pong
message payload has the following fields:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
seq | number | Y | The sequential identifier. |
user_id | string | Y | ID of the user submitting the message. |
msg:send
The msg:send
message payload has the following variables:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
app_object | string | N | An object for the embedded object data. Passes through on platform side. |
campaign_id | string | N | The ID of the campaign this message originated from. |
client_msg_id | string | N | Client generated unique message ID. |
correlation_id | string | N | A unique ID set by the client which can be used to correlate the responding acknowledgement of the request. |
file | string | N | A URL to a file to embed in the message. |
file_status | string | N | Indicates if the file is available for downloading from the URL. Possible value(s): uploading , ready , failed |
from | string | Y | ID of the user submitting the message. |
from_side | string | Y | Indicates the source of the message. Possible value(s): anonymous_consumer |
gateway | string | Y | Gateway type. Possible value(s): pypestream_widget |
msg | string | N | The contents of the message being submitted. |
msg_type | string | Y | Message type. We support text and embed . If it is text , then the msg field is required, but if it is embed , then the msg will be null , and the app_object and secure_app_object fields are required. |
persist_to_history | boolean | N | Flags whether this message should be written to the persistent conversational history. |
requeued | integer | N | System use only. |
secure_app_object | boolean | N | Flags whether this is a secure message and, thus, should not be persisted to the conversation history. |
user_id | string | Y | ID of the user submitting the message. |
version | integer | Y | Internal message version. Possible value(s): 1 . |
access_token | string | Y | The access token received in the Create User response. |
incoming:msg
The incoming:msg
message payload has the following variables:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
chat_id | string | Y | ID of the conversation you're receiving the message from. |
msg_action | string | N | Action of the message. Possible value(s): new , update |
from | string | Y | ID of the user submitting the message. |
from_side | string | Y | Indicates the source of the message. Possible value(s): company , agent , manager , bot , system , anonymous_consumer |
msg_type | string | Y | The type of message. Possible value(s): text , embed |
seq_num | integer | N | Message sequence number from internal server. |
timestamp | integer | N | Datetime in Unixtime format. |
msg | string | Y | The contents of the message being submitted. |
client_msg_id | string | N | Client generated unique message ID. |
file | string | N | A URL to a file to embed in the message. |
file_status | string | N | Indicates if the file is available for downloading from the URL. Possible value(s): uploading , ready , failed |
app_object | string | N | An object for the embedded object data. |
orig_app_object | string | N | The original embedded object data if it has been changed. |
secure_app_object | boolean | N | Flags whether this is a secure message and, thus, should not be persisted to the conversation history. |
free_text | boolean | N | Flags whether this is a free text message. |
campaign_id | string | N | The ID of the campaign this message originated from. |
metadata | array | N | Metadata of the message. |
encrypted | boolean | N | Flags whether this message is encrypted. |
persist_to_history | boolean | N | Flags whether this message should be written to the persistent conversational history. |
events | array | N | List of events. |
incoming:notice
The incoming:notice
message payload has the following variables:
Variable | Type | Required | Description |
---|---|---|---|
detail | string | Y | The type of notice sent to the end-user. Possible value(s): chat |
source_action | string | Y | Possible value(s): new or update . |
origin | string | Y | Possible value(s):user , bot , system |
version | string | Y | Internal message version. Possible value(s): 1 |
data | object | Y | The payload of the notice sent. |
chat:end
The chat:end
message payload has the following variables:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
ended_by | string | Y | The agent who ended the chat. |
pype_id | string | Y | Pype ID to which this chat belongs. |
source | string | Y | The source the chat conversation was ended by. Possible value(s): agent , consumer |
user_id | string | Y | ID of the user submitting the message. |
version | integer | Y | Internal message version. Possible value(s): 1 |
access_token | string | Y | The access token received in the Create User response. |
chat:snapshot
The chat:snapshot
message payload has the following variables:
Variable | Type | Required | Description |
---|---|---|---|
from | string | Y | ID of user who requested the snapshot. |
access_token | string | Y | The access token received in the Create User response. |
chat:snapshot_response
The chat:snapshot_response
message payload has the following variables:
Variable | Type | Required (Y/N) | Description |
---|---|---|---|
id | string | Y | The ID of the engagement. |
bot | string | N | The microapp ID. |
bot_name | string | N | Name of the microapp used. |
bot_enabled | boolean | N | Flag if the engagement has a microapp enabled. |
bot_msg_count | integer | N | The number of messages sent by the microapp |
bot_started_count | integer | N | The number of microapps used. |
with_end_bot | boolean | N | Indicates if the engagement contains a survey microapp. |
target_bot_node | string | N | Last node of the microapp reached. |
app_id | string | N | The ID of the interface this engagement is associated with. |
pype_id | string | N | The ID of the internal Pypestream environment to which the microapp is deployed. |
pype_name | string | N | The name of the internal Pypestream environment to which the microapp is deployed. |
stream_id | string | N | The ID of the internal "stream" that the microapp is connected to within the Pypestream environment. Multiple streams are allowed to live within one singular environment ("pype"). |
stream_name | string | N | The name of the internal "stream" that the microapp is connected to within the Pypestream environment. |
consumer | string | N | The ID of the consumer. |
consumer_name | string | N | The name of the consumer. |
consumer_type | string | N | Type of consumer. Possible value(s): anonymous , server |
consumer_msg_count | string | N | The number of messages sent by the consumer. |
originator_user_id | string | N | The ID of the user who originated the engagement. |
originator_name | string | N | The name of the user who originated the engagement. |
originating_side | string | N | Which side started the chat. Possible value(s): consumer , bot , agent |
agent | string | N | ID of the agent assigned to the engagement. |
agent_name | string | N | The name of the agent assigned to the engagement. |
agent_routing | string | N | Contact Center Service. Possible values(s): external_agent |
agent_is_assigned | boolean | N | Indicates if an agent is assigned to the engagement. |
agent_msg_count | integer | N | The number of messages sent by the agent. |
agent_assign_ts | integer | N | Unixtime of the agent assignment time. |
agent_response_ts | integer | N | Unixtime of the last agent response. |
participant_changed | boolean | N | Indicates if the engagement participant has changed. |
participants | array | N | List of engagement participants. |
participant_history | array | N | List of engagement participant changes. |
start_ts | integer | N | Unixtime for start of the engagement. |
end_ts | integer | N | Unixtime for end of the engagement. |
last_updated | string | N | |
ended_by | string | N | ID of the user that ended the engagement. |
end_tags | string | N | Tags/codes assigned to the engagement by the agent after it is completed. |
end_comment | string | N | Comments assigned to the engagement by the agent after it is completed. |
gateway | string | N | Gateway type. Possible value(s): pypestream_widget |
history | array | N | List of all engagement messages. |
delivery_receipts | array | N | List of delivery receipts that consumer received in the engagement. |
gateway_metadata | object | N | Metadata of the engagement. |
user_read_counts | array | N | List of consumer reads. |
read_receipts | array | N | List of read receipts from consumer received in the engagement. |
version | string | N | chat:snapshot_response version |
seq_num | integer | N | Sequential number of the last message received or sent. |
status | string | N | Status of the engagement. Possible value(s): new , active , active_with_bot , active_with_agent , ended |
access_token | string | N | The access token received in the Create User response. |
encrypted | boolean | N | Indicates if the engagement is encrypted. |
persist_bot_history | boolean | N | Indicates if the engagement should save the microapp conversational history. |
initial_msg | string | N | Initial message of engagement. |
Example
Here is an example of how to push events to the channel and listen for events. In the following example, the channel is set up to listen for the "new_msg" event and send the "new_msg" event back to the Websocket.
Please see the Phoenix Channels JavaScript client documentation
let channel = socket.channel("room:123", {token: roomToken})
channel.on("new_msg", msg => console.log("Got message", msg) )
$input.onEnter( e => {
channel.push("new_msg", {body: e.target.val}, 10000)
.receive("ok", (msg) => console.log("created message", msg) )
.receive("error", (reasons) => console.log("create failed", reasons) )
.receive("timeout", () => console.log("Networking issue...") )
})
channel.join()
.receive("ok", ({messages}) => console.log("catching up", messages) )
.receive("error", ({reason}) => console.log("failed join", reason) )
.receive("timeout", () => console.log("Networking issue. Still waiting..."))
Status Codes
The following are the possible response codes based on the requests:
Status Code | Reason | Description |
---|---|---|
HTTP 400 | Missing Parameter | A requested parameter is missing from the connection request (e.g., token or user_id ). |
HTTP 403 | Invalid Token | The access token is invalid. Please see Create User for more details. |
WebSocket 1007 | Invalid Message | The message is improperly formatted. |
WebSocket 1000 | Timeout | The WebSocket session has timed out. |