Features
This chapters looks at all Seamly features from the feature perspective and documents best practices on how to implement it on your side.
File uploads
The file uploads feature allows users to upload files. Whether uploads are allowed depends on a global Seamly account setting and on the currently attached service.
In the response to the config request a
config.features.uploads
entry might be returned. If it is present uploads a service may enable file upload.
Once the first service attaches or when a new service attaches a
ServiceAttach
message is sent. This message contains information about the ability for users to upload files in
payload.service.settings.entry.options.upload
. In case
enabled
is
true
a user may upload files. Please note that restriction to the mime type and filesize may apply (they are specified next to the
enabled
property).
Files must be sent to the uploads Api endpoint. When the request was successful (with a 201 response code), a MessageBodyUpload message will be sent over the websocket with all information so it can be rendered as a message bubble in the conversation. Note that, as a security precaution, files cannot be downloaded by users.
Context variables
Context variables allow you to add custom data to a conversation after it has been created. This can be useful when information becomes available later in the user journey, for example after closing the chat window.
Starting from Channel API v3 the create conversation response contains a
_links.context
link. Send a
PATCH
request to this URL to extend the conversation context variables.
Only the
variables
property can be updated through this endpoint. Other context properties, such as
contentLocale
and
userLocale
, can currently only be updated through the
websocket messages.
{
"variables": {
"customer": {
"id": "123"
}
}
}
More information about this endpoint can be found in the OpenAPI specification of Channel API v3.
Translation
The translation feature allows users to translate the whole conversation, including the user interface labels, to another language. Messages from the service will be translated into the user's language and messages typed by the user (in their language) will be translated to the service's language. This way a bot in a single language can be made available in a variety of languages. And it allows livechat agents to communicate in their own language while the user communicates in a completely different language.
In the response to the config request a
config.features.translation
entry might be returned. In case
enabled
is
true
, users are allowed to use the translation feature. A list of available languages to user may choose from is also returned.
The translation feature is automatically enabled when the user chooses a language that's different than the service's content language.
To switch the locale of the user do the following:
-
Send a Context message with the selected
userLocale:{ "type": "context", "payload": { "userLocale": "nl-informal" } } -
Request the language labels for the selected
userLocalefrom the account translation endpoint and replace all interface labels with the labels in the requested language.
When translations are enabled by Seamly it will be enabled for any upcoming messages; previous messages will be kept as is. With one exception: in case the user has not responded at all before translation is enabled, all messages previously sent by the service will be translated. This might help the user to understand the opening sentence from the service. If any previous messages are translated in this scenario a
UIBodyHistoryChanged
UI message will be sent, so you can send a request to the GET conversation endpoint to refetch the conversation messages, now containing the translated messages.
An optional property
"source"
can be set in the body to show from which action of the user the switch of the user locale originated. While basically any value is valid, the web-ui currently sends these values:
-
"translation_choice": when the users selects a locale from the list of available languages. -
"translation_proposal": when the user activates the language from the translation proposal element. -
"window_api": when the client activates translations without user interference (i.e. when on a translated page on the app or website).
The GET conversation request will contain information about the current state of the translation feature in the
conversation.translation
property. See the Translation schema in the OpenApi specification. When translation feature is enabled you can immediately request the language file for the translation locale.
It is possible to send the context message before the
StartConversation
message, so the conversation will have the right user locale set right away.
Typing
To notify livechat agents whether the user is typing send
ActionBodyTyping
Actions to Seamly. When the user starts typing send the following message:
{
"type": "action",
"payload": {
"type": "typing",
"state": true
}
}
Or, in case the
typingPeekahead
feature is enabled for the Seamly account (in this case the GET config endpoint response contains
config.features.typingPeekahead.enabled
= true), you should send the text the user has typed so far. Only some services implement this feature allowing agents to have a sneak peek at the text the user is typing. When enabled the message looks like:
{
"type": "action",
"payload": {
"type": "typing",
"state": true,
"body": {
"currentMessage": "Hi, I hav"
}
}
}
Once the user has not typed for a certain amount of time (~ 2 seconds), you should send the following message:
{
"type": "action",
"payload": {
"type": "typing",
"state": false
}
}
Conversation status
Internally Seamly keeps track of the current interaction status of the user. This status is updated on interactions from the user.
Initially, right after the conversation has been created by the POST conversation request, the status is set to
new
. If you don't establish a websocket connection the conversation will be shutdown after 60 seconds (this is configurable in your Seamly account).
Once you establish a websocket connection and send the
StartConversation
message the conversation status is switched to
started
. A timer is started, and in case there's no interactivity from the user for 2 minutes (this is also configurable in your Seamly account) the status is switched to
idle
.
A service might have an option enabled to detach the conversation if it has been idle for too long. Especially for livechat services it might be best to switch back to a bot service if the user didn't respond for a while. In case this option is configured an
UIBodyIdleDetachCountdown
UI message is sent from Seamly when the conversation status switches to
idle
. This message contains a
duration
after which the service will actually detach. This message allows you to display a message counting down to when the service will be detached. You can give the user two options to choose from:
-
A 'Continue this conversation' button to allow the user to continue chatting. Just send a
ActionBodyInteractivityUpdateaction message to reset all timers and set the conversation status tointeractive. -
A 'End conversation' button to allow the user to explicitly end the conversation with the current service and return to the default service (the bot for example). Send
ActionBodyDetachServiceaction message when the user chooses this option. In case the timer elapses without the user selecting an option the current service will be detached and aUIBodyIdleDetachCountdownElapsedmessage will be sent. So in any of those three cases you can remove the countdown prompt.
To prevent a conversation from being
idle
you can do any of the following things to make the conversation interactive (changes the conversation status to
interactive
):
- Send any message over the websocket.
-
Send an explicit
ActionBodyInteractivityUpdateaction message. This can be sent on any interaction with the chat, or with the window Seamly is displayed on. For example on mouse down, key up, touch start, mouse move, wheel, pointer down, pointer move or scroll. Please throttle this message so it isn't sent too much. On each of these moments the idle timer will be reset and the conversation will remaininteractivefor another 2 minutes. At this time aUIBodyIdleDetachCountdownCancelledmessage will be sent.
When you disconnect the websocket we wait for 60 seconds (configurable) before we set the conversation status to
disconnected
. This means network connectivity issues and users browsing to another page on your website do not affect the status of the conversation. Only once the user has not connected for a longer period (60 seconds) we'll update the status and notify the agents that the user has left the conversation (only some services support this and will show it to the agent). Other services might be configured to be detached if this happens. In case the conversation has been disconnected for 15 minutes (configurable) we'll shutdown the conversation completely.
Hibernation
The hibernation feature allows conversations to live an extended amount of time. By default when a conversation is shutdown (see 'Conversation status' feature on when this happens), we delete all information about the conversation. With hibernation enabled the complete conversation state is stored.
To actually use hibernation and to be able to retrieve the correct conversation state when the user returns later on we need to identify the user by a unique id; the
externalId
. This parameter must be sent along with the create conversation request. It is really important that this identifier is not guessable nor directly derivable from a user's meta data (say using a simple hash of the user's e-mail address or account number). The
externalId
must be at least 32 characters long. Any value shorter than that will be silently ignored.
In case it is the first time a conversation is created using the
externalId
a new conversation is created and the result will be the same as when the conversation was created without an
externalId
.
On a consecutive request with the same
externalId
the conversation will be fully restored, and the response to the request will contain all conversation data, including all messages.
Shutdown conversation
As described in the 'Conversation status' feature the conversation is shutdown after a certain amount of time has passed since the websocket was disconnected. Once the conversation is shutdown notifications are enabled for that conversation (in case this, and the hibernation feature, are enabled for your Seamly account), allowing notifications to be send to the user notifying the user about new messages. This will result in a gap, as the user is not notified of incoming messages received in the time frame between the disconnection and when the conversation is shutdown.
In case you know for sure the user has left you can trigger an immediate shutdown of the conversation using the DELETE conversation endpoint.
Topics
During a conversation you may switch the topic of the conversation. Usually this is implemented as a custom message or event to the connected service resulting in messages about a certain topic. For example you may add a button to your website like 'I want to cancel my subscription'. When the user clicks on the button you could then send a
ActionBodySetTopic
action message:
{
"type": "action",
"payload": {
"type": "set_topic",
"body": {
"name": "cancel_subscription",
"fallbackMessage": "Oops something went wrong setting the topic"
}
}
}
The new topic will be passed to the service and if all is fine a
InfoBodyDividerNewTopic
message will be sent over the websocket so the user can be informed that about the new topic, so the user isn't confused about why the bot suddenly starts talking about cancellation. If, somehow, the service was unable to process the topic, a new message will be sent back with the provided
fallbackMessage
.
Choice prompts
A choice prompt message is a regular text or image message along with a list of choices the user can choose from. You can present these choices as buttons for example. Clicking on a button is optional and you may still allow the user to just send in some text; Seamly (or actually, the service, will try to respond appropriately).
Each choice item has an
id
. Once the user selects a choice you must send an
ActionBodyPickChoice
action message with this
id
.
Depending on the service a choice prompt may have
chooseAgain
set to
true
. If this is the case you may allow users to scroll back to this message and let them reselect a choice. In case this happens, also set
choice.chooseAgain
to
true
in the
ActionBodyPickChoice
message.
Rich messages
Rich messages offer a richer user experience to the user than just regular text messages. Rich message types are Cards and Carousels.
Custom messages
A custom message are special messages constructed by the service and are just passed along over the websocket. This allows you to freely add message types. Every custom message has a type so you can identify it and know how to parse the freeform
data
. Is should also always contain a
text
alternative which you can use if your implementation does not (currently) support the received type of custom message. This
text
alternative is also used by Seamly in transcripts.
Send transcript
The transcript feature allows users to have a transcript of the conversation sent to their email address. In the response to the config request a
config.features.sendTranscript
entry might be returned. In case
enabled
is
true
, users are allowed to request a transcript. The
period
property will inform you about the period the transcript is about, so you can for example add a button like "Send transcript of the last 24 hours".
To make Seamly send the transcript you need to provide the user's email address and send an
ActionBodySendTranscript
action message. The transcript will be sent out immediately.
On success a
InfoBodyText
message will be sent with an informative text that the transcript was sent.
Entry types
Entry types are ways for the user to enter input. Most of the time the user will just enter text (
text
entry), but there may be other types of input; such as alphanumeric, choice prompt, date time, numeric, phone number, postal code or an upload.
The response to the conversation requests return settings regarding the various entry types in the
conversation.service.settings.entry
property.
See the Uploads feature on how, and when, to send uploads if enabled.
Besides the ability to send text or upload input at any time, a message from a service may request a specific entry response. A livechat agent for example might request a file to be uploaded and this may be reflected in the
entry
property of the message. This is really just a suggestion and Seamly will still process any text message.
The
entry
property of the last message can be used to aid the user to input the requested answer.