Oracle Digital Assistant Native Client SDK for Web
Release 25.08
Enhance your website or web app with live, production-grade chat using the Oracle Digital Assistant (ODA) Web SDK. This SDK offers a flexible, customizable chat widget, a headless API for building fully custom UIs, advanced messaging features, and robust support for attachments, voice, forms, internationalization, and accessibility.
Introduction
The ODA Web SDK enables you to:
- Embed a highly configurable chat widget or use headless mode to build your own interface.
- Customize themes, icons, colors, layout, and localization.
- Leverage advanced features such as voice messaging, TTS, autocomplete, live agent handoff, cross-tab sync, and more.
- Ensure accessibility with keyboard navigation and screen-reader support.
Integrate conversational experiences, bot flows, or live agent capabilities into any website or single-page application.
Installation
Quick Start (Script Tag)
- Host SDK: Serve
web-sdk.js
yourself or use Oracle's CDN. - Initialization:
Create a
settings.js
file to configure and connect the widget:// settings.js const chatSettings = { URI: '<Server URI>', channelId: '<Channel ID>', userId: '<User ID>' // optional; random ID will be generated if omitted }; function initSDK(name) { // Wait until the SDK global is available if (!document || !window.WebSDK) { setTimeout(() => initSDK(name), 2000); return; } const ns = name || 'Bots'; const Bots = new WebSDK(chatSettings); let firstOpen = true; Bots.on(WebSDK.EVENT.WIDGET_OPENED, async () => { if (firstOpen) { try { await Bots.connect(); console.log('Connection Successful'); } catch (error) { console.error('Connection failed', error); } firstOpen = false; } }); window[ns] = Bots; }
- Include scripts in your page:
<head> <script src="settings.js" defer></script> <script src="<WebSDK URL>" onload="initSDK('Bots')" defer></script> </head>
Note:
Client‑auth enabled channels require a JWT token generator function (see Security).Using the Oracle CDN
You can also load the Web SDK from Oracle's Content Delivery Network (CDN). Using a CDN can offer benefits such as faster load times due to geographically distributed servers and a reduced hosting burden, as you won't need to host the
web-sdk.js
file yourself.<head> <script src="settings.js" defer></script> <!-- Pin a specific version in production --> <script src="https://static.oracle.com/cdn/oda/25.8.0/web-sdk.js" onload="initSDK('Bots')" defer></script> <!-- or track latest stable (use with caution in production) --> <!-- <script src="https://static.oracle.com/cdn/oda/latest/web-sdk.js" onload="initSDK('Bots')" defer></script> --> </head>
Official CDN URLs:
- Latest stable: https://static.oracle.com/cdn/oda/latest/web-sdk.js
- Versioned: https://static.oracle.com/cdn/oda/\
/web-sdk.js - v25.08 -
https://static.oracle.com/cdn/oda/25.8.0/web-sdk.js
- v25.04 -
https://static.oracle.com/cdn/oda/25.4.0/web-sdk.js
- v25.02 -
https://static.oracle.com/cdn/oda/25.2.0/web-sdk.js
- v24.12 -
https://static.oracle.com/cdn/oda/24.12.0/web-sdk.js
- v24.10 -
https://static.oracle.com/cdn/oda/24.10.0/web-sdk.js
- v24.08 -
https://static.oracle.com/cdn/oda/24.8.0/web-sdk.js
- v24.06 -
https://static.oracle.com/cdn/oda/24.6.0/web-sdk.js
- v24.04 -
https://static.oracle.com/cdn/oda/24.4.0/web-sdk.js
- v24.02 -
https://static.oracle.com/cdn/oda/24.2.0/web-sdk.js
- v25.08 -
Tip:
To control updates, pin a specific version for production.Dynamic Import (Utility)
You can dynamically inject the SDK from JavaScript if needed using the following utility function, which is based on the MDN example:
function fetchSDK(src, onloadFunction, name) {
const script = document.createElement('script');
script.type = 'application/javascript';
script.defer = true;
script.onload = () => onloadFunction(name);
document.head.appendChild(script);
script.src = src;
}
fetchSDK('<path-to-web-sdk.js>', initSDK, 'Bots');
AMD Modules
Load the SDK with RequireJS or SystemJS:
requirejs.config({
paths: {
WebSDK: '<path-to-web-sdk>' // without the .js extension
}
});
define(['WebSDK'], (WebSDK) => {
const settings = {
URI: '<Server URI>',
channelId: '<Channel ID>',
userId: '<User ID>'
};
const Bots = new WebSDK(settings);
Bots.connect();
});
Browser Support
Desktop (macOS, Windows, Linux):
- Chrome, Firefox, Edge, Safari
Mobile:
- Android Browser
- iOS Safari
Security
The SDK connects to an ODA Web Channel either with client auth disabled or enabled. Use client auth enabled whenever you can provision secure server‑side token generation.
Channel with Client Auth Disabled
When client authentication is disabled, only connections made from allowed domains (unblocked lists) are accepted. This use case is recommended when the client application can't generate a signed JWT Token but requires ODA integration.
channelId
is required.userId
is required; a random one is generated if omitted.{ URI: 'oda-instance.com', channelId: '626f5db1-f99a-4984-86ee-df2d734537e6', userId: 'Jessica' }
Channel with Client Auth Enabled
When client auth is enabled, the authentication enforces a signed JWT in addition to allowed domains. Tokens must be generated and signed by your backend that safely stores the channel keyId
and keySecret
.
To enable this mode, these two fields are required during SDK initialization:
clientAuthEnabled: true
in settings- A token generator function (returns a Promise resolving to the signed JWT string)
async function generateToken() { // Return a signed JWT string from your backend const response = await fetch('https://yourbackend.com/endpointToGenerateJWTToken'); if (!response.ok) { throw new Error('Token fetch failed'); } return response.text(); // or response.json() depending on your endpoint } const Bots = new WebSDK( { URI: 'oda-instance.com', clientAuthEnabled: true }, generateToken );
JWT Token Requirements
The JWT token generation and signing are the responsibility of the client application. Some token payload fields are mandatory and are validated by the ODA server.
The tokens must be signed with HS256 using the Web Channel's secret. Required claims are:
iat
number (seconds since UNIX epoch)exp
number (seconds since UNIX epoch)channelId
stringuserId
string
Header:
{ "typ": "JWT", "alg": "HS256" }
Payload:
{
"iat": 1576747205,
"exp": 1576748406,
"channelId": "4920595c-ec79-4617-af9f-5950d603f8bb",
"userId": "John"
}
If claims are missing or malformed, the SDK throws an error and does not attempt a connection.
Configuration
Configure the widget by passing settings to the WebSDK
constructor.
Network
Property | Optional | Default | Description |
---|---|---|---|
URI |
No | Hostname of the ODA instance. Pass with or without protocol. | |
channelId |
No | Web Channel ID. | |
userId |
Yes | random | Unique user identifier. Generated if omitted. |
clientAuthEnabled |
Yes | false |
Enable when connecting with JWT client authentication. |
Feature Flags
Property | Default | Description |
---|---|---|
delegate |
Delegate callbacks for interception and custom rendering. See Delegation | |
embedded |
false |
Render widget inside targetElement . See Embedded mode. |
targetElement |
Element ID for embedded mode (required when embedded is true). |
|
enableAttachment |
true |
Enable file and location sharing. |
enableAttachmentSecurity |
false |
Client‑auth enabled only. Adds auth headers to attachment requests. |
enableHeaderActionCollapse |
true |
Collapse header actions into a menu if > 2 buttons. |
shareMenuItems |
['audio','file','location','visual'] |
Configure attachment categories and custom items. See Restrict attachment types. |
enableAutocomplete |
false |
Suggest queries as the user types. See Autocomplete. |
enableAutocompleteClientCache |
false |
Client‑side caching for autocomplete. |
enableBotAudioResponse |
false |
Speak responses via TTS. See Text‑to‑Speech. |
enableDefaultClientResponse |
false |
Show client‑side default messages when responses are delayed. See Default Client Responses. |
enableOldLinkAdvisory |
false |
Advisory tooltip for older conversation links. |
enableVoiceOnlyMode |
false |
Auto‑start voice recognition after responses, enabling the voice-only mode. |
initBotAudioMuted |
true |
Start TTS muted (when TTS enabled). |
disableInlineCSS |
false |
Prevent SDK from injecting inline CSS (you must provide CSS). |
ttsVoice |
Preferred voices array for TTS. | |
ttsService |
'oracle' |
TTS provider. See Speech Synthesis Service Injection. |
enableHeadless |
false |
Headless mode (no UI). See Headless SDK. |
enableLongPolling |
false |
HTTP long‑poll fallback when WebSocket not available. See Long Polling. |
enableSpeech |
false |
Enable voice recognition. See Voice Recognition. |
enableSpeechAutoSend |
true |
Auto‑send recognized text to the ODA. |
speechLocale |
'en-us' |
Recognition locale. See WebSDK.SPEECH_LOCALE. |
enableTabsSync |
true |
Sync conversation across tabs. See Cross‑Tab Conversation Synchronization. |
timestampMode |
'relative' |
Show timestamp with messages. Set 'absolute' for full timestamp with each message, 'relative' for relative timestamp next to latest response, 'none' to disable. |
timestampFormat |
Intl.DateTimeFormat options or pattern. See Format message timestamps. string. |
|
timestampHeaderMode |
'absolute' |
Header timestamp above first message of the day. Use 'absolute' for full timestamp, 'relative' for relative format, 'none' to hide it. |
timestampHeaderFormat |
Formatting for header timestamps. Accepts values in the DateTimeFormat options object or a pattern string compatible with timestampFormat . |
|
multiLangChat |
Enable language selection and/or detection. See Multi-Lingual Chat. | |
webViewConfig |
{ referrerPolicy: 'no-referrer-when-downgrade', closeButtonType: 'icon', size: 'tall' } |
Configure in‑widget Webview. See In-Widget Webview. |
Functionality
Property | Default | Description |
---|---|---|
alwaysShowSendButton |
false |
Always show send button. |
customHeaderElementId |
Inject a custom element into header. | |
disablePastActions |
'all' |
'all' , 'none' , 'postback' to disable actions of past messages. |
defaultGreetingTimeout |
5 |
Seconds before greeting message appears when response is delayed. |
defaultWaitMessageInterval |
5 |
Interval in seconds between wait messages. |
displayActionsAsPills |
false |
Display local actions with global actions outside bubble. |
embeddedVideo |
true |
Inline supported platforms' videos in messages. |
embedBottomScrollId |
Element to render below conversation (scrollable). | |
embedBottomStickyId |
Element to pin at bottom. | |
embedTopScrollId |
Element to render above conversation (scrollable). | |
embedTopStickyId |
Element to pin at top. | |
enableAgentSneakPreview |
false |
Send current user text to live agent (requires OSvC Sneak Preview). |
enableClearMessage |
false |
Show clear conversation button. |
enableDraggableButton |
false |
Make launch button draggable. See Draggable Launch Button and widget. |
enableDraggableWidget |
false |
Make expanded widget draggable. See Draggable Launch Button and widget. |
enableEndConversation |
true |
Enable ending the current session. |
enableLocalConversationHistory |
false |
Load previous conversations for provided userId . |
enableResizableWidget |
false |
Resize edges/corners of expanded widget. |
enableSendTypingStatus |
false |
Send typing status to live agent. |
focusOnNewMessage |
'input' |
'input' or 'action' to focus first action button. See Focus First Action of Response Message. |
hotkeys |
{} |
Define ALT+key shortcuts for elements. See Keyboard Shortcuts - Hotkeys. |
i18n |
{'en': {...}} |
Per‑locale strings for UI and a11y text. See Text (i18n). |
icons |
{} |
Custom icons (URL or inline SVG). |
initUserHiddenMessage |
Send a hidden user message on connect/open. | |
initUserProfile |
Initialize user profile before conversation starts. | |
initMessageOptions |
{ sendAt: 'expand' } |
'expand' or 'init' timing for init messages/profile. |
isDebugMode |
false |
Log debug statements to console. |
linkHandler |
{ onclick, target } |
Override link handling (see Webview/Open Links). See Open Links. |
locale |
'en' |
UI locale. Fallback logic described below. |
messageCacheSizeLimit |
2000 |
Max messages stored in web storage. |
name |
'oda-chat' |
Namespace for CSS classes and element IDs. |
noSpeechTimeout |
0 (ODA) / 30 (OCI) |
Seconds to stop recognition if no voice detected. |
ociSpeechConfig |
Configuration for OCI speech service based recognition | |
openChatOnLoad |
false |
Expand chat on initialization. |
openLinksInNewWindow |
false |
Force window open instead of following browser prefs. See See Open Links. |
reconnectInterval |
5 |
Seconds between reconnect attempts. |
reconnectMaxAttempts |
5 |
Max reconnect attempts. |
showConnectionStatus |
false |
Show connection state in header subtitle. |
showPrevConvStatus |
true |
Show "end of previous conversation" marker. |
showTypingIndicator |
true |
Show typing indicator while waiting for response. |
typingIndicatorTimeout |
30 |
Auto hide typing indicator after N seconds. |
typingStatusInterval |
3 |
Throttle user typing status to agent (seconds). |
storageType |
'localStorage' |
'localStorage' or 'sessionStorage' . |
theme |
'default' |
'default' , 'redwood-dark' , 'classic' . |
Layout
Property | Default | Description |
---|---|---|
actionsLayout |
'vertical' |
Local action layout orientation. |
badgePosition |
{ top: '0', right: '0' } |
Notification badge position relative to launch button. |
cardActionsLayout |
'vertical' |
Card actions orientation. |
formActionsLayout |
'vertical' |
Form actions orientation. |
colors |
{branding:'#1B8FD2',text:'#212121',textLight:'#737373'} |
Color config (see Colors). |
conversationBeginPosition |
'bottom' |
Start conversation at top or bottom. |
font |
16px "Oracle Sans", ... |
Font shorthand for wrapper. |
fontFamily |
"Oracle Sans", ... |
Font family for all text (overrides font ). |
fontSize |
'16px' |
Base font size (overrides font ). |
globalActionsLayout |
'vertical' |
Global action orientation. |
height |
'620px' |
Widget height. |
messagePadding |
'6px 16px' |
Bubble padding. |
position |
{ bottom:'20px', right:'20px' } |
Fixed position for floating widget. |
width |
'375px' |
Widget width. |
Colors
You can modify the following colors to customize the look of the widget. Provide either:
- CSS variables on
.oda-chat-wrapper
(recommended), or colors
config object
Most UI elements have dedicated variables/keys. Example (CSS variables):
.oda-chat-wrapper {
--color-branding: #e00;
--color-text: #545454;
}
Equivalent config:
colors: {
branding: '#e00',
text: '#545454'
}
See the full colors reference table for the full list of supported variables/keys.
Icons
The icons used in the widget can be customized in two ways - image URLs or inline SVG strings. Inline SVGs allow theming and animation.
Example:
const settings = {
icons: {
rating: '<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24"><path d="M15.994 3.006a5.7 5.7 0 00-3.795 1.707L12 4.916l-.199-.202a5.676 5.676 0 00-8.128 0c-2.231 2.275-2.231 5.953 0 8.228L12 21.428l8.326-8.486A5.873 5.873 0 0022 8.828a5.873 5.873 0 00-1.675-4.115A5.693 5.693 0 0016.262 3z"/></svg>'
}
};
The complete list of icon property mappings are available at Full Icons Reference.
You can also control the typing indicator icon size via:
chatBubbleIconHeight
,chatBubbleIconWidth
- or
setChatBubbleIconSize(width, height)
Text (i18n)
Provide per‑locale strings under i18n
. Keys include UI labels, a11y strings, and fallbacks:
i18n: {
fr: { chatTitle: 'Soutien' },
en: { chatTitle: 'Support' },
es: { chatTitle: 'Apoyo' },
'zh-cn': { chatTitle: '支持' }
}
- If you provide any locale other than
en
, include all keys for that locale; missing keys fall back toen
. - See the Full Text (i18n) Keys Reference for all customizable strings.
Keyboard Shortcuts (Hotkeys)
Use ALT + key (a‑z, 0‑9) to focus/activate UI elements:
const settings = {
hotkeys: {
launch: 'l', // ALT+L to launch
collapse: 'c', // ALT+C to collapse
input: 'i',
send: 's'
}
};
Supported keys map to elements like launch
, close
, send
, mic
, keyboard
, shareMenu
, etc. See the Full Hotkeys Element Map for details.
CSS Class Hooks
Override styles by targeting these classes:
Class | Component |
---|---|
oda-chat-wrapper |
Root wrapper |
oda-chat-button |
Launch button |
oda-chat-widget |
Expanded widget |
oda-chat-header |
Header |
oda-chat-title |
Header title |
oda-chat-footer |
Footer |
oda-chat-message |
Message wrapper |
oda-chat-left / oda-chat-right |
Bot/User bubble wrappers |
… | See Full CSS Class Hooks all hooks |
Usage Examples
Initialize and Connect
<script>
const chatSettings = {
URI: '<Chat server URI>',
channelId: '<Channel ID>',
userId: '<User ID>',
fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif',
locale: 'en',
enableClearMessage: true,
icons: {
launch: 'style/Robot.png',
avatarBot: 'style/Robot.png',
avatarUser: 'style/userIcon.png'
}
};
function initSDK(name) {
if (!document || !window.WebSDK) {
setTimeout(() => initSDK(name), 2000);
return;
}
const ns = name || 'Bots';
setTimeout(() => {
const Bots = new WebSDK(chatSettings);
// Register events BEFORE connect
Bots.on(WebSDK.EVENT.READY, () => {
console.log('Widget ready');
});
Bots.connect();
window[ns] = Bots;
}, 0);
}
</script>
<script src="<WebSDK URL>" onload="initSDK('Bots')" defer></script>
Handle Events
Bots.on(WebSDK.EVENT.MESSAGE_SENT, (msg) => {
console.log('User sent:', msg);
});
Bots.on(WebSDK.EVENT.MESSAGE_RECEIVED, (msg) => {
console.log('Bot sent:', msg);
});
Bots.on(WebSDK.EVENT.NETWORK, (status) => {
// WebSocket.CONNECTING=0, OPEN=1, CLOSING=2, CLOSED=3
console.log('Network status:', status);
});
Send Messages and Attachments
// Simple text
await Bots.sendMessage('Show my payslip');
// Structured text
await Bots.sendMessage({ type: 'text', text: 'Show menu' });
// Postback
await Bots.sendMessage({
type: 'postback',
text: 'Order Pizza',
postback: {
'system.botId': '5409672A-AB06-4109-8303-318F5EDE91AA',
'system.state': 'ShowMenu',
action: 'pizza',
variables: {}
}
});
// Attachment (file input change)
const file = document.querySelector('#file').files[0];
await Bots.sendAttachment(file);
// Hidden user message (not shown in UI)
await Bots.sendMessage('What is the menu today?', { hidden: true });
Headless Usage
const Bots = new WebSDK({ /* settings */, enableHeadless: true });
await Bots.connect();
Bots.on(WebSDK.EVENT.MESSAGE_RECEIVED, (message) => {
// Render your own UI
});
await Bots.sendMessage('Hello from headless UI!');
Open Links in the In‑Widget Webview
Open all links inside the widget:
const Bots = new WebSDK({
// ...
linkHandler: { target: 'oda-chat-webview' },
webViewConfig: {
accessibilityTitle: 'In‑widget Webview',
size: 'tall',
sandbox: ['allow-scripts', 'allow-downloads']
}
});
Open only specific links via delegate:
const Bots = new WebSDK({
// ...
delegate: {
beforeDisplay(message) {
// Convert URL actions to open in webview
const mp = message?.messagePayload;
if (mp?.actions?.length) {
mp.actions.forEach(a => {
if (a.type === 'url') a.type = 'webview';
});
}
return message;
}
}
});
Multi‑Lingual Chat (Quick Setup)
const Bots = new WebSDK({
// ...
multiLangChat: {
supportedLangs: [
{ lang: 'en' },
{ lang: 'es', label: 'Español' },
{ lang: 'fr', label: 'Français' },
{ lang: 'hi', label: 'हिंदी' }
],
primary: 'en'
}
});
// Dynamically switch
Bots.setPrimaryChatLanguage('fr'); // or 'und' to auto‑detect
API Reference
This section documents runtime enums, methods, and events.
Enums
WebSDK.EVENT
Subscribe with Bots.on(WebSDK.EVENT.<NAME>, handler)
:
CHAT_LANG
-'chatlanguagechange'
CHAT_END
-'chatend'
CLICK_AUDIO_RESPONSE_TOGGLE
-'click:audiotoggle'
CLICK_ERASE
-'click:erase'
CLICK_VOICE_TOGGLE
-'click:voicetoggle'
DESTROY
-'destroy'
MESSAGE
-'message'
MESSAGE_RECEIVED
-'message:received'
MESSAGE_SENT
-'message:sent'
NETWORK
-'networkstatuschange'
READY
-'ready'
TYPING
-'typing'
UNREAD
-'unreadCount'
WIDGET_CLOSED
-'widget:closed'
WIDGET_OPENED
-'widget:opened'
WIDGET_SHOW
-'widget:show'
WIDGET_HIDE
-'widget:hide'
TTSStart
-'tts:start'
TTSStop
-'tts:stop'
For details about each event, see Events.
WebSDK.SPEECH_LOCALE
This enum provides the locales that are supported by the voice recognition service. The ODA Supported locales for voice recognition are:
DE_DE
-'de-de'
- GermanEN_AU
-'en-au'
- English (Australian)EN_IN
-'en-in'
- English (India)EN_GB
-'en-gb'
- English (UK)EN_US
-'en-us'
- English (US)ES_ES
-'es-es'
- SpanishFR_FR
-'fr-fr'
- FrenchHI_IN
-'hi-in'
- HindiIT_IT
-'it-it'
- ItalianPT_BR
-'pt-br'
- Portuguese (Brazilian)
With OCI Speech integration, more languages can be added for recognition.
The enum values can be passed in the speechLocale
setting or setSpeechLocale(locale) API.
WebSDK.THEME
This enum provides the themes that can be applied to the chat widget. The values are:
DEFAULT
-'default'
(WCAG AAA contrast)REDWOOD_DARK
-'redwood-dark'
(WCAG AA)CLASSIC
-'classic'
WebSDK.TTS
This enum provides the text-to-speech (TTS) services that are exposed . The values are:
platform
(Web Speech API)oracle
(OCI TTS)
You can set the service in settings with ttsService
or via setTTSService()
.
Methods
The SDK namespace is the name you pass to initSDK
. For example, with initSDK('Bots')
, call methods as Bots.<method>()
.
Core connection and lifecycle:
connect()
Connects to the current chat server.
Bots.connect()
The API returns a Promise
which can be used to execute code after the connection is complete or closed.
try {
await Bots.connect();
// Successful connection
} catch (error) {
// Something went wrong during connection
}
connect(config)
Connects to current chat server with passed parameters. All fields are optional, if a field is not passed and is already set from initial settings or an earlier invocation, the existing value is reused. If userId
is not passed and is not set so far, a random userId is generated and used.
Bots.connect({
URI: '<URI>',
channelId: '<channelId>',
userId: '<userId>'
})
The API returns a Promise
which can be used to execute code after the connection is complete or closed.
try {
await Bots.connect({
URI: '<URI>'
channelId: '<channelId>',
userId: '<userId>'});
// Successful connection
} catch (error) {
// Something went wrong during connection
}
The call to connect()
API can result in a new connection or continuing existing connection depending on a few factors:
- On calling
connect()
with no parameters during no active connection, a new connection is initiated using the existing settings. For client auth enabled mode, a new token is fetched to open the connection. - On calling
connect(param)
with parameters during no active connection, a new connection is initiated using the passed parameters. For client auth enabled mode, parameters other thanURI
are ignored, as thechannelId
anduserId
are parsed from the token. - On calling
connect()
with no parameters during an active connection, the current connection is continued, and the returned Promise is immediately resolved. - On calling
connect(params)
with parameters during an active connection in client auth disabled mode, if the passed parameters are the same as existing parameters, the current connection is continued. - On calling
connect(params)
with parameters during an active connection in client auth disabled mode, if the passed parameters are different from existing parameters, the current connection is closed and a new connection is initiated with passed parameters. - On calling
connect(params)
with parameters during an active connection in client auth enabled mode, the current connection is closed and a new connection is initiated with a new token only if a newURI
is passed in parameters. Otherwise, the current connection is continued.
disconnect()
Closes the currently active connection to the chat server. This includes closing the connection to the chat server, any active voice recognition, ongoing attachment uploads, and running speech synthesis.
Bots.disconnect()
The API returns a Promise
which is resolved when the connection is closed.
await Bots.disconnect();
console.log('The connection is now closed');
isConnected()
Returns whether the connection to the chat server is currently active.
Bots.isConnected()
endChat()
Ends the current conversation session. The SDK sends an event message to the digital assistant to mark the conversation as complete. It then closes the connection, collapses the chat widget, erases the user's conversation history, and triggers the 'chatend'
event for subscribers.
Bots.endChat()
destroy()
Destroys the SDK instance by closing any active connection, voice recognition, speech synthesis, file uploads, and by removing the widget from the UI. Once called, none of the current instance methods can be called afterward.
Bots.destroy();
Widget visibility and state:
openChat()
Opens the chat widget popup.
Bots.openChat();
closeChat()
Collapses the chat widget and displays the chat icon.
Bots.closeChat();
isChatOpened()
Returns true
if the widget is open. Otherwise, it returns false
.
Bots.isChatOpened();
showWidget()
Displays the chat widget in its collapsed or expanded state if it is hidden from the page. The method invocation is ignored in the embedded or headless modes.
Bots.showWidget();
hideWidget()
Hides the chat widget in its collapsed or expanded state if it is visible on the page. The method invocation is ignored in the embedded or headless modes.
Bots.hideWidget();
Messaging:
sendMessage(message, options)
Sends a message on the user's behalf. Returns a Promise
that is resolved with the user message on success, or gets rejected with an error message for an unsuccessful delivery or an invalid message payload. The user message is not displayed if the Promise
is rejected.
Bots.sendMessage({
type: 'text',
text: 'hello'
});
// OR
Bots.sendMessage('hello');
The messages can be sent in these formats:
- Passing text string:
Bots.sendMessage('Show my payslip')
- You can also pass location coordinates:
Bots.sendMessage('32.323232, 143.434343') // Latitude, longitude
- Passing
messagePayload
of message:Bots.sendMessage({ type: 'text', text: 'Show menu' }) Bots.sendMessage({ postback: { variables: {}, 'system.botId': '5409672A-AB06-4109-8303-318F5EDE91AA', action: 'pizza', 'system.state': 'ShowMenu' }, text: 'Order Pizza', type: 'postback' })
- passing entire message:
Bots.sendMessage({ messagePayload: { postback: { variables: {}, system.botId: '5409672A-AB06-4109-8303-318F5EDE91AA', action: 'pizza', 'system.state': 'ShowMenu' }, text: 'Order Pizza', type: 'postback' }, userId: 'Guest' })
Note:
To keep the message from being displayed in the widget, pass thehidden
boolean flag in the options object:
Bots.sendMessage('What is the menu today?', { hidden: true });
This call sends the message to the server without displaying it in the widget.sendAttachment(file)
Uploads file to the server. Returns a Promise
that is resolved with the server response for successful uploads, or gets rejected with an error message for unsuccessful uploads.
try {
const result = await Bots.sendAttachment(file);
console.log('File uploaded successfully.');
} catch (error) {
console.log(reason);
}
sendUserTypingStatus(status, userText)
Sends the user's typing status to the agent. The status can be either RESPONDING
or LISTENING
, where RESPONDING
represents the user typing activity. Use this API to send the user typing status when running in headless mode.
Bots.sendUserTypingStatus('RESPONDING', 'Hello!'); // Send typing status for the user with the user text `Hello!`
Bots.sendUserTypingStatus('LISTENING'); // Send listening status for the user
getConversationHistory()
Returns information about the current conversation for the user. The response is an object containing user ID, messages, and unread message count.
Bots.getConversationHistory()
{
messages: [
{
date: '2020-01-22T17:06:24.085Z',
isRead: true,
messagePayload: {
text: 'show menu',
type: 'text'
},
userId: 'user74882436'
}
],
messageCount: 1,
unread: 0,
userId: 'user74882436'
}
clearConversationHistory(userId, shouldClearWidget)
This API clears the conversation history for a known user from the browser's localStorage. The userId
must be a string. On passing an empty or no userId, the current user's history is removed.
If the passed userId
is the same as the current user's userId
, then you can also pass an optional boolean argument, shouldClearWidget
, to configure whether the current chat widget UI should also be cleared on calling this API. By default, the value is true
.
Bots.clearConversationHistory('Jonathan');
// Removes conversation history of Jonathan
Bots.clearConversationHistory('Adriana');
// Removes conversation history of Adriana and clears the widget UI if Adriana is current user
Bots.clearConversationHistory('', false);
// Removes conversation history of current user without clearing the widget UI
Note:
This API does not interact withsessionStorage
for users other than the current user. The sessionStorage
is automatically cleared on closing the tab.
clearAllConversationsHistory(shouldClearWidget)
This API clears the conversation history for all users from the browser's localStorage. You can also pass an optional boolean argument, shouldClearWidget
, to configure whether the current chat widget UI should also be cleared on calling this API.
Bots.clearAllConversationsHistory()
Caution:
The actions taken by calling this API cannot be undone. Once the messages are deleted, they cannot be recovered. Call this method sparingly and only when absolutely needed.Like clearConversationHistory
, this method can also help in recovering significant portions of localStorage from the user's browser.
By default, the value is true
.
Note:
This API does not interact withsessionStorage
for users other than the current user. The sessionStorage
is automatically cleared on closing the tab.
getUnreadMessagesCount()
Returns the count of the unread messages.
Bots.getUnreadMessagesCount();
setAllMessagesAsRead()
Marks all messages as have been read/seen by the user.
Bots.getUnreadMessagesCount(); // 2
Bots.setAllMessagesAsRead();
Bots.getUnreadMessagesCount(); // 0
setUserInputMessage(text)
Populates the user input field with the passed message.
Bots.setUserInputMessage('Show my agenda for today please.');
setUserInputPlaceholder(text)
Updates user input's placeholder text. It can be used to change the placeholder text according to the input expected from the user.
Bots.setUserInputPlaceholder('Add your pizza topping');
showTypingIndicator()
Displays the typing indicator in the conversation. If the typing indicator is already visible, then the timer to hide it gets reset. The typing indicator is automatically removed if the server sends a response, or the timer period set by typingIndicatorTimeout
(in seconds) has expired.
The method only works if the showTypingIndicator
setting is set to true
, the SDK is not in headless mode, and the widget is connected to the server.
Bots.showTypingIndicator();
User/Agent Data:
updateUser(userDetails)
Updates the user information.
Bots.updateUser({
messagePayload: {
text: 'give me a pizza',
type: 'text'
},
profile: {
firstName: 'Jane',
lastName: 'Smith',
email: 'updated@email.com',
properties: {
justGotUpdated: true
}
}
});
Note:
You can also use theinitUserProfile
property to set profile values. If you use the initUserHiddenMessage
property, and the response from the server is expected to have user profile values, then you must use the initUserProfile
property instead of setting the values in updateUser()
. For later updates to the user profile, use updateUser()
.
setUserAvatar(userAvatar)
Sets the user avatar. The value passed must be the URL of the image source, or the source string of the SVG image that should be displayed alongside the user messages.
Bots.setUserAvatar('../assets/images/avatar-user.jpg');
setAgentDetails(agentDetails)
Sets the current agent details that should be displayed for agent messages. If there is an agent handover, the latest agent details will replace the details set by this API. All fields are optional, so if a field is not passed and is already set from the initial settings or an earlier invocation, the existing value is reused. The value passed for avatarImage
must be the URL of the image source, or the source string of the SVG image that should be displayed alongside the agent messages. The values passed for nameTextColor
, avatarTextColor
, and avatarBackgroundColor
must be in standard color format.
Bots.setAgentDetails({
name: 'Ana Lee',
avatarImage: '../assets/images/avatar-agent.jpg',
nameTextColor: 'rgba(22, 21, 19, 0.65)',
avatarTextColor: 'green',
avatarBackgroundColor: '#A890B6'
});
Note:
This API does not change the previous agent details. These passed values will have the lifetime of the current agent session onlygetAgentDetails()
Returns the current agent details.
Bots.getAgentDetails();
Autocomplete:
getSuggestions(query)
If the autocomplete feature is enabled (enableAutocomplete: true
), this API returns a Promise
that resolves to the suggestions for the given query string. If it takes too long (~10s) to fetch the suggestion, the Promise
is rejected.
try {
const suggestions = await Bots.getSuggestions('pizza');
const suggestionString = suggestions.toString();
console.log('The suggestions are: ', suggestionString);
} catch (error) {
console.log('Suggestion request failed', error);
}
The API expects a single query string parameter and returns a Promise
. On a successful request for suggestions, the Promise
is resolved to a string array. On failure, the Promise
is rejected with an error message.
If the API is called when the feature is disabled, it returns a rejected Promise.
Voice & TTS:
startVoiceRecording(onSpeechRecognition, onSpeechNetworkChange, options)
Starts the voice recording if the speech recognition feature is enabled. The API returns a Promise
that is resolved when the speech service starts recording. In case of an error, the Promise
is rejected with an Error object.
The API expects two callbacks to be passed as its parameters:
onSpeechRecognition
function is called on the speech server response. The JSON response is passed as a parameter.
onSpeechNetworkChange
function is called on a change in the speech connection. A single parameter, the WebSocket status, is passed.
Bots.startVoiceRecording(function(data) {
let recognizedText = '';
if (data && (data.event === 'finalResult' || data.event === 'partialResult')) {
if (data.nbest && data.nbest.length > 0) {
recognizedText = data.nbest[0].utterance;
}
}
}, function(status) {
if (status === WebSocket.OPEN) {
// Connection established
} else if (status === WebSocket.CLOSED) {
// Connection closed
}
})
The function also accepts an optional options
object that can have fields for two callback functions for the analyser - onAnalyserReady
, and onAnalyserFrequencies
. Either one, or both, fields can be passed.
These callbacks can be used to get regular frequency values for visualization.
onAnalyserReady
is a one-time callback that is called when the analyser node is initialized. The callback method is passed as a single argument, an AnalyserNode
, which is configured with a fftSize
of 256, and connected to the voice input source.
onAnalyserFrequencies
is a callback method that is called every time a new set of voice input frequencies are provided by the analyser node. The callback method is passed a single argument, an Uint8Array
of size 128, depicting the frequency data composed of integers on a scale from 0 to 255. Each item in the array represents the decibel value for a specific frequency. The frequencies are spread linearly from 0 to 1/2 of the sample rate. For example, for the 48000 sample rate, the last item of the array will represent the decibel value for 24000 Hz.
Bots.startVoiceRecording(function(data) {
let recognizedText = '';
if (data && (data.event === 'finalResult' || data.event === 'partialResult')) {
if (data.nbest && data.nbest.length > 0) {
recognizedText = data.nbest[0].utterance;
}
}
}, function(status) {
if (status === WebSocket.OPEN) {
// Connection established
} else if (status === WebSocket.CLOSED) {
// Connection closed
}
}, {
onAnalyserReady: function(analyserNode) { console.log('The analyser node is', analyserNode); },
onAnalyserFrequencies: function(frequencies) { console.log('New input frequencies are', frequencies); }
})
stopVoiceRecording()
Stops any running voice recording. Throws an error if speech recognition is not enabled.
Bots.stopVoiceRecording()
setSpeechLocale(locale)
Sets the locale used for speech connection. The user is expected to speak with the same locale that is set here to the SDK. The list of currently supported locales is available at WebSDK.SPEECH_LOCALE. If an unsupported locale is passed, the API returns false
while maintaining the passed locale. In such a case, any voice recognition attempt is failed.
The function returns a boolean indicating whether the passed locale is supported or not.
Bots.setSpeechLocale('fr-fr');
Note:
When both voice recognition and audio response are enabled but the audio response locale is not set, then the locale for the audio response voice gets set to the same locale as the voice recognition locale.In this example, the locale for audio response voice is set to 'es-es'
automatically.
const Bots = new WebSDK({
// ...,
enableSpeech: true,
enableBotAudioResponse: true
});
// ...
Bots.setSpeechLocale('es-es');
setPrimaryChatLanguage(languageTag)
Updates the language selected for the conversation between the user and the skill in the selection dropdown. This function can only be called when the multi-lingual chat feature is configured.
Bots.setPrimaryChatLanguage('fr')
If the passed language tag does not match any of the passed supported languages, Detect Language
is set and skill determines which language is being used for conversation.
setTTSService(service)
Injects a TTS service that is used by the SDK for the utterance of incoming skill messages. The passed service object needs to implement the SpeechSynthesisService
interface to have the functions that the SDK requires to utilize it. If an invalid or empty service object is passed, the synthesis service is disabled. See Speech Synthesis Service Injection for more details.
const myOwnTTSService = {
/**
* Adds a phrase to the utterance queue to be spoken
*
* @param {string} phrase
*/
speak: function(phrase) {},
/**
* Cancels any ongoing speech synthesis utterance
*/
cancel: function() {},
/**
* Returns a Promise that resolves into a list of SpeechSynthesisServiceVoice objects representing
* the available voices
*
* @return {*} {Promise<SpeechSynthesisServiceVoice[]>}
*/
getVoices: function() {},
/**
* Sets the voice to be used for speaking the utterances. It accepts an array of candidate voices
* sorted in their preference order, and sets one of them according to its matching criteria.
* It returns a Promise that gets resolved when the voice is set.
*
* @param {SpeechSynthesisServiceVoice[]} voice
* @return {*} {Promise<void>}
*/
setVoice: function(voices) {},
/**
* Returns the voice that is currently used for speaking utterances
*
* @return {*} {SpeechSynthesisServiceVoice}
*/
getVoice: function() {}
};
Bots.setTTSService(myOwnTTSService);
You can also pass the WebSDK.TTS
values to the setTTSService
method to set them as the TTS service used by the SDK.
Bots.setTTSService(WebSDK.TTS.oracle); // Sets the OCI TTS service
Bots.setTTSService(WebSDK.TTS.platform); // Sets the platform based TTS service
getTTSVoices()
Returns a Promise
that resolves into a list of SpeechSynthesisServiceVoice
objects representing the available voices for speech synthesis. When using SDK's native speech synthesis service, this list is populated with the voices provided by the platform/OS. When using a third-party synthesis service, the list is populated by the voices that are provided by that service.
await Bots.getTTSVoices();
console.log(voices);
/**
* [
* {
* default: false,
* lang: "en-US",
* localService: true,
* name: "Alex",
* voiceURI: "urn:moz-tts:osx:com.apple.speech.synthesis.voice.Alex"
* },
* {
* default: false,
* lang: "it-IT",
* localService: true,
* name: "Alice",
* voiceURI: "urn:moz-tts:osx:com.apple.speech.synthesis.voice.alice"
* },
* {
* default: false,
* lang: "sv-SE",
* localService: true,
* name: "Alva",
* voiceURI: "urn:moz-tts:osx:com.apple.speech.synthesis.voice.alva"
* }...
* ]
* /
setTTSVoice(voices)
Sets the voice that's used for speaking the skill's utterances. It accepts an array of candidate voices that's sorted by preference. From this array, it either sets the first voice that's provided by the synthesis service as the skill's voice, or it sets a voice that closely matches one of the voices available in the synthesis service. It returns a Promise
that gets resolved when the voice is set.
Note: This function is similar to the deprecated
setSkillVoices(voices)
method. UsesetTTSVoice
instead.
await Bots.setTTSVoice([{
lang: 'es-mx',
name: 'Juan'
}, {
lang: 'es-es',
name: 'Monica'
}, {
lang: 'es-ar',
name: 'Diego'
}, {
lang: 'es-es'
}]);
Bots.speak('Hello');
getTTSVoice()
Returns the voice that is currently used by the synthesis service for speaking utterances. It returns a SpeechSynthesisServiceVoice
object representing the selected voice.
const currentVoice = Bots.getTTSVoice();
console.log(currentVoice);
/**
* {
* default: false,
* lang: "en-US",
* localService: true,
* name: "Alex",
* voiceURI: "urn:moz-tts:osx:com.apple.speech.synthesis.voice.Alex"
* }
* /
speakTTS(phrase)
Calls the speech synthesis service to speak the passed phrase. The passed phrase can either be a plain string, or a skill message object received from the server.
Bots.speakTTS('Hello World');
const skillMessage = {
messagePayload: {
type: 'text',
text: 'What is your order number?'
}
};
Bots.speakTTS(skillMessage); // Will utter 'What is your order number?'
cancelTTS()
Cancels any ongoing utterance from the speech synthesis service.
Bots.cancelTTS();
Delegation & rendering:
setDelegate(delegate)
The setDelegate
method can be used to change or remove delegate callbacks after a conversation has been initialized. If no value is passed, the existing delegates are removed.
await Bots.connect();
Bots.setDelegate({
beforeDisplay(message) {
return message;
},
beforeSend(message) {
return message;
},
beforePostbackSend(postback) {
return postback;
},
beforeEndConversation(message) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message);
}, 2000);
});
},
render(message) {
if (message.messagePayload.type === 'card') {
// Perform custom rendering for card using msgId
return true;
}
return false;
}
});
Layout & appearance:
setWebViewConfig(webViewConfig)
Sets and updates the Webview configuration, customizing the Webview component. Check out the In-Widget Webview section under customization for more details.
Bots.setWebViewConfig({
accessibilityTitle: 'Webview container for Wikipedia',
sandbox: ['allow-scripts', 'allow-downloads'],
size: 'tall',
title: 'Wikipedia'
});
setChatBubbleIconHeight(height)
Sets the height of the loading chat bubble icon. The height must be provided as a string value in one of the standard length units.
Bots.setChatBubbleIconHeight('18px');
setChatBubbleIconWidth(width)
Sets the width of the loading chat bubble icon. The width must be provided as a string value in one of the standard length units.
Bots.setChatBubbleIconWidth('24px');
setChatBubbleIconSize(width, height)
Sets the size of the loading chat bubble icon. The width and height must be provided as string values in one of the standard length units.
Bots.setChatBubbleIconSize('24px', '18px');
setFontFamily(fontFamily)
Set font family used for all text content in the chat widget. The fontFamily
argument must be a string and follow the standard pattern.
Bots.setFontFamily('"Gill Sans", sans-serif');
setFontSize(fontSize)
Sets the font size for the text in the chat widget. The syntax of fontSize
must follow the standard permissible values.
Bots.setFontSize('16px');
setHeight(height)
Sets the height of the chat widget. The value passed must be in one of the length units.
Bots.setHeight('786px')
setWidth(width)
Sets the width of the chat widget. The value passed must be in one of the length units.
Bots.setWidth('320px')
setSize(width, height)
Sets the size of the chat widget. The values passed must be in one of the length units.
Bots.setSize('320px' ,'786px',)
setMessagePadding(padding)
Sets the padding around the message in the chat widget. The syntax of padding
must follow standard permissible values.
// Apply padding to all four sides
Bots.setMessagePadding('15px');
// vertical | horizontal
Bots.setMessagePadding('5% 10%');
// top | horizontal | bottom
Bots.setMessagePadding('15em 20em 20em');
// top | right | bottom | left
Bots.setMessagePadding('15px 20px 20px 15px');
setTextColor(color)
Sets the primary text color of messages in the chat widget. It does not modify the colors in actions. The value passed must be in standard color format.
Bots.setTextColor('#33ee00')
setTextColorLight(color)
Sets the color of the secondary messages in the chat widget, like descriptions. The value passed must be in standard color format.
Bots.setTextColorLight('rgb(13, 155, 200)')
Events
Register with Bots.on(event, handler)
, remove with Bots.off()
in one of following ways:
Bots.off(<event name>, handler)
to remove one specific handler.Bots.off(<event name>)
to remove all handlers for an event.Bots.off()
to unbind all handlers.
We recommend adding event handlers before calling the connect()
method so that they can be registered and triggered appropriately.
ready
This event is triggered when connect completes successfully. Be sure to bind before calling connect.
Bots.on('ready', function(){
console.log('the init has completed!');
});
Listeners to the ready
event must be added before calling the connect()
method. Otherwise, the listeners will not be registered in time to be triggered.
destroy
This event is triggered when the widget is destroyed.
Bots.on('destroy', function(){
console.log('the widget is destroyed!');
});
Bots.destroy();
message:received
This event is triggered when the user receives a message. If beforeDisplay delegate is set, the callback would receive the message to be displayed after executing the delegate.
Bots.on('message:received', function(message) {
console.log('the user received a message', message);
});
message:sent
This event is triggered when the user sends a message. If beforeSend delegate is set, the callback would receive the message sent to the server after executing the delegate.
Bots.on('message:sent', function(message) {
console.log('the user sent a message', message);
});
message
This event is triggered when a message is added to the conversation.
Bots.on('message', function(message) {
console.log('a message was added to the conversation', message);
});
networkstatuschange
This event is triggered whenever the network status of the connection to the server changes. The callback receives a status number parameter, which corresponds to WebSocket network status constants.
Bots.on('networkstatuschange', function(status) {
switch (status) {
case 0:
status = 'Connecting';
break;
case 1:
status = 'Open';
break;
case 2:
status = 'Closing';
break;
case 3:
status = 'Closed';
break;
}
console.log(status);
});
typing
This event is triggered whenever the user starts or stops typing in the user input field. The listener receives a boolean parameter, which is set true
when the user starts typing and set false
when typingStatusInterval
has elapsed after the user stops typing.
Bots.on('typing', function(isTyping) {
console.log('User currently typing: ', isTyping);
});
unreadCount
This event is triggered when the number of unread messages changes.
Bots.on('unreadCount', function(unreadCount) {
console.log('the number of unread messages was updated', unreadCount);
});
widget:opened
This event is triggered when the widget is opened.
Bots.on('widget:opened', function() {
console.log('Widget is opened!');
});
widget:closed
This event is triggered when the widget is closed.
Bots.on('widget:closed', function() {
console.log('Widget is closed!');
});
widget:show
This event is triggered when the widget is toggled to be shown with showWidget()
method.
Bots.on(WebSDK.EVENT.WIDGET_SHOW , function() {
console.log('Widget is visible.');
});
widget:hide
This event is triggered when the widget is toggled to be hidden with hideWidget()
method.
Bots.on(WebSDK.EVENT.WIDGET_HIDE, function() {
console.log('Widget is hidden.');
});
click:audiotoggle
This event is triggered when the audio utterance of response is toggled. The subscribers receive the boolean status - true
if the audio response is turned on, false
if it is turned off.
Bots.on('click:audiotoggle', function(status) {
if (status === true) {
console.log('Audio response is turned on.');
} else {
console.log('Audio response is turned off.');
}
})
click:erase
This event is triggered when the erase conversation history button is clicked. No parameters are passed to the subscribers.
Bots.on('click:erase', function() {
console.log('Conversation history is erased.');
})
click:voicetoggle
This event is triggered when the voice activation button is toggled. The subscribers receive the boolean status - true
if the voice is activated, false
if it is deactivated.
Bots.on('click:voicetoggle', function(status) {
if (status === true) {
console.log('Voice recording is started.');
} else {
console.log('Voice recording is stopped.');
}
})
chatlanguagechange
This event is triggered when the chat language in language selection dropdown is selected or changed. This dropdown is exposed on enabling the Multi-Lingual Chat feature. Its subscribers receive the selected language's language tag. If auto-detect is selected, null
is passed as the argument.
Bots.on('chatlanguagechange', function(language) {
console.log('The selected chat language is', language);
});
chatend
This event is triggered when the conversation is ended.
Bots.on('chatend', function() {
console.log('The conversation is ended.');
});
TTSStart
This event is triggered when the TTS is started.
Bots.on(WebSDK.EVENT.TTSStart, function() {
console.log('The TTS is started.');
});
TTSStop
This event is triggered when the TTS is stopped or ended.
Bots.on(WebSDK.EVENT.TTSStop, function() {
console.log('The TTS is ended.');
});
Examples in the Usage section show typical subscriptions.
Message Model
The SDK uses a consistent, typed message model for all traffic. Understanding the envelope and payload types is important for headless integrations, delegates, custom rendering, and testing.
Overview and Envelope
All conversation items are "messages" with a standard envelope:
{
"messagePayload": { /* see types below */ },
"userId": "guest"
}
messagePayload.type
determines the concrete payload shape.- User messages are initiated by the client; response messages originate from the skill/agent.
Base Types
These are building blocks that are reused across payloads:
Action
: Variants includecall
,client
,location
,popup
,postback
,share
,submitForm
,url
Attachment
:audio
,file
,image
,video
Card
:title
:description
,imageUrl
,actions
Location
:latitude
,longitude
,optional title/url
Voice
:text
,longText
,soundUr
Field
: read‑only (link
,text
,media
,action
) and editable (textInput
,numberInput
,datePicker
,timePicker
,singleSelect
,multiSelect
,toggle
)SelectFieldOption
:label
,value
TableHeading
TableRow
Form
FormRow
FormColumn
PaginationInfo
EventContextProperties
User Messages
User message payloads (types extend MessagePayload
):
Text
{ "type": "text", "text": "Order Pizza" }
Attachment
{ "type": "attachment", "attachment": { "type": "image", "URL": "https://..." } }
Location
{ "type": "location", "location": { "latitude": 45.9, "longitude": 132.6 } }
Postback
{ "type": "postback", "text": "Small", "postback": { "variables": { "pizza": "Small" }, "system.botId": "....", "system.state": "orderPizza" } }
Inbound Event
{ "type": "inboundEvent", "eventType": "com.pizzastore.pizza.orderserved", "eventVersion": "1.0", "eventData": { "size": "Medium", "type": "Cheese" }, "contextProperties": { "id": "6ce23f...", "source": "pizza/service" } }
Form Submission
{ "type": "formSubmission", "submittedFields": { "Subject": "Expense", "Amount": 6 }, "partialSubmitField": "Attendees", "postback": { "system.state": "editFormMapVar" } }
Response Messages
Response payloads from the skill/agent include:
Text
{ "type": "text", "text": "What do you want to do?" }
Attachment
{ "type": "attachment", "attachment": { "type": "file", "url": "https://..." } }
Card
{ "type": "card", "layout": "horizontal", "cards": [{ "title": "Hawaiian Pizza", "actions": [/*...*/] }] }
Command
{ "type": "command", "command": "someCommand", "properties": { "k": "v" } }
Error
{ "type": "error", "errorMessage": "Details...", "error": "..." }
Execute Application Context Command
{ "type": "executeApplicationActionCommand", "actionType": "navigate", "command": "executeApplicationAction", "context": "appName", "properties": { "route": "/home" } }
Feedback (stars)
{ "type": "text", "text": "How would you like to rate us?", "channelExtensions": { "displayType": "stars" }, "actions": [/* star postbacks */] }
Location
{ "type": "location", "location": { "latitude": 37.53, "longitude": -122.26 } }
Outbound Event
{ "type": "outboundEvent", "eventType": "com.pizzastore.pizza.ordercreated", "eventVersion": "1.0", "eventData": { "size": "Medium" } }
Raw
{ "type": "raw", "payload": { /* channel specific */ } }
Session Closed
{ "type": "sessionClosed" }
Text Stream
{ "type": "texStream", "streamId": "123", "streamState": "running", "text": "partial chunk", "aggregateText": "accumulated text so far" }
Form / Table / Table‑Form / Edit‑Form All read‑only/interactive forms and tabular responses as specified in the original sections, with the same shapes (
forms
,rows
,headings
,formRows
,actions
,paginationInfo
, etc.). TheEdit‑Form
supportsreplaceMessage
viachannelExtensions
.
See Conversation Message Model Reference for complete message model.
Advanced Features
Autocomplete
- Enable with
enableAutocomplete: true
(optional cache:enableAutocompleteClientCache
). - Adds suggestions while typing; available via
getSuggestions(query)
in headless mode. - WebSocket only.
Autocomplete provides suggestions to end users to better form the utterance and select the specific entity value. To enable autocomplete, you must add autocomplete suggestions to the skill's intents. Then, whenever the user types a character in the input field, the intents' autocomplete suggestions display in a popup to suggest the best format, helping to minimize user errors. An intent's autocomplete suggestions should not be a full word dictionary. Their purpose is to minimize the scope and allow better guidance to the end user.
The feature can also be used in headless mode using getSuggestions(query) API.
Auto‑Submit in Edit‑Form
- Set
autoSubmit: true
on an editable field to send partial form payload when the entered value is valid. - Fields that have not yet been set -- regardless of whether they are required -- or fields that violate a client-side validation, are not included in the
submittedField
map. - Client‑side invalid fields prevent submission.
Replace Previous Edit‑Form
- To replace the previous Edit‑Form, set
channelExtensions.replaceMessage = true
in the next Edit‑Form payload.
Delegation
- Configure with
delegate
- Add interception and rendering hooks
The delegation feature enables you set a delegate to receive callbacks before certain events in the conversation. To set a delegate, pass it in the delegate
property or use the setDelegate
method. The delegate object may optionally contain beforeDisplay
, beforeSend
, beforePostbackSend
, beforeEndConversation
and render
delegate functions.
const delegate = {
beforeDisplay: function(message) {
return message;
},
beforeSend: function(message) {
return message;
},
beforePostbackSend: function(postback) {
return postback;
},
beforeEndConversation: function(message) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message);
}, 2000);
});
},
render: function(message) {
if (message.messagePayload.type === 'card') {
// Create a placeholder with id = message.msgId and render custom UI
return true;
}
return false;
}
}
Bots.setDelegate(delegate);
beforeDisplay
The beforeDisplay
delegate allows a skill message to be modified before it is displayed in the conversation. The message returned by the delegate displays instead of the original message. The returned message is not displayed if the delegate returns a falsy value like null
, undefined
, or false
. If the delegate errors out, then the original message will be displayed instead.
beforeSend
The beforeSend
delegate allows a user message to be modified before it is sent. The message returned by the delegate is sent to the skill instead of the original message. The message returned by the delegate is not sent if the delegate returns a falsy value like null
, undefined
, or false
. If the delegate errors out, the original message will be sent instead.
beforePostbackSend
The beforePostbackSend
delegate is similar to beforeSend
but is instead applied to postback messages from the user. The postback returned by the delegate is sent to the skill. The postback returned by the delegate is not sent if the delegate returns a falsy value like null
, undefined
, or false
. If the delegate errors out, the original postback will be sent instead.
beforeEndConversation
The beforeEndConversation
delegate allows an interception the end conversation flow if some pre-exit activity must be performed. The function receives the exit message as its input parameter. It must return a Promise
. If this Promise
resolves with the exit message, then the CloseSession
exit message is sent to the chat server. Otherwise, the exit message is prevented from being sent.
render
The render
delegate allows to override the default message rendering. If the render
delegate function returns true
for a particular message type, then the WebSDK creates a placeholder slot instead of default message rendering. To identify the placeholder, the WebSDK adds the msgId
of the message as the id
of the element. In the render
delegate function, you can use this identifier to get the reference for the placeholder and render your custom message template. See Custom Message Rendering for more details.
Embedded Mode
embedded: true
,targetElement: '<div id>'
- Widget fills container; ensure the element has explicit height/width.
The chat widget appears as a fixed position element on the bottom right of the page, which does not respond to gestures on the page. But it can also be embedded into the host and become part of the page. To activate the embedded mode, you need to pass embedded: true
, and provide a target container with targetElement: <targetDivId>
. This accepts a DOM element that will be used as the container where the widget will be rendered.
The embedded widget occupies the full width and height of the container. A height and width must be specified for the target element. Otherwise, the widget will collapse.
Headless SDK
enableHeadless: true
- Full API without widget UI. Render your own UI, wire events and methods.
Similar to headless browsers, the SDK can also be used without a UI. The SDK maintains the connection to the server, and provides APIs to send messages, receive messages, and get updates of the network status. Developers can use the APIs to interact with the SDK, and update UI appropriately.
The communication can be implemented as follows:
- Sending messages - Call
Bots.sendMessage(message)
to pass any payload to server. - Receiving messages - Response can be listened for using
Bots.on('message:received', <messageReceivedCallbackFunction>)
. - Get connection status update - Updates to status of the connection to server can be listened for using
Bots.on('networkstatuschange', <networkStatusCallbackFunction>)
. The callback has a parameterstatus
, which is updated with values from 0 to 3. These values map to WebSocket states:- 0 -
WebSocket.CONNECTING
- Connecting - 1 -
WebSocket.OPEN
- Open - 2 -
WebSocket.CLOSING
- Closing - 3 -
WebSocket.CLOSED
- Closed
- 0 -
- Check if connection is open - Call
Bots.isConnected()
to check if the connection is open or not. - Get suggestions list - If autocomplete is enabled, call
Bots.getSuggestions(query)
where query is the string to get the suggestions list.
In‑Widget Webview
- Set
linkHandler: { target: 'oda-chat-webview' }
to open all links in Webview. - Or use
beforeDisplay
to convert specificurl
actions towebview
. - Configure
webViewConfig
(accessibilityTitle
,closeButtonType
,errorInfoBar
,referrerPolicy
,sandbox
,size
,title
). - Configure dynamically with
setWebViewConfig(webViewConfig)
- Limitations:
X-Frame-Options
sites cannot be embedded; auth pages typically disallow iframes.
The Web SDK contains an in-widget Webview component that can be used to view the message links within the chat widget. This feature allows users to interact with links in the conversation without taking them away from the widget to a new tab or window. The in-widget Webview can be applied globally to open all links in the messages inside it, or can be selectively configured for specific links.
To open all links in the conversation in the Webview, you just need to pass linkHandler: { target: 'oda-chat-webview' }
in the settings. This sets the target of all links to oda-chat-webview
, which is the name of the Webview iframe.
In more general scenarios, you'll probably need to open only certain links in the Webview, while ensuring other links open normally in other tabs/windows. The beforeDisplay
delegate can be used to make that work. To open a specific message URL action in the Webview, replace action.type
field's value from url
to webview
. Once the action type is changed to webview
in beforeDisplay
, clicking that action button will open the link in the Webview.
Opening specific links embedded in the text in Webview is a bit more challenging. The embedded link needs to be converted into an anchor element (<a href="https://www.oracle.com"\>), and the target="oda-chat-webview"
attribute should be added in that anchor element.
The webViewConfig
setting allows customizing the Webview component. It accepts an object that can have the following optional fields:
{
accessibilityTitle: string, // Name of Webview frame element for Web Accessibility
closeButtonIcon: string, // Image URL/SVG string that is used to display the close button icon
closeButtonLabel: string, // Text label/tooltip title for the close button
closeButtonType: 'icon' | 'label' | 'iconWithLabel', // Sets how the close button is displayed in the Webview
errorInfoBar: boolean, // Sets to display or hide fallback view with original URL
errorInfoDismissLabel: string, // Label for error-view bar dismiss button
errorInfoText: string, // Informational text displayed in an error-view bar inside Webview as a fallback for the user in case the URL fails to load in the Webview
referrerPolicy: ReferrerPolicy // Indicates which referrer to send when fetching the frame's resource
sandbox: string[], // Array of extra restrictions to the content in the Webview frame
size: 'tall' | 'full', // Height of the Webview compared to chat widget. When set 'tall', it is set as 80%, 100% for 'full'.
title: string // Webview title shown on the header of the Webview container
}
The referrerPolicy
policy value passed should be a valid directive. The default policy applied is 'no-referrer-when-downgrade'
.
The sandbox
field accepts an array of valid restriction strings that allows for the exclusion of certain actions inside the frame. The restrictions that can be passed to the field can be found under the sandbox attribute manual at MDN.
The configuration can also be updated dynamically by passing a webViewConfig
object in the method setWebViewConfig()
. Every property in the object is optional.
The Webview optionally presents a fallback view that contains the original URL link as a fallback in case the page fails to load inside the Webview. Clicking the link in this view opens the page in a new tab. The informational text can be customized with the webViewErrorInfoText
i18n
translation string and must contain a placeholder text for the link label. For example:
settings = {
URI: 'instance',
//...,
i18n: {
en: {
webViewErrorInfoText: 'This link can\'t be opened here. You can open it in a new page by clicking {0}here{/0}.'
}
}
}
This error view can be disabled by passing errorInfoBar: false
in the webViewConfig
setting.
Limitations
- Pages that provide response header
X-frame-options: deny
orX-frame-options: sameorigin
may not open in the Webview due to server-side restrictions preventing the page to be opened inside iframes. The Webview presents a dismissible popup with a link back to the user in the Webview. Users can open it in a new window or tab by clicking it. - Due to the above restrictions, authorization pages like IDCS, Google Login, FB Login, etc. can not be opened inside the WebViews, as authorization pages always return
X-frame-options: deny
to prevent clickjacking. - Only links inside the conversation messages can be opened inside the Webview. Any external links must not be targeted to be opened in the Webview, clicking on such links won't open the Webview correctly.
Long Polling
enableLongPolling: true
for HTTP fallback where WebSockets are unavailable.
The SDK uses WebSockets to connect to the server and converse with skills. If for some reason the WebSocket is disabled over the network, traditional HTTP calls can be used to chat with the skill. This feature is known as long polling, as the SDK has to continuously call or poll the server to fetch the latest messages from the skill.
Long polling provides fallback support for conversations on browsers that don't have WebSockets enabled or blocked.
Multi‑Lingual Chat
- Configure via
multiLangChat.supportedLangs
and optionalprimary
. - Optionally omit
supportedLangs
and pass onlyprimary
to set chat language without dropdown. Detect Language
shown when primary isnull
or'und'
.setPrimaryChatLanguage(lang)
can update dynamically.- Voice and TTS availability depends on selected language (not available on
Detect Language
).
The Web SDK's native language support enables the chat widget to detect a user's language or allow users to select the conversation language.
Enable the Language Menu
You can enable a menu that allows users to select a preferred language from a dropdown menu by defining the multiLangChat
property with an object containing the supportedLangs
array, which is comprised of language tags (lang
) and optional display labels (label
) to override the default translation strings. Outside of this array, you can optionally set the default language with the primary key (primary: 'en'
in the following snippet). If the primary key matches one of the supported languages, then that language is selected. When no match can be found, Detect Language is activated.
multiLangChat: {
supportedLangs: [{
lang: 'en'
}, {
lang: 'es',
label: 'Español'
}, {
lang: 'fr',
label: 'Français'
}, {
lang: 'hi',
label: 'हिंदी'
}],
primary: 'en'
}
The chat widget displays the passed-in supported languages in a dropdown menu that's located in the header. In addition to the available languages, the menu also includes a Detect Language option. When a user selects a language from this menu, the current conversation is reset, and a new conversation is started with the selected language. The language selected by the user persists across sessions in the same browser, so the user's previous language is automatically selected when the user revisits the skill through the page containing the chat widget.
You can add an event listener for the chatlanguagechange
event, which is triggered when a chat language has been selected from the dropdown menu or has been changed.
Bots.on('chatlanguagechange', function(language) { console.log('The selected chat language is', language); });
Disable Language Menu
You can also configure and update the chat language without also having to configure the language selection dropdown menu by passing multiLangChat.primary
in the initial configuration without also passing a multiLangChat.supportedLangs
array. The value passed in the primary variable is set as the chat language for the conversation.
Language Detection
In addition to the passed in languages, the chat widget displays a Detect Language option in the dropdown. Selecting this option tells the skill to automatically detect the conversation language from the user's message and, when possible, to respond in the same language.
If you omit the primary key or if the primary key is invalid, the widget automatically detects the language in the user profile and activates the Detect Language option in the menu.
You can dynamically update the selected language by calling the setPrimaryChatLanguage(lang)
API. If the passed lang
matches one of the supported languages, then that language is selected. When no match can be found, Detect Language is activated. You can also activate the Detected Language option by calling setPrimaryChatLanguage('und')
API, where 'und'
indicates undetermined or by passing either multiLangChat: {primary: null}
or multiLangChat: {primary: 'und'}
.
You can update the chat language dynamically using the setPrimaryChatLanguage(lang)
API even when the dropdown menu has not configured. For example:
Bots.setPrimaryChatLanguage('fr')
You can dynamically update the language irrespective of whether the chat language is initially configured or not.
Response narration and voice recognition, when configured, are available when users select a supported language. They are not available when the Detect Language option is set. Selecting a language that is not supported by voice recognition disables the recognition functionality until a supported language has been selected.
Multi-Lingual Chat Quick Reference
To do this... | ...Do this |
---|---|
Display the language selection dropdown to end users. | Pass multiLangChat.supportedLangs . |
Set the chat language without displaying the select language selection dropdown menu to end users. | Pass multiLangChat.primary . |
Set a default language. | Pass multiLangChat.primary with multiLangChat.supportedLangs . The primary value must be one of the supported languages included the array. |
Enable language detection. | Pass primary: null or primary: 'und' with multiLangChat . |
Dynamically update the chat language. | Call the setPrimaryChatLanguage(lang) API. |
Text‑to‑Speech
enableBotAudioResponse: true
- Default
ttsService: WebSDK.TTS.oracle
(OCI). AlternativeWebSDK.TTS.platform
. ttsVoice
: array of candidate voices (lang
,name
, optionalpitch
,rate
,volume
).
You can enrich the conversational experience by enabling text-to-speech (TTS) to speak the responses as they reach the SDK. The SDK provides two types of TTS service out of the box: WebSDK.TTS.platform
and WebSDK.TTS.oracle
. By default, the SDK uses the Oracle Cloud Infrastructure (OCI) Speech service, to have the responses spoken in a more naturalistic tone. This service has several voices that you can select from to provide a more branded experience. However, you can instead use the platform-dependent TTS service, WebSDK.TTS.platform
that's based on the Web Speech API. It uses the speech synthesis APIs on the user's device to speak the responses.
You use the ttsVoice
array to configure the voice for the TTS. Each item in the array must be an object that has at least a lang
field or a name
field. The SDK looks up the availability of each voice in the order that they are passed in the setting. The first complete match is set as the voice. If no exact match is found, then the SDK uses the first match based on the lang
value alone. If there's still no match, then the SDK uses the default voice.
const settings = {
...,
enableBotAudioResponse: true,
ttsVoice: [{
lang: 'en-US',
name: 'Samantha'
}, {
lang: 'en-US',
name: 'Alex'
}, {
lang: 'en-UK'
}]
}
To tailor the way the utterances are spoken, the ttsVoice
array allows passing optional pitch
, rate
, and volume
properties in each item. These properties correspond to the same fields in SpeechSynthesisUtterance interface.
- The
pitch
property can have a value between 0 and 2. - The
rate
property can have a value between 0.1 and 10. - The
volume
property can have a value between 0 and 1.
const settings = {
// ....,
ttsVoice: [{
lang: 'en-us',
name: 'Alex',
pitch: 1.5,
rate: 2,
volume: 0.8
}, {
lang: 'en-us',
name: 'Victoria',
pitch: 1.2,
rate: 1.7,
}, {
lang: 'en',
name: 'Fiona',
pitch: 2,
}, {
lang: 'en'
}]
}
Speech Synthesis Service Injection
Implement the SpeechSynthesisService
interface and inject via settings or setTTSService(service)
:
const myTTS = {
speak(phrase) {},
cancel() {},
getVoices() { return Promise.resolve([]) },
setVoice(voices) { return Promise.resolve() },
getVoice() { return null },
on(event, listener) {},
off(event, listener) {}
};
Bots.setTTSService(myTTS);
Voice Recognition
enableSpeech: true
enableSpeechAutoSend
controls auto‑send vs populate input.startVoiceRecording(onSpeechRecognition, onSpeechNetworkChange, options)
/stopVoiceRecording()
setSpeechLocale(locale)
ensures a supported recognition locale.
OCI Speech Integration
interface OCIAuthCredentials {
compartmentId: string;
region: string;
token: string;
}
interface OCISpeechConfig {
getOCIAuthCredentials(): Promise<OCIAuthCredentials>;
useOCISpeech?: 'auto' | 'always' | 'never';
}
Example:
async function getOCIAuthCredentials() {
const res = await fetch('<OCIAuthCredentialsEndpoint>');
if (!res.ok) throw new Error(String(res.status));
return res.json();
}
const ociSpeechConfig = {
getOCIAuthCredentials,
useOCISpeech: 'auto'
};
Timestamps
- Configure message timestamps with
timestampMode
,timestampFormat
,timestampHeaderMode
,timestampHeaderFormat
. timestampMode: 'relative'
shows contextual time ("A few seconds ago") with periodic updates;'absolute'
prints exact times.
You can enable absolute or relative timestamps for chat messages. Absolute timestamps display the exact time for each message. Relative timestamps display only on the latest message and express the time in terms of the moments, minutes, hours, days, months, or years ago relative to the previous message.
The precision afforded by absolute timestamps makes them ideal for archival tasks, but within the limited context of a chat session, this precision detracts from the user experience because users must compare timestamps to find out the passage of time between messages. Relative timestamps allow users to track the conversation easily through terms like Just Now and A few moments ago that can be immediately understood. Relative timestamps improve the user experience in another way while also simplifying your development tasks: because relative timestamps mark the messages in terms of seconds, minutes, hours, days, months, or years ago, you don't need to convert them for time zones.
Cross‑Tab Conversation Synchronization
enableTabsSync: true
synchronize messages and state across tabs (sameURI
,channelId
,userId
).
You may need to open the website in multiple tabs for various reasons. With enableTabsSync: true
, you can synchronize and continue your conversation from any tab, as long as the connections parameters (i.e., URI
, channelId
, and userId
) are the same across all tabs. This feature ensures that you can see messages from the skill on any tab and respond from the same tab or any other one.
Additionally, if you clear the conversation history in one tab, it is deleted from other tabs as well. If you update the chat language on one tab, it also gets synchronized on other tabs.
Limitations
- A new tab synchronizes with existing tab(s) for the new messages between you and the skill on opening. If you have not configured the SDK to display messages from your conversation history, the initial chat widget on the new tab will appear empty when opened.
- If you have configured the SDK to display conversation history, the messages from the current chat on existing tabs will appear as part of conversation history on a new tab. If
disablePastActions
is set'all'
or'postback'
, you may not be able to interact with the actions of those messages in the new tab. - The Safari browser currently does not support this feature.
End Conversation Session
enableEndConversation: true
(default). Shows header button to end session.- Also available programmatically via
Bots.endChat()
.
This feature adds a close button to the chat header that allows user to end the current conversation session. Clicking the close button opens a confirmation prompt. On confirming the action, the SDK sends an event message to the skill to mark the current conversation session as ended. The instance then disconnects from the skill, collapses the chat widget, and erases the conversation history of the current user. It also raises a 'chatend'
event that you can register for. Opening the chat widget afterward starts a new conversation session.
Default Client Responses
enableDefaultClientResponse: true
- Shows greeting/wait/sorry messages based on configured timeouts when skills are slow.
Use this flag to provide default client-side responses along with a typing indicator when the skill response has been delayed, or when there's no skill response at all. If the user sends out the first message/query, but the skill does not respond within the number of seconds set by defaultGreetingTimeout
, the skill can display a greeting message that's configured using the defaultGreetingMessage
translation string. Next, the client checks again for the skill response. The client displays the skill response if it has been received, but if it hasn't, then the client displays a wait message (configured with the defaultWaitMessage
translation string) at intervals set by defaultWaitMessageInterval
. When the wait for the skill response exceeds the threshold set by typingIndicatorTimeout
, the client displays a sorry response to the user and stops the typing indicator. You can configure the sorry response using the defaultSorryMessage
translation string.
Custom Message Rendering
- Use delegate
render(message) => boolean
to replace SDK rendering for selected messages. - You are responsible for actions, focus, and a11y in custom rendering.
This feature lets you override the default message rendering with your custom message template. To use this feature, you need to implement the render
delegate function which takes the message model as the input and returns a boolean flag as the output. It must return true
to replace the default rendering with your custom rendering for a particular message type. If false
is returned, the default message is rendered instead.
Note: For custom rendering, all of the action click handling, and the disabling or enabling of action must be handled explicitly.
You can use any external framework component for your message rendering. Refer to the integration samples to check how you can use this feature with such frameworks like React, Angular and Oracle JavaScript Extension Toolkit (JET).
Live Agent Typing Indicator
enableSendTypingStatus: true
sendsRESPONDING
/LISTENING
to OSvC (throttled bytypingStatusInterval
).enableAgentSneakPreview: true
sends typed text to agent; requires OSvC Sneak Preview.
This feature allows agents to ascertain if users are still engaged in the conversation by sending the user status to the live agent. When this flag is enabled, the SDK sends a RESPONDING
status message with the text that is currently being typed by the user to Oracle Service Cloud. This, in turn, displays a typing indicator on the agent console. When the user has finished typing, the SDK sends a LISTENING
status message to Oracle Service Cloud to hide the typing indicator on the agent console.
The typingStatusInterval
configuration, which has a minimum value of three seconds, throttles the typing status update.
To send the agent both the text as it's being typed by the user and the typing status, enableAgentSneakPreview
(which by default is false
) must be set to true
and Sneak Preview must be configured in Oracle Service Cloud. For more details refer to Sneak Preview documentation
Note: You do not have to configure live typing status on the user side. The user can see the live typing status of the agent by default. When the agent is typing, the SDK receives a
RESPONDING
status message which results in the display of a typing indicator in the user's view. Similarly, when the agent is idle, the SDK receives aLISTENING
status message which hides the typing indicator.
Customization
Customizability is one of the biggest strengths of the Web SDK. In this section, we'll cover some of the various customization that can be performed on the SDK.
Add Avatar Icons to Messages
The messages in the chat are not accompanied by any avatars by default. You can, however, display icons with user and skill messages with the following parameters:
avatarBot
- The URL of the image source, or the source string of the SVG image that should be displayed alongside the skill messages.avatarUser
- The URL of the image source, or the source string of the SVG image that should be displayed alongside the user messages. Additionally, if the skill has a live agent integration, the SDK can be configured to show a different icon for agent messages.avatarAgent
- The URL of the image source or the source string of the SVG image that should be displayed alongside the agent messages. If this value is not provided, butavatarBot
is set, theavatarBot
icon is used instead.new WebSDK({ URI: '<URI>', //..., icons: { avatarBot: '../assets/images/avatar-bot.png', avatarUser: '../assets/images/avatar-user.jpg', avatarAgent: '<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M12 6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2m0 9c2.7 0 5.8 1.29 6 2v1H6v-.99c.2-.72 3.3-2.01 6-2.01m0-11C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"/></svg>' } })
All of the above settings can only be passed in the initialization settings. They cannot be modified dynamically.
Card Cardinal Utterance for Card Messages
To identify the place of each card in a CRC cards message during a TTS utterance, the card
translation string is used with its cardinal number before the content of each card. If the cards message contains a single card though, this identifier is skipped.
The default string used for the card
translation key is 'Card {0}'
, where the placeholder {0}
is replaced with its cardinal position. You can overwrite this translation with your own custom string. If you do not include the placeholder {0}
in your custom string, it is added to the end of the string by default. You can localize the string by placing {0}
before or after the word.
If you don't want this card identifier to be uttered, you can do so by passing an empty string to the card
key.
i18n: {
en: {
card: '', // Will prevent uttering 'Card 1', 'Card 2' before the card message content
}
}
Change Header Buttons Icons
There are three buttons on the chat header that be displayed in the chat widget. These buttons can be configured and customized as follows:
- Clear Message button - Clicking this button clears the current and older messages in the conversation.
- Feature flag -
enableClearMessage: true
- Custom icon -
icons.clearHistory: '<image URL | SVG string>'
- Feature flag -
- Audio response toggle button - This button toggles the utterance of skill responses as they are received. As it is a toggle button, it has two states, utterance on, where responses are spoken, and utterance off, where responses are not spoken.
- Feature flag -
enableBotAudioResponse: true
- Custom icon - response on -
icons.ttsOn: '<image URL | SVG string>'
response off -icons.ttsOff: '<image URL | SVG string>'
- Feature flag -
- Close widget button - This button collapses the widget and shows the launch button. This button can not be disabled in normal chat widget, and it is not shown in the embedded chat widget.
- Feature flag - none (always enabled in the chat widget, not displayed in embedded mode)
- Custom icon -
icons.collapse : '<image URL | SVG string>'
These header button icons can be customized in two ways: through passing the source URL of the image, or through a raw SVG string. If a raw SVG string is passed, the fill color of the SVG can be customized by CSS classes, as well as by passing a color value in the colors.headerButtonFill
property in the initial settings. The color customization may not work for all SVGs, as they can be multi-colored or have their own stroke and fill colors.
Draggable Launch Button and widget
Feature flag: enableDraggableButton: true
(default: false
)
Feature flag: enableDraggableWidget: true
(default: false
)
In some scenarios, the chat widget or the launch button can block the background content and there may not be an easy way to view it. This can be especially apparent in mobile screens where there is less space available for the web page. However, by setting enableDraggableButton
or enableDraggableWidget
to true
, the chat widget or launch button can be made draggable, so the users can drag it around the screen as needed.
Feedback Message's Rating Gauge
The new feedback component enables users to rate their interactions with your skill. When users complete a conversation flow, the feedback message presents users with a star rating system, a row of stars (typically there are five stars, depending on the configuration of the System.Feedback
component in the dialog flow). The stars are highlighted as users hover over them, which indicates that they have selected a rating.
You can change the icon for the component's rating selecting buttons by passing the icon of your choice in using the rating
icon setting. For the best user experience, use a solid SVG string without a fill color, as it allows for a recognizable highlighting on hover.
new WebSDK({
URI: '<Server URI>',
//...,
icons: {
rating: '<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M15.994 3.006a5.7 5.7 0 00-3.795 1.707L12 4.916l-.199-.202a5.676 5.676 0 00-8.128 0c-2.231 2.275-2.231 5.953 0 8.228L12 21.428l8.326-8.486A5.873 5.873 0 0022 8.828a5.873 5.873 0 00-1.675-4.115A5.693 5.693 0 0016.262 3z"/></svg>' // A heart icon
}
})
The color of the icon in the two states, unselected and hovered/selected, can be configured with the ratingStar
and ratingStarFill
color fields in colors
setting respectively.
new WebSDK({
URI: '<Server URI>',
//...,
icons: {
rating: '<svg height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M15.994 3.006a5.7 5.7 0 00-3.795 1.707L12 4.916l-.199-.202a5.676 5.676 0 00-8.128 0c-2.231 2.275-2.231 5.953 0 8.228L12 21.428l8.326-8.486A5.873 5.873 0 0022 8.828a5.873 5.873 0 00-1.675-4.115A5.693 5.693 0 0016.262 3z"/></svg>' // A heart icon
},
colors: {
ratingStar: '#ffebee',
ratingStarFill: '#d32f2f'
}
})
Focus First Action of Response Message
Feature flag: focusOnNewMessage: 'action'
(default: 'input'
)
With each new message, the chat widget normally sets the focus back to the user input field. This works well when the dialog flow expects a lot of textual input from the user. However, if the dialog flow contains a number of messages with actions, then the user needs to either use their mouse or reverse tab navigation to select one of the actions. For such use cases and for power users who prefer keyboard-based navigation, a better choice can be focusing the first action button in the skill message as it is received. By setting focusOnNewMessage: 'action'
, when a new skill message containing actions is received, the focus is set to the first action button. If the message does not contain any actions, the focus is set to the user input field.
Format Message Timestamps
Feature flag: timestampMode: 'relative' | 'absolute'
(default: 'relative'
)
Functionality configuration: timestampFormat
Timestamps are shown with messages indicating the time they were sent or received. By default, they are displayed in the locale time in day of week, month date, year, time am/pm format (Thursday, August 13, 2020, 9:52:22 AM, for example). This timestamp can be configured by passing formatting options in the timestampFormat
setting.
The formatting can be performed in two ways - by passing a pattern string consisting of formatting tokens, or by passing an object containing Intl.DateTimeFormat options.
- Using pattern string The timestamp can be formatted by passing a pattern string which is composed of format tokens. The available format tokens are:
Component | Token | Output |
---|---|---|
Day of Month | D | 1 2 ... 30 31 |
Do | 1st 2nd ... 30th 31st | |
DD | 01 02 ... 30 31 | |
Day of Week | d | 0 1 ... 5 6 |
ddd | Sun Mon ... Fri Sat | |
dddd | Sunday Monday ... Friday Saturday | |
Month | M | 1 2 ... 11 12 |
MM | 01 02 ... 11 12 | |
MMM | Jan Feb ... Nov Dec | |
MMMM | January February ... November December | |
Year | YY | 70 71 ... 29 30 |
YYYY | 1970 1971 ... 2029 2030 | |
Hour | H | 0 1 ... 22 23 |
HH | 00 01 ... 22 23 | |
h | 1 2 ... 11 12 | |
hh | 01 02 ... 11 12 | |
Minute | m | 0 1 ... 58 59 |
mm | 00 01 ... 58 59 | |
Second | s | 0 1 ... 58 59 |
ss | 00 01 ... 58 59 | |
Fractional Second | S | 0 1 ... 8 9 |
SS | 0 1 ... 98 99 | |
SSS | 0 1 ... 998 999 | |
AM/PM | A | AM PM |
a | am pm | |
Timezone | Z | -07:00 -06:00 ... +06:00 +07:00 |
ZZ | -0700 -0600 ... +0600 +0700 |
So, passing timestampFormat: 'hh:mm:ss a'
would set timestamp as '09:30:14 pm'.
Note:
The tokens in the pattern string are case-sensitive: e.g., passingyyyy
instead of YYYY
would not display a year in the date.
- Using the
Intl.DateTimeFormat
options object
The timestamp can also be formatted using the options defined for Intl.DateTimeFormat object. The object can be passed with some or all of the following properties:
Property | Acceptable Values |
---|---|
dateStyle |
'full' , 'long' , 'medium' , 'short' |
timeStyle |
'full' , 'long' , 'medium' , 'short' |
weekday |
'long' (e.g., Thursday), 'short' (e.g., Thu), 'narrow' (e.g., T) |
day |
'numeric' (e.g., 1), '2-digit' (e.g., 01) |
month |
'numeric' (e.g., 2), '2-digit' (e.g., 02), 'long' (e.g., March), 'short' (e.g., Mar), 'narrow' (e.g., M) |
year |
'numeric' (e.g., 2012), '2-digit' (e.g., 12) |
era |
'long' (e.g., Anno Domini), 'short' (e.g., AD), 'narrow' (e.g., A) |
hour |
'numeric' , '2-digit' |
minute |
'numeric' , '2-digit' |
second |
'numeric' , '2-digit' |
timeZoneName |
'long' (e.g., British Summer Time), 'short' (e.g., GMT+1) |
timeZone |
The time zone to use. The only value implementations must recognize is "UTC"; the default is the runtime's default time zone. Implementations may also recognize the time zone names of the IANA time zone database, such as "Asia/Shanghai", "Asia/Kolkata", "America/New_York". |
hour12 |
Whether to use 12-hour time (as opposed to 24-hour time). Possible values are true and false |
Open Links
Custom handling: linkHandler: { onclick: <function>, target: '<string>' }
In the In-widget Webview : linkHandler: { target: 'oda-chat-webview' }
In new window: openLinksInNewWindow: true
The Web SDK provides various ways for you to control the target location of the URL links within the conversations. By default, clicking any link in the conversation opens the linked URL in the new tab. You can configure the widget to open it in a specific target using linkHandler
setting.
The linkHandler
setting expects an object that can take two optional fields - target
and onclick
. The target
field accepts a string that identifies the location where the linked URL is to be displayed (a tab, window, or <iframe>). The following keywords have special meanings for where to load the URL:
'_self'
: the current browsing context.'_blank'
: usually a new tab, but users can configure browsers to open a new window instead.'_parent'
: the parent browsing context of the current one. If no parent, behaves as'_self'
.'_top'
: the topmost browsing context (the "highest" context that's an ancestor of the current one). If no ancestors, behaves as'_self'
.
settings = {
...,
linkHandler: { target: '_blank'}
};
const Bots = new WebSDK(settings);
To open the links inside an iframe
, you can pass its name attribute in the target
property.
<iframe name="container" width="400" height="300"></iframe>
<script>
settings = {
...
linkHandler: { target: 'container'}
}
const Bots = new WebSDK(settings);
</script>
The onclick
property of linkHandler
allows you to add an event listener on all anchor links in the conversation. The listener is fired before the link is opened, and can be used to perform actions based on the link. The listener is passed an event
object as parameter that is generated by the click action. You can prevent the link from being opened by returning false
from the listener. The listener is also bound to the anchor element that is clicked, and the this
context refers to the HTMLAnchorElement
inside the listener.
linkHandler: {
onclick: function(event) {
console.log('The element clicked is', this);
console.log('The event fired from the click is', event);
console.log('The clicked link is', event.target.href);
console.log('Preventing the link from being opened');
return false;
}
}
You can set either one or both properties of the linkHandler
setting, but passing one of the fields is required.
In some scenarios, you may want to open links explicitly in a new window, overriding browser preferences. This can be achieved by passing openLinksInNewWindow: true
in the settings.
Finally, the chat widget also provides an in-widget Webview that can be used to display linked URLs inside the widget. This helps in preventing the user from navigating away from the page to a new tab or window. See In-Widget Webview for more details on this feature.
Relative Timestamps
Feature flag: timestampMode: 'relative'
Timestamp color: colors.timestamp: 'color string'
The appearance of the message timestamps can be modified with the timestampMode
setting. When set as 'relative'
, the timestamp is only shown before the first message of the day as a header, and for the new messages as an updating timestamp indicating the time passed since the message was added in the conversation. This relative timestamp is refreshed in the following intervals if no new message is added:
- For the first 10s
- Between 10s-60s
- Every minute between 1m-60m
- Every hour between 1hr-24hr
- Every day between 1d-30d
- Every month between 1m-12m
- Every year after the first year
As soon as a new message is added to the conversation, the relative timestamp from the last message is removed and added to the new message. The timestamp is also updated to start afresh for the new message.
For older messages in the conversation, a timestamp header is shown indicating the date before the first message of the day, for all days a conversation is performed. The timestamp header format can be customized using the timestampFormat
setting.
Restrict Attachment Types
Feature flag: enableAttachment: true
(default: true
)
Functionality configuration: shareMenuItems
Users can share various kinds of files and their location to the skills using the share menu from the chat widget. By default, the share attachment popup menu shows 4 items - sharing visual media files (i.e., images and videos, audio files, general files like documents, PDF, excel sheets, etc., and location). This menu can be customized to show fewer options using the shareMenuItems
setting. This setting accepts an array of strings where each item maps to a menu item – 'visual'
for Share Image/Video, 'audio'
for Share Audio, 'file'
for Share File, and 'location'
for Share Location. The share menu only shows the items for passed values, so by passing fewer items, the share menu can be modified. For example, passing shareMenuItems: ['audio', 'location']
in the settings will only show the Share Audio
and Share Location
menu items in the share popup menu. However, passing an empty array, or invalid values will show all menu items. To show no items, the feature can be disabled by passing enableAttachment: false
.
Custom Share Menu Items
You can configure the share menu items to set specific file types that users are allowed to upload. The custom menu item can be passed as an object to the shareMenuItems
array. It can be passed along with the string categories, or can also be passed without them. A custom share menu item may look as follows:
{
type: string, // Space separated list of file formats, pass '*' to allow all supported file types
label: string, // OPTIONAL, label for the share menu item, should preferably be configured through i18n strings
icon?: string, // OPTIONAL, Icon image source path or SVG source string, the file icon is displayed as fallback
maxSize?: number // OPTIONAL, Maximum file size allowed for upload in KiloBytes, the maximum and fallback value is 25 MB (25600 KB)
}
The following code snippet shows passing custom menu items in settings and defining their labels using the i18n
field.
const settings = {
shareMenuItems: [ {
type: 'odf',
label: 'Upload ODF',
}, {
type: 'pdf'
}, {
type: 'jpg png jpeg',
icon: 'https://image-source-site/imageicon'
}, {
type: 'doc docx xls',
maxSize: 4096
}],
i18n: {
en: {
share_pdf: 'Upload PDF',
share_jpg_png_jpeg: 'Upload Image',
share_doc_docx_xls: 'Upload document'
}
}
}
As illustrated by the above snippet, the i18n
labels for the custom menu items can be set by passing them with share_\<type joined by '_'\>
keys. For the wildcard '*'
, the label can be set using the 'share_all'
i18n
key. Using i18n
is recommended over the label
as it allows supporting the menu item labels in multiple languages.
Using attachment functionality often requires updating the network security policy of the host site. The attachments are uploaded to ODA object storage using HTTP calls and may get blocked by the site's CORS policies. With the site blocking the uploads, an error can be seen in the browser console indicating that the client has blocked the request due to CORS policy. To fix such issues, the network security policy of the host site should be updated to whitelist the ODA domain, allowing the upload requests to go through. Since the CORS policy does not apply to WebSockets, the conversations between the SDK and ODA skills are not impacted by such restrictions.
When connecting to a client auth enabled channel on the ODA platform, you can optionally make attachments more secure by passing enableAttachmentSecurity: true
. When set to true
, extra headers are passed to the attachment upload requests to ensure that they can't be downloaded without passing a valid signed JWT token as the value of the token
query parameter in the attachment fetch request URL.
Troubleshooting
- Connection fails immediately:
- Verify
URI
,channelId
,userId
and CORS/network access to ODA domain. - For client‑auth, ensure your JWT conforms (HS256 algorithm,
iat
claim,exp
,channelId
,userId
). - Check browser console for SDK error messages.
- Verify
- JWT errors:
- Validate time skew.
exp
must be in the future.iat
must be present. - Ensure channel secret used for signing matches the destination channel.
- Validate time skew.
- Attachments blocked:
- Host CORS policy must allow ODA object storage endpoints. Whitelist the ODA domain.
- For
enableAttachmentSecurity
, pass a valid token in thetoken
query param when downloading.
- Webview does not load page:
- If the target page returns
X-Frame-Options: deny|sameorigin
, it cannot be embedded. Use the fallback link.
- If the target page returns
- Voice recognition issues:
- Browser must allow microphone permissions.
- Use a supported
speechLocale
. - Adjust
noSpeechTimeout
if recognition times out too quickly.
- TTS is silent:
- If
initBotAudioMuted: true
, unmute via header toggle or set tofalse
. - Check selected TTS service and available voices via
getTTSVoices()
.
- If
- Tabs are not syncing:
- Ensure
enableTabsSync: true
and the sameURI
,channelId
,userId
across tabs. - Safari is not supported for cross‑tab sync.
- Ensure
- Accessibility:
- Provide localized
i18n
strings for screenreader labels. - Use
hotkeys
for keyboard discoverability. Ensure visible focus styles via CSS.
- Provide localized
- Framework integration (React/Angular/Vue):
- Use headless mode for full UI control. Manage lifecycle in component mount/unmount.
- If embedding the widget, perform SDK calls in effect/hooks after script load.
Limitations
- A short network outage (e.g., ~10s) can cause state inconsistencies if a server response is lost. Send the previous message again or restart the conversation.
- Attachment size limit: 25 MB.
- Only one connection to the ODA instance per
userId
per browser/device. Multiple devices/browsers with the sameuserId
will synchronize bot responses but not user messages.
References
Full Colors Reference
You can modify the following colors to customize the look of the widget. The provided color must be a hexadecimal color. If you don't provide a color, then a default color is used instead.
The colors can be configured using the CSS variables defined on the chat wrapper (.oda-chat-wrapper
) or by passing the colors
configuration. We recommend using CSS variables.
CSS Variable | Color Config Key | Description |
---|---|---|
--color-branding |
branding |
The primary color for branding the widget |
--color-launch-icon-background |
launchIconBackground |
The background color of the launch icon |
--color-text |
text |
The text color of the messages in the chat widget |
--color-text-light |
textLight |
The text color of the secondary text in messages, like card descriptions |
--color-header-background |
headerBackground |
The background color of the chat widget's header |
--color-header-button-fill |
headerButtonFill |
The SVG fill color of buttons in the chat header |
--color-header-text |
headerText |
The color of title in the chat header |
--color-header-button-background-hover |
headerButtonBackgroundHover |
The background color of the header buttons on hover |
--color-header-button-fill-hover |
headerButtonFillHover |
The fill color of the header buttons on hover |
--color-conversation-background |
conversationBackground |
The background of the chat widget's conversation pane |
--color-bot-message-background |
botMessageBackground |
The skill message background color |
--color-bot-text |
botText |
The skill text color. Overrides the text color, if passed. |
--color-user-message-background |
userMessageBackground |
The user message background color |
--color-user-text |
userText |
The user text color. Overrides the text color, if passed. |
--color-actions-background |
actionsBackground |
The action button background color |
--color-actions-background-focus |
actionsBackgroundFocus |
The action button background color on focus |
--color-actions-background-hover |
actionsBackgroundHover |
The action button background color on hover |
--color-actions-border |
actionsBorder |
The action button border color |
--color-actions-text |
actionsText |
The action button text color |
--color-actions-text-focus |
actionsTextFocus |
The action button text color on focus |
--color-actions-text-hover |
actionsTextHover |
The action button text color on hover |
--color-global-actions-background |
globalActionsBackground |
The global action button background color |
--color-global-actions-background-focus |
globalActionsBackgroundFocus |
The global action button background color on focus |
--color-global-actions-background-hover |
globalActionsBackgroundHover |
The global action button background color on hover |
--color-global-actions-border |
globalActionsBorder |
The global action button border color |
--color-global-actions-text |
globalActionsText |
The global action button text color |
--color-global-actions-text-focus |
globalActionsTextFocus |
The global action button text color on focus |
--color-global-actions-text-hover |
globalActionsTextHover |
The global action button text color on hover |
--color-primary-actions-background |
primaryActionsBackground |
The primary action button background color |
--color-primary-actions-background-focus |
primaryActionsBackgroundFocus |
The primary action button background color on focus |
--color-primary-actions-background-hover |
primaryActionsBackgroundHover |
The primary action button background color on hover |
--color-primary-actions-border |
primaryActionsBorder |
The primary action button border color |
--color-primary-actions-text |
primaryActionsText |
The primary action button text color |
--color-primary-actions-text-focus |
primaryActionsTextFocus |
The primary action button text color on focus |
--color-primary-actions-text-hover |
primaryActionsTextHover |
The primary action button text color on hover |
--color-danger-actions-background |
dangerActionsBackground |
The danger action button background color |
--color-danger-actions-background-focus |
dangerActionsBackgroundFocus |
The danger action button background color on focus |
--color-danger-actions-background-hover |
dangerActionsBackgroundHover |
The danger action button background color on hover |
--color-danger-actions-border |
dangerActionsBorder |
The danger action button border color |
--color-danger-actions-text |
dangerActionsText |
The danger action button text color |
--color-danger-actions-text-focus |
dangerActionsTextFocus |
The danger action button text color on focus |
--color-danger-actions-text-hover |
dangerActionsTextHover |
The danger action button text color on hover |
--color-card-background |
cardBackground |
The card message's background color |
--color-card-nav-button |
cardNavButton |
The card navigation button background color |
--color-card-nav-button-focus |
cardNavButtonFocus |
The card navigation button background color on focus |
--color-card-nav-button-hover |
cardNavButtonHover |
The card navigation button background color on hover |
--color-rating-star |
ratingStar |
The color applied to unselected rating stars of the feedback message |
--color-rating-star-fill |
ratingStarFill |
The color applied to hovered or selected rating stars of feedback message |
--color-links |
links |
The color of the links that are embedded in skill messages |
--color-user-links |
userLinks |
The color of the links that are embedded in user messages |
--color-horizontal-rule-background |
horizontalRuleBackground |
The color of the separator displayed at the end of the previous conversation |
--color-timestamp |
timestamp |
The color of the timestamp header and the relative timestamp in messages |
--color-agent-initials |
agentInitials |
The color of the agent initials that is displayed alongside the agent messages |
--color-agent-avatar-background |
agentAvatarBackground |
The background color of the agent initials avatar that is displayed alongside the agent messages |
--color-agent-name |
agentName |
The color of the agent name that is displayed above the agent messages |
--color-typing-indicator |
typingIndicator |
The background fill color of the typing indicator |
--color-footer-background |
footerBackground |
The background color of the chat widget's footer |
--color-footer-button-fill |
footerButtonFill |
The SVG fill color of the buttons in chat footer |
--color-footer-button-background-hover |
footerButtonBackgroundHover |
The background color of the footer buttons on hover |
--color-footer-button-fill-hover |
footerButtonFillHover |
The SVG fill color of the footer buttons on hover |
--color-input-background |
inputBackground |
The background color of the message input field |
--color-input-border |
inputBorder |
The border color of the input field |
--color-input-text |
inputText |
The text color in the message input field. Overrides text , if passed. |
--color-recognition-view-text |
recognitionViewText |
The text color in the recognition text view that is displayed in voice mode. If it's absent, text color is used. |
-- | recognitionViewButtonFill |
The SVG fill color of the mode toggle color in voice mode |
--color-visualizer-container-background |
visualizerContainerBackground |
The background color of the visualizer container displayed in voice mode. If absent, the user message background color is used. |
--color-visualizer |
visualizer |
The color used in the bars of the visualizer graph. If it's absent, the branding color is used instead. |
--color-notification-badge-background |
notificationBadgeBackground |
The background color of the message notification badge |
--color-notification-badge-text |
notificationBadgeText |
The text color of message count in notification badge |
--color-popup-background |
popupBackground |
The background color of prompts and popups |
--color-popup-text |
popupText |
The text and icon color of prompts and popups |
--color-popup-button-background |
popupButtonBackground |
The background color of popup buttons |
--color-popup-button-text |
popupButtonText |
The text color of popup buttons |
--color-popup-horizontal-rule |
popupHorizontalRule |
The horizontal rule color for separator for multi-lang chat menu action |
--color-popup-item-background-hover |
popupItemBackgroundHover |
The background color on hover of popup list items |
--color-table-header-background |
tableHeaderBackground |
The background color of table headers |
--color-table-header-text |
tableHeaderText |
The text color of table headers |
--color-table-background |
tableBackground |
The background color of tables |
--color-table-text |
tableText |
The text color of tables |
--color-table-separator |
tableSeparator |
The separator color of table rows |
--color-table-row-background-hover |
tableRowBackgroundHover |
The background color of table rows on hover in table-form messages |
--color-table-actions-background |
tableActionsBackground |
The background color of table actions |
--color-table-actions-background-focus |
tableActionsBackgroundFocus |
The background color of table actions on focus |
--color-table-actions-background-hover |
tableActionsBackgroundHover |
The background color of table actions on hover |
--color-table-actions-border |
tableActionsBorder |
The border color of table actions |
--color-table-actions-text |
tableActionsText |
The text color of table actions |
--color-table-actions-text-focus |
tableActionsTextFocus |
The text color of table actions on focus |
--color-table-actions-text-hover |
tableActionsTextHover |
The text color of table actions on hover |
--color-form-header-background |
formHeaderBackground |
The background color of form titles |
--color-form-header-text |
formHeaderText |
The text color of form titles |
--color-form-background |
formBackground |
The background color of forms |
--color-form-text |
formText |
The text color of forms |
--color-form-input-background |
formInputBackground |
The background color of the input fields in Edit-Form messages |
--color-form-input-border |
formInputBorder |
The border color of the input fields in Edit-Form messages |
--color-form-input-border-focus |
formInputBorderFocus |
The border color of the input fields on focus in Edit-Form messages |
--color-form-input-text |
formInputText |
The text color of the input fields in Edit-Form messages |
--color-form-label |
formLabel |
The color of the form labels |
--color-form-error |
formError |
The SVG fill color of the error message icon in Edit-Form messages |
--color-form-error-text |
formErrorText |
The text color of field-level error message that is displayed in Edit-Form messages |
--color-form-actions-background |
formActionsBackground |
The background color of form actions |
--color-form-actions-background-focus |
formActionsBackgroundFocus |
The background color of form actions on focus |
--color-form-actions-background-hover |
formActionsBackgroundHover |
The background color of form actions on hover |
--color-form-actions-border |
formActionsBorder |
The border color of form actions |
--color-form-actions-text |
formActionsText |
The text color of form actions |
--color-form-actions-text-focus |
formActionsTextFocus |
The text color of form actions on focus |
--color-form-actions-text-hover |
formActionsTextHover |
The text color of form actions on hover |
--color-primary-form-actions-background |
primaryFormActionsBackground |
The background color of primary actions in Table, Form, Table-Form and Edit-Form messages |
--color-primary-form-actions-background-focus |
primaryFormActionsBackgroundFocus |
The background color of primary actions on focus in Table, Form, Table-Form and Edit-Form messages |
--color-primary-form-actions-background-hover |
primaryFormActionsBackgroundHover |
The background color of primary actions on hover in Table, Form, Table-Form and Edit-Form messages |
--color-primary-form-actions-border |
primaryFormActionsBorder |
The border color of primary actions in Table, Form, Table-Form and Edit-Form messages |
--color-primary-form-actions-text |
primaryFormActionsText |
The text color of primary actions in Table, Form, Table-Form and Edit-Form messages |
--color-primary-form-actions-text-focus |
primaryFormActionsTextFocus |
The background color of primary actions on focus in Table, Form, Table-Form and Edit-Form messages |
--color-primary-form-actions-text-hover |
primaryFormActionsTextHover |
The background color of primary actions on hover in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-background |
dangerFormActionsBackground |
The background color of danger actions in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-background-focus |
dangerFormActionsBackgroundFocus |
The background color of danger actions on focus in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-background-hover |
dangerFormActionsBackgroundHover |
The background color of danger actions on hover in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-border |
dangerFormActionsBorder |
The border color of danger actions in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-text |
dangerFormActionsText |
The text color of danger actions in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-text-focus |
dangerFormActionsTextFocus |
The text color of danger actions on focus in Table, Form, Table-Form and Edit-Form messages |
--color-danger-form-actions-text-hover |
dangerFormActionsTextHover |
The text color of danger actions on hover in Table, Form, Table-Form and Edit-Form messages |
--color-error-message-background |
errorMessageBackground |
The background color of form-level error message |
--color-error-border |
errorBorder |
The border color of form-level error message |
--color-error-title |
errorTitle |
The title color of a form-level error message |
--color-error-text |
errorText |
The description color of an error message content. |
Full Icons Reference
Property Name | Description |
---|---|
avatarAgent |
The avatar icon displayed alongside responses from a live agent. |
avatarBot |
The avatar icon displayed alongside responses. |
avatarUser |
The avatar icon displayed alongside user messages. |
fileAudio |
The icon in audio attachment messages for unreachable URL. |
fileImage |
The icon in image attachment messages for unreachable URL. |
fileGeneric |
The icon in file attachment messages. |
fileVideo |
The icon in video attachment messages for unreachable URL. |
clearHistory |
The icon for the chat header button to clear local conversation history. |
close |
The icon for the close button in error message banners, expanded image previews, and the in-widget Webview. |
collapse |
The icon for the chat header button to collapse the widget to launch button. |
download |
The icon for the download file button in image attachment messages. |
error |
The icon displayed alongside error messages like upload failure |
expandImage |
The icon for the button to expand the image in attachment messages to full-screen |
externalLink |
The icon to indicate external link. |
keyboard |
The icon for chat footer button to switch to text input mode and stop voice recognition. |
logo |
The logo icon displayed in the chat header. |
launch |
The icon for the launch button displayed when the widget is collapsed. |
mic |
The icon for the chat footer button to switch to voice input mode and initiate voice recognition. |
rating |
The icon for the feedback rating actions. Preferable to pass a filled SVG string. |
send |
The icon for the chat footer button to send messages. |
shareMenu |
The icon for the share menu button in chat footer. |
shareMenuAudio |
The icon for the audio menu item in the share menu popup. |
shareMenuFile |
The icon for the file menu item in the share menu popup. |
shareMenuLocation |
The icon for the location menu item in the share menu popup. |
shareMenuVisual |
The icon for the image or video menu item in the share menu popup. |
ttsOff |
The icon for the chat header button to toggle message audio response when on mute. |
ttsOn |
The icon for the chat header button to toggle message audio response when audible. |
typingIndicator |
The animated icon in conversation pane indicating response being generated. |
Full Text (i18n) Keys Reference
Key | Default Value | Description |
---|---|---|
agent |
'Agent' |
The text used for the Agent. |
agentMessage |
'{0} says' |
The skill message indicator for screen readers. It is spoken by the screen readers before the skill responses. The text ({0} ) is replaced by the agent name. |
attachment_audio |
'Audio attachment' |
The text used for the TTS utterance of an audio attachment. |
attachment_file |
'File attachment' |
The text used for the TTS utterance of a file attachment. |
attachment_image |
'Image attachment' |
The text used for the TTS utterance of an image attachment. |
attachment_video |
'Video attachment' |
The text used for the TTS utterance of a video attachment. |
attachmentAudioFallback |
'Your browser does not support embedded audio. However you can {0}download it{/0}.' |
The fallback message that is displayed in place of an audio attachment if the audio can not be rendered by the client. The text between {0} and {/0} is set to a link to download the file. |
attachmentVideoFallback |
'Your browser does not support embedded video. However you can {0}download it{/0}.' |
The fallback message that's displayed in place of a video attachment if the video can not be rendered by the client. The text between {0} and {/0} is set to a link to download the file. |
audioResponseOff |
'Turn audio response on' |
The tooltip that appears when hovering over the audio utterance on the button in the header. |
audioResponseOn |
'Turn audio response off' |
The tooltip that appears when hovering over the audio utterance off the button in the header. |
avatarAgent |
'Agent icon' |
The alternative text used for the agent icon that's displayed alongside the agent messages. |
avatarBot |
'Bot icon' |
The alternative text used for the skill icon that's displayed alongside the skill messages. |
avatarUser |
'User icon' |
The alternative text used for the user icon that's displayed alongside the user messages. |
card |
'Card {0}' |
The card identifier. The text ({0} ) is replaced by the card index. |
cardImagePlaceholder |
'Card image' |
The text placeholder that's displayed while the card image is fetched and loaded. |
cardNavNext |
'Next card' |
The card navigation button label that displays the next card in horizontal layout. |
cardNavPrevious |
'Previous card' |
The card navigation button label that displays the previous card in horizontal layout. |
chatButtonTitle |
The title of the chat widget launch button. The chatTitle string is used if this is not passed. |
|
chatTitle |
'Chat' |
Title of the chat widget that is displayed on the header. |
chatSubtitle |
The subtitle of the chat widget that's displayed on the header below the title. If showConnectionStatus is set to true , and the subtitle is set as well, then the subtitle displays in place of the connection status. |
|
clear |
'Clear conversation' |
The tooltip that appears when hovering over the clear messages button in the header. |
close |
'Close widget' |
The tooltip that appears when hovering over the close widget button in the header. |
closing |
'Closing' |
The status text when the connection between the chat widget and the server is closing. |
connected |
'Connected' |
The status text when the connection between the chat widget and the server is established. |
connecting |
'Connecting' |
The status text when the connection between the chat widget and the server is connecting. |
connectionFailureMessage |
'Sorry, the assistant is unavailable right now. If the issue persists, contact your help desk.' |
The failure message that displays when the widget can't connect to skill. |
connectionRetryLabel |
'Try Again' |
The label of the retry connection button. |
defaultGreetingMessage |
'Hey, Nice to meet you! Allow me a moment to get back to you.' |
The default client greeting response that's displayed when the skill response has not been received within the number of seconds set by defaultGreetingTimeout . |
defaultWaitMessage |
'I\'m still working on your request. Thank you for your patience!' |
The default response that displays at the interval when an actual skill response has not been received. This interval is set, in seconds, by defaultWaitMessageInterval . |
defaultSorryMessage : |
'I\'m sorry. I can\'t get you the right content. Please try again.' |
The default client response when the skill response has not received within the number of seconds set by typingIndicatorTimeout . |
disconnected |
'Disconnected' |
The status text when the connection between the chat widget and the server is closed. |
download |
'Download' |
The tooltip that appears when hovering over the download button in attachments. |
editFieldErrorMessage |
'Field input is invalid' |
The field-level error message that is displayed in the Edit-Form messages when the value entered by the user is invalid for that field. SDK defaults to this message in-case clientErrorMessage is not supplied by the skill or browser validation errors are not present for input field. |
editFormErrorMessage |
'Some of the fields need your attention' |
The form-level error message that is displayed below the form submit action in Edit-Form messages on client-side validation. This is shown when at least one of the fields is not valid and there are more than one field. SDK defaults to this message in-case errorMessage is not supplied by the skill in the message payload. |
endConversation |
'End Conversation' |
The tooltip that appears when hovering over the end conversation header button. |
endConversationConfirmMessage |
'Are you sure you want to end the conversation?' |
The confirmation message that displays when a user clicks the end conversation button. |
endConversationDescription |
'This will also clear your conversation history.' |
The description message that displays along with the confirm message in the end conversation prompt. |
errorSpeechInvalidUrl |
'ODA URL for connection is not set. Please pass \'URI\' parameter during SDK initialization.' |
The error message that is displayed when the voice server URL is invalid or not set. |
errorSpeechMultipleConnection |
'Another voice recognition is ongoing. Can\'t start a new one.' |
The error message that's displayed when the user attempts a new voice message while another recognition is ongoing. This usually happens when multiple voice connections are attempted in a short interval by repeatedly toggling between keyboard and voice mode. |
errorSpeechNoResponse |
'Speech recognition is taking too long. Please try again.' |
The message displayed when speech recognition times out (after 10 seconds). |
errorSpeechStartRecognition |
'Unable to start recognition. Please try again.' |
The message displayed when recognition start fails because of either a network or backend failure. |
errorSpeechTooMuchTimeout |
'The voice message is too long to recognize and generate text.' |
The error message that's displayed when the user provides a voice message that can't be recognized because it's too long. |
errorSpeechUnavailable |
'To allow voice messaging, update your browser settings to enable access to your microphone.' |
The error message that's displayed when the browser does not provide any API to access the microphone. |
errorSpeechUnsupportedLocale |
'The locale set for voice recognition is not supported. Please use a valid locale in \'speechLocale\' setting.' |
The error message that's displayed when an unsupported speech locale is configured for voice recognition and a recording is attempted. |
inputPlaceholder |
'Type a message' |
The placeholder text that appears in the user input field in keyboard mode. |
imageViewerClose |
'Close image viewer' |
Accessibility text for the button that closes the expanded image. |
imageViewerOpen |
'Open image viewer' |
Accessibility text for the button that expands the image. |
itemIterator |
'Item {0}' |
Item identifier in a list of items in a message like Table, Form, or Table-Form message. The placeholder {0} is replaced by the item index. |
noResultText |
'No more results' |
The status text that's displayed when there are no matches while doing a search in multi select dropdown list. |
noSpeechTimeout |
'The voice could not be detected to perform recognition.' |
The status text that's displayed when the server is unable to recognize the voice. |
languageSelectDropdown |
'Select chat language' |
The tooltip that appears when users hover over the language selection button in the header. |
language_detect |
'Detect Language' |
The label for auto-detect option in language selection dropdown. |
language_<languageTag> |
Language Label |
The label for the language represented by the languageTag . For example, 'English' for 'en' in the language selection dropdown available when Multi-Lingual Chat is configured. |
linkField |
'Click on the highlighted text to open Link for {0}' |
The replacement utterance text for a link Field. The placeholder {0} is replaced with the linkLabel of the field. |
noText |
'No' |
The label for the No confirmation button. |
oldLinkAdvisory |
'Please note that the content of this link may have been updated since it was originally shared.' |
The label for advisory tooltip for links in messages from older conversations. |
openMap |
'Open Map' |
The label of the action button to open a location map. |
previousChats |
'End of previous conversation' |
The status text that's displayed at the end of older messages. |
ratingStar |
'Rate {0} star' |
The tooltip text that's displayed for each rating star in a feedback message. The placeholder {0} is replaced by the number of stars that the user has selected. |
recognitionTextPlaceholder |
'Speak your message' |
Placeholder text that appears in the recognition text field in voice mode. |
requestLocation |
'Requesting location' |
Text that is displayed while user location is requested on the browser. |
requestLocationDeniedPermission |
'To allow sharing your location, update your browser settings to enable access to your location. You can also type in the location instead.' |
The error message that's displayed when permission to access the location is denied. |
requestLocationDeniedTimeout |
'It is taking too long to get your location. Please try sharing it again, or else type it in.' |
The error message that's displayed when the location request is not resolved due to a timeout. |
requestLocationDeniedUnavailable |
'Your current location is unavailable. Please try sharing it again, or else type it in.' |
The error message that is displayed when the location request is denied due to the unavailability of the current location in the client's device. |
retryMessage |
'Try again' |
Text that is displayed when a user message is not sent to the server. |
send |
'Send message' |
Tooltip that appears when hovering over send button in the footer. |
shareAudio |
'Share Audio' |
The menu item text for sharing an audio file in the share popup. |
shareFile |
'Share File' |
The menu item text for sharing a generic file in the share popup. |
shareLocation |
'Share Location' |
The menu item text for sharing a location in the share popup. |
shareVisual |
'Share Image/Video' |
The menu item text for sharing an image or video file in the share popup. |
shareFailureMessage |
'Sorry, sharing is not available on this device.' |
The error message that's shown when a user clicks on a share action button and the share API is not supported by the device. |
skillMessage |
'Skill says' |
The skill message indicator for screen readers. It is spoken by the screen readers before the skill responses. |
showOptions |
'Show Options' |
The tooltip that appears when users hover over the menu button in the header when the header actions are collapsed. |
speak |
'Say your request' |
The tooltip that appears when hovering over speak button in the footer. |
relTimeNow |
'Now' |
The relative timestamp that's shown right after a new message |
relTimeMoment |
'A few seconds ago' |
The relative timestamp that displays ten seconds after the message has been received and before 60 seconds has elapsed since the last message was received. |
relTimeMin |
'{0}min ago' |
The relative timestamp that's shown for every minute since the last message. The placeholder {0} is replaced by the number of minutes passed. |
relTimeHr |
'{0}hr ago' |
The relative timestamp shown for each hour since the last message. The placeholder {0} is replaced by the number of hours passed. |
relTimeDay |
'{0}d ago' |
The relative timestamp that's shown each day since the last message. The placeholder {0} is replaced by the number of days passed. |
relTimeMon |
'{0}mth ago' |
The relative timestamp shown for each month since the last message. The placeholder {0} is replaced by the number of months passed. |
relTimeYr |
'{0}yr ago' |
The relative timestamp shown for every year since the last message. The placeholder {0} is replaced by the number of years passed. |
typingIndicator |
'Waiting for response' |
The accessibility text for the typing indicator. It is spoken by the screen readers. |
upload |
'Share popup' |
The tooltip that appears when hovering over the upload share popup button in the footer. |
uploadFailed |
'Upload Failed.' |
The error text for an upload failure. |
uploadFileNetworkFailure |
'Upload not completed due to network failure.' |
The error text that's displayed when the upload file does not complete due to network failure. |
uploadFileSizeLimitExceeded |
'File size should not be more than {0}MB.' |
The error text that's displayed when the upload file size is too large. The placeholder {0} is replaced by the SDK to the maximum allowed file size, which defaults to 25MB. |
uploadFileSizeZeroByte |
'Files of size zero bytes can\'t be uploaded.' |
The error text that's displayed when the upload file size is 0 bytes. |
uploadUnauthorized |
'Upload request is unauthorized.' |
The error text that's displayed when the upload request is unauthorized. |
uploadUnsupportedFileType |
'Unsupported file type.' |
The error text that's displayed when an unsupported file type upload is attempted. |
userMessage |
'I say' |
The user message indicator for screen readers. It is spoken by the screen readers before the user messages. |
utteranceGeneric |
'Message from skill.' |
The fallback description of a response message for an utterance that was not parsed by the SDK. |
webViewAccessibilityTitle |
'In-widget Webview to display links' |
The default accessibility title for the Webview that is read out by screen readers |
webViewClose |
'Done' |
The default label/tooltip title for Webview close button |
webViewErrorInfoDismiss |
'Dismiss' |
The tooltip for the dismiss button that's used to close the fallback link inside the webview. |
webViewErrorInfoText |
'Don't see the page? {0}Click here{/0} to open it in a browser.' |
The informational text displayed in the webview when the clicked link can't be opened within it. The text between {0} and {/0} is set to the original link that opens in a new tab or window. |
yesText |
'Yes' |
The label for the Yes confirmation button. |
Full Hotkeys Element Map
The following table lists the keys and the corresponding elements against which you can pass the hotkey attribute. The attribute value is not case-sensitive.
Key | Element |
---|---|
clearHistory |
The button that clears the conversation history. |
close |
The button that closes the chat widget and ends conversation. |
collapse |
The button that collapses the expanded chat widget. |
input |
The text input field on the chat footer. |
keyboard |
The button that switches the input mode from voice to text. |
language |
The select menu that shows the language selection list. |
launch |
The chat widget launch button. |
mic |
The button that switches the input mode from text to voice. |
send |
The button that sends the input text to the skill. |
shareMenu |
The share menu button in the chat footer. |
shareMenuAudio |
The menu item in the share menu popup that selects an audio file for sharing. |
shareMenuFile |
The menu item in the share menu popup that selects a generic file for sharing. |
shareMenuLocation |
The menu item in the share menu popup that selects user location for sharing. |
shareMenuVisual |
The menu item in the share menu popup that selects an image or video file for sharing. |
Full CSS Class Hooks
Class | Component |
---|---|
oda-chat-wrapper |
The wrapper for entire chat widget |
oda-chat-button |
The chat widget launcher button |
oda-chat-notification-badge |
An message notification badge yet unseen |
oda-chat-widget |
The expanded chat widget; wraps the widget header, conversation, and footer |
oda-chat-header |
The chat widget header |
oda-chat-logo |
The logo on the widget header |
oda-chat-title |
The title on the widget header |
oda-chat-connection-status |
The connection status. Each connection value has its own class as well - oda-chat-connected , oda-chat-disconnected , etc. |
oda-chat-connected |
Applied as a sibling to connection-status when the widget is connected to server |
oda-chat-connecting |
Applied as a sibling to connection-status when the widget is connecting to server |
oda-chat-disconnected |
Applied as a sibling to connection-status when the widget is disconnected from server |
oda-chat-closing |
Applied as a sibling to connection-status when the widget is disconnecting from server |
oda-chat-header-button |
A common class for all header buttons |
oda-chat-button-clear |
The clear messages button |
oda-chat-button-narration |
The skill audio response toggle button |
oda-chat-button-close |
The close widget button |
oda-chat-conversation |
The container for the conversation |
oda-chat-message |
A common wrapper class for all chat messages |
oda-chat-left |
The skill message wrapper |
oda-chat-right |
The user message wrapper |
oda-chat-icon-wrapper |
The skill/person icon wrapper displayed alongside message |
oda-chat-message-icon |
The skill/person icon image displayed alongside message |
oda-chat-message-bubble |
The message bubble |
oda-chat-message-actions |
The action buttons wrapper |
oda-chat-message-global-actions |
The global action buttons wrapper |
oda-chat-rating-star |
The rating star button in a feedback message |
oda-chat-rating-star-icon |
The SVG icon for the rating star button |
oda-chat-action-postback |
The postback action button |
oda-chat-action-location |
The location request action button |
oda-chat-card |
The card message |
oda-chat-footer |
The chat widget footer |
oda-chat-footer-button |
The common class for all footer buttons |
oda-chat-button-upload |
The upload file button |
oda-chat-button-send |
The send message button |
oda-chat-user-input |
the user input text area |
Conversation Message Model Reference
To use features like headless mode and delegate, a clear understanding of skill and user messages is essential. Everything received from and sent to the chat server are represented as messages. This includes:
- Messages from the user to the skill (e.g., "I want to order a Pizza")
- Messages from the skill to the user (e.g., "What kind of crust do you want?")
The following section describes each of the message types in more detail.
Base Types
These are the base types that are used by user-to-skill messages and skill-to-user messages. They are the building blocks for the messages.
Action
An action represents something that the user can select. Every action includes the following properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | 'call' , 'client' , 'location' , 'popup' , 'postback' , 'share' , 'submitForm' , 'url' |
Yes |
label |
The descriptive label text for the action. | string | At least a single label or imageUrl property must be present |
imageUrl |
Image to display for the action | string | At least a single label or imageUrl property must be present. |
style |
The rendering style of the button | "primary" , "danger" , "default" |
No |
displayType |
The rendering for the type of action element (button, link, or icon). | "button" , "link" , "icon" |
No |
voice |
Content to be used for voice description of the action | Voice |
No |
tooltip |
The tooltip displayed when hovering over the action button | string | No |
channelExtensions |
The channel-specific extension properties associated with the action | JSONObject | No |
CallAction
This action will request the client to call a specified phone number on the user's behalf.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "call" |
Yes |
phoneNumber |
The phone number to call | string | Yes |
Example JSON
{
"type": "call",
"label": "Call Support",
"imageUrl": "http://ahoraescuando.bluefm.com.ar/files/2016/05/cuidado.jpg",
"phoneNumber": "18002231711"
}
ClientAction
This action performs an action on the client app when activated by the user.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "client" |
Yes |
actionType |
The type of client action | 'custom' , 'copyMessageText' , 'navigate' , 'query' , 'updateFields' |
Yes |
context |
The application context | string | No |
customAction |
Set when actionType is 'custom' |
string | No |
properties |
Key-value pairs that can be used as arguments when executing the action | JSONObject | No |
LocationAction
This action will request the client to ask the user for a location.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "location" |
Yes |
PopupAction
This action will request the client to ask the user for a location.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "popup" |
Yes |
popupContent |
The CMM message type that should be displayed inside the dialog window | MessagePayload | Yes |
{
"type": "popup",
"label": "Give Feedback",
"popupContent": {
"formRows": [
{
"columns": [
{
"width": "stretch",
"fields": [
{
"displayType": "text",
"label": "What was the issue with this response?"
},
{
"displayType": "multiSelect",
"options": [
{
"label": "Inaccurate",
"value": "inaccurate"
},
{
"label": "Inappropriate",
"value": "inappropriate"
}
],
"id": "system_feedback_reasons",
"required": true
},
{
"displayType": "textInput",
"id": "system_feedback_comments",
"placeholder": "Additional feedback"
}
]
}
]
},
{
"columns": [
{
"fields": [
{
"displayType": "action",
"action": {
"postback": {
"rating": "negative",
"action": "cancel",
},
"label": "Cancel",
"type": "postback"
},
}
]
},
{
"fields": [
{
"displayType": "action",
"action": {
"postback": {
"rating": "negative",
"system.state": "invokeLLM"
},
"label": "Submit Feedback",
"type": "submitForm"
},
}
]
}
]
}
],
"type": "editForm",
"title": "Give your feedback",
"formColumns": 1,
}
}
PostbackAction
This action will send a predefined postback back to the skill if the user selects the action.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "postback" |
Yes |
postback |
The postback to be sent back if the action is selected | string or JSONObject | Yes |
Example JSON
{
"type": "postback",
"label": "Large Pizza",
"imageUrl": "https://amicis.com/images/gallery/locations/11.jpg",
"postback": {
"state": "askSize",
"action": "getCrust"
}
}
ShareAction
This action will request the client to open a sharing dialog for the user.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "share" |
Yes |
SubmitFormAction
This action is used to submit an Editable Form to the skill in case the form passes the client side validation.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "submitForm" |
Yes |
postback |
The postback payload, which might include an action property to trigger navigation. The value of this property should be set in the FormSubmissionMessagePayload | JSONObject | No |
Example JSON
{
"type": "submitForm",
"label": "Submit",
"postback": {
"system.botId": "6803DE12-DAA9-4182-BD54-3B4D431554F4",
"system.flow": "ExpenseFlow",
"system.state": "editFormMapVar"
}
}
UrlAction
This action will request the client to open a website in a new tab or in an in-app browser.
It adds the following properties to the Action
properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "url" |
Yes |
url |
The URL of the website to display | string | Yes |
Example JSON
{
"type": "location",
"label": "Share location",
"imageUrl": "http://images.clipartpanda.com/location-clipart-location-pin-clipart-1.jpg"
}
Attachment
This represents an attachment that's sent from the user to the skill or from the skill to the user.
Name | Description | Type | Required? |
---|---|---|---|
type |
The type of attachment | "audio" , "file" , "image" , "video" |
Yes |
url |
The URL to download the attachment | string | Yes |
title |
A title for the attachment | string | No |
Example JSON
{
"title": "Oracle Open World Promotion",
"type": "image",
"URL": "https://www.oracle.com/us/assets/hp07-oow17-promo-02-3737849.jpg"
}
Card
A card represents a single card in the message payload. It contains the following properties:
Name | Description | Type | Required? |
---|---|---|---|
title |
The title of the card, displayed as the first line on the card. | string | Yes |
description |
The description of the card | string | No |
imageUrl |
URL of the image that is displayed | string | No |
URL |
URL of a website that is opened when taping on the card | string | No |
actions |
An array of actions related to the text | Array<Action> | No |
voice |
Content to be used for voice description of the card | Voice | No |
channelExtensions |
The channel-specific extension properties associated with the card | JSONObject | No |
Location
This represents a Location object.
Name | Description | Type | Required? |
---|---|---|---|
latitude |
The GPS coordinate's longitude value | double | Yes |
longitude |
The GPS coordinate's longitude value | double | Yes |
title |
A title for the location | string | No |
url |
A URL for displaying a map of the location | string | No |
Example JSON
{
"title": "Oracle Headquarters",
"url": "https://www.google.com.au/maps/place/37°31'47.3%22N+122°15'57.6%22W",
"longitude": -122.265987,
"latitude": 37.529818
}
Voice
This represents a voice information in a message.
Name | Description | Type | Required? |
---|---|---|---|
text |
Summary text for TTS | string | At least one of the properties must be passed |
longText |
Detailed text for TTS | string | At least one of the properties must be passed |
soundUrl |
URL of a sound file to play | string | At least one of the properties must be passed |
Field
This represents the atomic information of a table cell or a form field in Table
, Form
, Table-Form
, Edit Form
object, provided as key-value pair. The fields can be of two types: ReadOnlyField and EditableField.
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "link" , "text" , "datePicker" , "multiSelect" , "numberInput" , "singleSelect" , "textInput" , "timePicker" , "toggle" , "action" , "media" |
Yes |
label |
Key of the field | string | No |
marginTop |
The amount of vertical space between this field and the previous field in the same column | "none" , "medium" , "large" |
No |
labelFontSize |
The font size used for the field label | 'extraSmall' , "small" , "medium" , "large" |
No |
labelFontWeight |
The font weight used for the field label | "light" , "medium" , 'semiBold' , "bold" |
No |
channelExtensions |
The channel-specific extension properties associated with the field | JSONObject | No |
Read Only Field
This represents a read only field. All read only fields inherit the generic field properties and have the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
alignment |
The positioning of the label within its cell. | "center" , "left" , "right" |
No |
value |
The field value | unknown | No |
width |
The suggested percentage of the total available width that the field should occupy in a table layout. | number | No |
Action Field
The media field inherits all read only field properties and has following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "action" |
Yes |
action |
The action that should be performed when the user clicks the action button. | Action | Yes |
Link Field
The link field inherits all read only field properties and has following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "link" |
Yes |
linkLabel |
The label used for the hyperlink | string | No |
imageUrl |
The URL of the image that opens a link when clicked. | string | No |
Media Field
The media field inherits all read only field properties and has following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "media" |
Yes |
mediaType |
The field media type. | "audio" , "image" , "video" |
Yes |
Text Field
The text field inherits all read only field properties and has following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "text" |
Yes |
fontSize |
The font size used for the field value | "small" , "medium" , "large" |
No |
fontWeight |
The font weight used for the field value | "medium" , "bold" , "light" |
No |
truncateAt |
The position at which lengthy text gets truncated and an ellipsis mark (which indicates the value has been truncated) displays. | number | No |
Note: If both
linkLabel
andimageUrl
are present, image will be displayed that opens a link when clicked.
Editable Field
This represents an editable field. All editable fields inherit the generic field properties and have the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
id |
The ID of the field | string | Yes |
autoSubmit |
When set to true, the form is partially submitted when the user has entered a value for the field. See Auto-Submit for more details. | boolean | No |
clientErrorMessage |
The field level error message that's displayed below the field when a client-side validation error occurs. If not provided, SDK defaults to editFieldErrorMessage |
string | No |
defaultValue |
The default value for the corresponding field | unknown | No |
placeholder |
A description of the input that's expected from the user. This text displays when the user has not yet made a selection or entered a value. | string | No |
required |
Whether this input is required | boolean | No |
serverErrorMessage |
The field level error message that's displayed below the field when a server-side validation error occurs. This error message must be included in the payload sent by the skill. | string | No |
DatePicker
The date picker field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "datePicker" |
Yes |
defaultValue |
The initial value for this field, format must be YYYY-MM-DD | string | No |
minDate |
The minimum, or earliest, date allowed. The format must be YYYY-MM-DD. | string | No |
maxDate |
The maximum, or latest, date allowed. The format must be YYYY-MM-DD. | string | No |
MultiSelect
The multi select field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "multiSelect" |
Yes |
options |
An array of options presented to the user. | Array<SelectFieldOption> | Yes |
defaultValue |
The default selection | Array<object> primitive data types (could be a string, number, boolean, etc.) | No |
layoutDirection |
The layout direction to use for the radio buttons when layoutStyle is set to radioGroup . The default direction is "vertical" . |
"horizontal" , "vertical" |
No |
layoutStyle |
The layout style used to render the multi select options. The default layout is list . |
"list" , "checkboxes" |
No |
NumberInput
The number input field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "numberInput" |
Yes |
defaultValue |
The initial value for this field | number | No |
minValue |
A smallest allowable number | number | No |
maxValue |
A largest allowable number | number | No |
SingleSelect
The single select field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "singleSelect" |
Yes |
options |
An array of options presented to the user. | Array<SelectFieldOption> | Yes |
defaultValue |
The default selection | Primitive data types (string, number, boolean, etc.) | No |
layoutDirection |
The layout direction to use for the radio buttons when layoutStyle is set to radioGroup . The default direction is "vertical" . |
"horizontal" , "vertical" |
No |
layoutStyle |
The layout style used to render the single select options. The default layout is list . |
"list" , "radioGroup" |
No |
TextInput
The text input field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "textInput" |
Yes |
defaultValue |
The initial value for this field | string | No |
inputStyle |
The input style that should be rendered. Falls back to text when not specified. Allowable values are: "text" , "tel" , "url" , "email" and "password" |
string | No |
maxLength |
The maximum number of characters allowed in the text input field | number | No |
minLength |
The minimum length of input that the user must provide | number | No |
multiline |
The flag that determines whether to render multiple lines of input | boolean | No |
validationRegularExpression |
A regular expression indicating the required format for this text input. | string | No |
TimePicker
The time picker field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "timePicker" |
Yes |
defaultValue |
The initial value for this field, format must be HH:mm in 24H format | string | No |
minTime |
The minimum, or earliest, time allowed, entered as HH:mm in 24-hour format. For example, 00:00. | string | No |
maxTime |
The maximum, or latest, time allowed, entered as HH:mm in 24-hour format. For example, 00:00. | string | No |
Toggle
The toggle field inherits all editable field properties and has the following additional properties:
Name | Description | Type | Required? |
---|---|---|---|
displayType |
The field type | "toggle" |
Yes |
valueOff |
The value when toggle is off | string | Yes |
valueOn |
The value when toggle is on | string | Yes |
defaultValue |
The initial selected value. If you want the toggle to be initially on, set this to the value of valueOn 's value. |
string | No |
labelOff |
The label that is displayed when the toggle field is hovered in the off state | string | No |
labelOn |
The label that is displayed when the toggle field is hovered in the on state | string | No |
SelectFieldOption
The SingleSelect and MultiSelect fields use a list of select options with following properties:
Name | Description | Type | Required? |
---|---|---|---|
label |
The display text | string | Yes |
value |
The raw value for the choice | Primitive data types (string, number, boolean, etc.) | Yes |
channelExtensions |
The channel-specific extension properties associated with the field option | JSONObject | No |
TableHeading
This represents a heading for tables in a Table
or Table-Form
object.
Name | Description | Type | Required? |
---|---|---|---|
label |
The label for the heading | string | Yes |
alignment |
Positioning of the label within its cell | "center" , "left" , "right" |
Yes |
width |
Suggested percentage of table width that should be provided to the heading | string | No |
channelExtensions |
The channel-specific extension properties associated with the heading | JSONObject | No |
TableRow
This represents an array of fields.
Name | Description | Type | Required? |
---|---|---|---|
fields |
Array of read-only fields | Array<Field> | Yes |
selectAction |
The action that is executed when the row is selected. The label of the action is shown as a tooltip when users hover over the row. | Action | No |
channelExtensions |
The channel-specific extension properties associated with the row | JSONObject | No |
Form
This represents an array of fields or form rows along with a title. Used in Table-Form
messages for nested forms of a table row.
Name | Description | Type | Required? |
---|---|---|---|
fields |
Array of fields | Array<Field> | Yes |
id |
The ID of the form | string | No |
title |
A representative title for the form in the table row | string | No |
formRows |
A list of rows displayed in the form. You can define either the list of fields using the fields property, or a list of rows using this property. The fields and formRows properties are mutually exclusive. |
Array<FormRow> | No |
selectAction |
The action that is executed when the form is selected. The label of the action is shown as a tooltip when users hover over the form. | Action | No |
actions |
A list of actions displayed at the bottom of the form | Array<Action> | No |
separator |
Whether to display a separator for the form or not. If this value is not passed, then a separator displays for the form. | boolean | No |
channelExtensions |
The channel-specific extension properties associated with the form | JSONObject | No |
FormRow
A form row contains a list of columns that are laid out side-by-side. Multiple form rows are laid out vertically with each form row starting on a new line below the previous form row.
Name | Description | Type | Required? |
---|---|---|---|
columns |
A list of columns displayed in the form row. | Array<FormColumn> | Yes |
type |
Indicates when the form row is a header or a data row. | 'header' , 'dataRow' |
No |
id |
The ID of the form row | string | No |
selectAction |
The action that is executed when the form row is selected. The label of the action is shown as a tooltip when users hover over the form row. | Action | No |
separator |
When set to true , a separator line is added above the form row content. |
boolean | No |
channelExtensions |
The channel-specific extension properties associated with the form row | JSONObject | No |
FormColumn
A column contains a list of fields. These fields are laid out vertically.
Name | Description | Type | Required? |
---|---|---|---|
fields |
A list of fields displayed vertically in the column. The fields must be read only fields when the column is used in a FormRow within a Form message Payload. The fields can include both editable and read only fields when the FormRow is used within an EditFormMessagePayload. | Array<Field> | Yes |
id |
The ID of the column | string | No |
verticalAlignment |
The vertical alignment of the column with respect to other columns in the same form row | "bottom" , "center" , "top" |
No |
width |
Determines how the width of the column is determined within the form row. | "auto" , "stretch" , 'fixed' |
No |
widthPct |
Passed when width is set to fixed . Sets the width property on the column element to the passed in percentage value. |
number | No |
channelExtensions |
The channel-specific extension properties associated with the column | JSONObject | No |
PaginationInfo
This represents the paging information of results in a Table
, Form
, and Table-Form
object.
Name | Description | Type | Required? |
---|---|---|---|
totalCount |
Total count of results | number | Yes |
rangeSize |
Range size of results per page | number | Yes |
status |
Paging status message | string | Yes |
currentRangeSize |
Size of current range of results | number | Yes |
rangeStart |
Starting offset of the current range of results | number | Yes |
nextRangeSize |
Size of the next range of results | number | Yes |
hasPrevious |
Indicates whether there is a previous set of results | boolean | Yes |
hasNext |
Indicates whether there is next set of results | boolean | Yes |
EventContextProperties
The Event Context Properties represent the CloudEvent context properties.
Name | Description | Type | Required? | Example |
---|---|---|---|---|
dataschema |
Identifies the schema that the data adheres to. | URI | No | "/dw/approval_payload.json" |
datacontenttype |
The content type of the data contained in the data attribute. | string | No | "application/json" |
source |
The resource that produced the event. | URI | No | "objectstorage" |
time |
The time of the event expressed in RFC 3339 timestamp format. | Timestamp | No | "2021-01-10T21:19:24Z" |
specversion |
The version of the CloudEvents specification | string | No | "1.0" |
id |
The ID of the CloudEvents specification | string | No | "123e4567-e89b-12d3-a456-426614174000" |
subject |
The event's subject in the context of the event producer and/or event type. | string | No | "mynewfile.jpg" |
requesttype |
Determines how the runtime executes the event handler flows. Defaults to 'interrupt' if the value is missing. |
"interrupt" , "join" , "notification" , "reset" , "sync" |
No | "interrupt" |
Conversation Messages
All messages that are part of the conversation are structured as follows:
Name | Description | Type | Required? |
---|---|---|---|
messagePayload |
Message payload | Message Payload | Yes |
userId |
User ID | string | Yes |
Example conversation message
{
"messagePayload": {
"text": "show menu",
"type": "text"
},
"userId": "guest"
}
Message Payload
Message is the abstract base type for all other messages. All messages extend it to provide more information.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | string | Yes |
User Message Payload
This represents a Message sent from a user to a skill.
User Text Message Payload
This is a simple text message sent to the server.
It applies the following properties to the Message Payload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "text" |
Yes |
text |
Text message | string | Yes |
{
"messagePayload": {
"text": "Order Pizza",
"type": "text"
},
"userId": "guest"
}
User Attachment Message Payload
This is the attachment response message sent to the server.
It applies the following properties to the Message Payload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "attachment" |
Yes |
attachment |
Attachment metadata | Attachment | Yes |
{
"messagePayload": {
"attachment": {
"type": "image",
"URL": "http://oda-instance.com/attachment/v1/attachments/d43fd051-02cf-4c62-a422-313979eb9d55"
},
"type": "attachment"
},
"userId": "guest"
}
User Location Message Payload
This is the location response message sent to the server.
It applies the following properties to the Message Payload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "location" |
Yes |
location |
User location information | Location | Yes |
{
"messagePayload": {
"location": {
"latitude": 45.9285271,
"longitude": 132.6101925
},
"type": "location"
},
"userId": "guest"
}
User Postback Message Payload
This is the postback response message sent to the server.
It applies the following properties to the Message Payload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "postback" |
Yes |
postback |
The postback of the selected action | string or JSONObject | Yes |
text |
Text for postback | string | No |
{
"messagePayload": {
"postback": {
"variables": {
"pizza": "Small"
},
"system.botId": "69F2D6BB-35BF-4BCA-99A0-A88D44A51B35",
"system.state": "orderPizza"
},
"text": "Small",
"type": "postback"
},
"userId": "guest"
}
User InboundEvent Message Payload
This represents the inbound event messages that can be sent to the server.
It applies the following properties to the Message Payload
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "inboundEvent" |
Yes |
eventData |
The business data | JSONObject | Yes |
eventType |
The event type (defined in the event catalog) | string | Yes |
eventVersion |
The event type version (defined in the event catalog) | string | Yes |
contextProperties |
The event context properties | EventContextProperties | No |
Here's an example:
{
"messagePayload": {
"eventData": {
"size": "Medium",
"type": "Cheese"
},
"eventVersion": "1.0",
"eventType": "com.pizzastore.pizza.orderserved",
"type": "inboundEvent",
"contextProperties": {
"id": "6ce23f09-bff7-4369-8467-0c510e971aaf",
"source": "pizza/service",
}
},
"userId": "guest"
}
User Form Submission Message Payload
This represents the form submission message that's sent after the user has submitted a form by clicking SubmitFormAction. It has the following properties:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "formSubmission" |
Yes |
submittedFields |
Key-value pairs of the submitted field values. The key is the name (ID) of the field. | JSONObject | Yes |
partialSubmitField |
The ID of the field that triggers a partial form submission. Fields with the autoSubmit property set to true can trigger a partial form submission. See Auto-Submit for more details. |
string | No |
postback |
The postback payload, which might include an action property to trigger navigation. The value of this property should be taken from the SubmitFormAction | JSONObject | No |
Here's an example:
{
"messagePayload": {
"submittedFields": {
"Attendees": [
"Toff van Alphen"
],
"Type": "Public transport",
"Description": "expense",
"Subject": "Expense",
"Date": "2023-06-07",
"Time": "18:58",
"Amount": 6,
"TipIncluded": "true"
},
"partialSubmitField": "Attendees",
"type": "formSubmission"
},
"userId": "guest"
}
Response Message Payload
This represents a Message Payload sent from a skill or an agent to the user.
It applies the following properties to the MessagePayload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | string | Yes |
headerText |
The header text displayed above the message text | string | No |
footerText |
The footer text displayed below the message text and actions, but before the global actions | string | No |
actions |
A list of actions related to the message | Array<Action> | No |
footerForm |
A form layout that displays below the footer text of the message and above its global actions. | Form | No |
globalActions |
A list of global actions related to the text | Array<Action> | No |
embeddedActions |
List of actions that can be triggered by a special HTML <span> tag in the message text | Array<Client Action> | No |
llmGenerated |
Indicates whether the content is LLM-generated | boolean | No |
voice |
Description of the message that can be used for audio-based description | Voice | No |
channelExtensions |
The channel-specific extension properties associated with the message | JSONObject | No |
Response Attachment Message
This represents an attachment message.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "attachment" |
Yes |
attachment |
The attachment sent | Attachment | Yes |
Response Card Message
This represents a set of choices displayed to the user, either horizontally like a carousal or vertically like a list.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "card" |
Yes |
cards |
Array of cards to be rendered | Array<Card> | Yes |
layout |
Whether to display the cards horizontally or vertically | 'horizontal' , 'vertical' |
Yes |
Response Command Message Payload
This represents a command message payload.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "command" |
Yes |
command |
Command that needs to be performed | string | Yes |
properties |
Map of key-value pairs | JSONObject | Yes |
Response Error Message Payload
This represents an error message payload that provides feedback to clients on errors in the backend.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "error" |
Yes |
errorMessage |
The error message | string | Yes |
error |
java.lang.Error object | string | No |
Response ExecuteApplicationContextCommand Message Payload
This represents an execute application action command message payload.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "executeApplicationActionCommand" |
Yes |
actionType |
Type of action | "custom" , "navigate" , "query" , "updateFields" |
Yes |
command |
Execute application action command | "executeApplicationAction" |
Yes |
context |
Name of the application context | string | Yes |
customAction |
Must be set when actionType is 'custom' |
string | No |
properties |
Key-value pairs that can be used as arguments when executing the action | JSONObject | No |
Response Feedback Message
This represents a feedback rating component that takes user's feedback using a rating gauge. Typically, this gauge is represented as a star rating system. Its payload is similar to a normal text message, but it has an additional channelExtensions
object field that is set as { "displayType": "stars" }
.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "text" |
Yes |
text |
Text of the message | string | Yes |
channelExtensions |
An object depicting specific extension to the payload | { "displayType": "stars" } |
Yes |
Example JSON
{
"messagePayload":{
"text":"How would you like to rate us?",
"type":"text",
"actions":[
{
"postback":{
"variables":{
"rating":"1"
},
"system.botId":"61C8D800-23AF-4DDD-B5AF-D79AB3F3BE67",
"action":"1",
"system.state":"giveFeedback"
},
"label":"1",
"type":"postback"
},
{
"postback":{
"variables":{
"rating":"2"
},
"system.botId":"61C8D800-23AF-4DDD-B5AF-D79AB3F3BE67",
"action":"2",
"system.state":"giveFeedback"
},
"label":"2",
"type":"postback"
},
{
"postback":{
"variables":{
"rating":"3"
},
"system.botId":"61C8D800-23AF-4DDD-B5AF-D79AB3F3BE67",
"action":"3",
"system.state":"giveFeedback"
},
"label":"3",
"type":"postback"
},
{
"postback":{
"variables":{
"rating":"4"
},
"system.botId":"61C8D800-23AF-4DDD-B5AF-D79AB3F3BE67",
"action":"4",
"system.state":"giveFeedback"
},
"label":"4",
"type":"postback"
},
{
"postback":{
"variables":{
"rating":"5"
},
"system.botId":"61C8D800-23AF-4DDD-B5AF-D79AB3F3BE67",
"action":"5",
"system.state":"giveFeedback"
},
"label":"5",
"type":"postback"
}
],
"channelExtensions":{
"displayType":"stars"
}
},
"source":"BOT",
"userId":"<userID>"
}
Response Location Message
This represents a location message.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "location" |
Yes |
location |
The location | Location | Yes |
Example JSON
{
"messagePayload": {
"type": "card",
"layout": "horizontal",
"cards": [
{
"title": "Hawaiian Pizza",
"description": "Ham and pineapple on thin crust",
"actions": [
{
"type": "postback",
"label": "Order Small",
"postback": {
"state": "GetOrder",
"variables": {
"pizzaType": "hawaiian",
"pizzaCrust": "thin",
"pizzaSize": "small"
}
}
},
{
"type": "postback",
"label": "Order Large",
"postback": {
"state": "GetOrder",
"variables": {
"pizzaType": "hawaiian",
"pizzaCrust": "thin",
"pizzaSize": "large"
}
}
}
]
},
{
"title": "Cheese Pizza",
"description": "Cheese pizza (i.e. pizza with NO toppings) on thick crust",
"actions": [
{
"type": "postback",
"label": "Order Small",
"postback": {
"state": "GetOrder",
"variables": {
"pizzaType": "cheese",
"pizzaCrust": "thick",
"pizzaSize": "small"
}
}
},
{
"type": "postback",
"label": "Order Large",
"postback": {
"state": "GetOrder",
"variables": {
"pizzaType": "cheese",
"pizzaCrust": "thick",
"pizzaSize": "large"
}
}
}
]
}
],
"globalActions": [
{
"type": "call",
"label": "Call for Help",
"phoneNumber": "123456789"
}
]
},
"userId": "guest"
}
Response OutboundEvent Message
This represents the outbound event messages that can be sent by the server.
It applies the following properties to the Message Payload
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "outboundEvent" |
Yes |
eventType |
The event type (defined in the event catalog) | string | Yes |
eventVersion |
The event type version (defined in the event catalog) | string | Yes |
eventData |
The business data | JSONObject | Yes |
contextProperties |
The event context properties | EventContextProperties | No |
Here's an example:
{
"messagePayload": {
"eventData": {
"size": "Medium",
"type": "Cheese"
},
"eventVersion": "1.0",
"eventType": "com.pizzastore.pizza.ordercreated",
"type": "outboundEvent",
"contextProperties": {
"tenancy": "odaserviceinstance00",
"specversion": "1.0",
"id": "7a923f09-bff7-4369-8467-0c510e971aaf",
"source": "hello/app",
"time": 1659357000,
"type": "com.pizzastore.pizza.ordercreated",
"channelname": "System_Global_Test",
"version": "1.0",
"userid": "3910088",
"contenttype": "application/json"
}
}
}
Response Raw Message Payload
This is used when a component creates the channel-specific payload itself.
It applies the following properties to the Message Payload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "raw" |
Yes |
payload |
The channel-specific payload | JSONObject | Yes |
Response Session Closed Message Payload
This represents a session closed message payload. It provides acknowledgement of session closure at the backend.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "sessionClosed" |
Yes |
Response Text Message Payload
This represents a text message.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "text" |
Yes |
text |
Text of the message | string | Yes |
Example
{
"messagePayload": {
"type": "text",
"text": "What do you want to do?",
"actions": [
{
"type": "postback",
"label": "Order Pizza",
"postback": {
"state": "askAction",
"action": "orderPizza"
}
},
{
"type": "postback",
"label": "Cancel A Previous Order",
"postback": {
"state": "askAction",
"action": "cancelOrder"
}
}
]
},
"userId": "guest"
}
Response Text Stream Message Payload
This represents a streaming text response that is delivered in chunks
It applies the following properties to the Response Message Payload
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "texStream" |
Yes |
aggregateText |
Aggregated text delivered in the stream till the current chunk | string | Yes |
streamId |
ID for the stream. Chunks of the same stream have same streamId | string | Yes |
streamState |
Stream state of the current stream chunk | "start" , "running" , "end" |
Yes |
text |
Partial text delivered in the current chunk | string | Yes |
Response Form Message Payload
Represents a message that returns the results of a query in a form that's read only. The message consists of an array of form results. Each form result contains a fields
array with key-value pairs that represent a field.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "form" |
Yes |
forms |
An array of form results. Each result contains a fields array that represents the form fields. |
Array<Form> | Yes |
formColumns |
A number suggesting the number of columns in which the fields of the form should be grouped. | 1, 2 | Yes |
paginationInfo |
The paging information for the results in the form | PaginationInfo | No |
Example JSON
{
"type":"form",
"headerText":"A-Team",
"forms":[
{
"fields":[
{
"displayType":"text",
"label":"First Name",
"alignment":"left",
"value":"Aaron"
},
{
"displayType":"text",
"label":"Last Name",
"alignment":"left",
"value":"Adams"
},
{
"displayType":"text",
"label":"Title",
"alignment":"left",
"value":"Demo Builder"
},
{
"displayType":"text",
"label":"Phone",
"alignment":"left",
"value":"1234567890"
},
{
"linkLabel":"Open Link",
"displayType":"link",
"label":"Contact",
"alignment":"left",
"value":"https://www.example.com/in/aaron-adams-4862752"
},
{
"displayType":"text",
"label":"Bio",
"alignment":"left"
}
]
},
{
"fields":[
{
"displayType":"text",
"label":"First Name",
"alignment":"left",
"value":"Bob"
},
{
"displayType":"text",
"label":"Last Name",
"alignment":"left",
"value":"Brown"
},
{
"displayType":"text",
"label":"Title",
"alignment":"left",
"value":"Multi-lingual Expert"
},
{
"displayType":"text",
"label":"Phone",
"alignment":"left",
"value":"1234567890"
},
{
"linkLabel":"Open Link",
"displayType":"link",
"label":"Contact",
"alignment":"left",
"value":"https://www.example.com/in/Bobbrown"
},
{
"displayType":"text",
"label":"Bio",
"alignment":"left",
"value":"Bob is a member of the cloud architects team which is specialized in enterprise mobility and cloud development. Bob has been directly involved with Oracle middleware since 2005 during which he held different roles in managing highly specialized teams."
}
]
},
{
"fields":[
{
"displayType":"text",
"label":"First Name",
"alignment":"left",
"value":"Charlie"
},
{
"displayType":"text",
"label":"Last Name",
"alignment":"left",
"value":"Chase"
},
{
"displayType":"text",
"label":"Title",
"alignment":"left",
"value":"Flow Builder"
},
{
"displayType":"text",
"label":"Phone",
"alignment":"left",
"value":"1234567890"
},
{
"linkLabel":"Open Link",
"displayType":"link",
"label":"Contact",
"alignment":"left",
"value":"https://www.example.com/in/Charlie-chase-97a418"
},
{
"displayType":"text",
"label":"Bio",
"alignment":"left",
"value":"Charlie is a member of the enterprise mobility team. Charlie has 20+ years experience with custom development. Charlie is an expert on mobile cloud services and development tools. He is the creator of productivity tools. His latest passion is building chatbots with a minimum amount of custom code."
}
]
}
],
"formColumns":2,
"paginationInfo":{
"currentRangeSize":3,
"rangeStart":0,
"nextRangeSize":2,
"hasPrevious":false,
"hasNext":true,
"totalCount":5,
"rangeSize":3,
"status":"Showing 1-3 of 5 items"
},
"globalActions":[
{
"postback":{
"variables":{},
"action":"system.showMore"
},
"label":"Show More",
"type":"postback"
}
]
}
Response Table Message Payload
Represents a message that returns the results of a query in table form The message consists of an array of headings and an array of rows. The rows themselves contain a fields
array that represents individual cells.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "table" |
Yes |
headings |
An array of table headings | Array<TableHeading> | Yes |
rows |
An array of table rows. Each row contains a fields array that represents the table cells. |
Array<TableRow> | Yes |
tableTitle |
The table title | string | No |
paginationInfo |
The paging information for the results in the table | PaginationInfo |
No |
Example JSON
{
"type":"table",
"headerText":"A-Team",
"tableTitle": "Document",
"headings":[
{
"width":20,
"label":"First Name",
"alignment":"left"
},
{
"width":20,
"label":"Last Name",
"alignment":"left"
},
{
"width":35,
"label":"Title",
"alignment":"left"
},
{
"width":25,
"label":"Phone",
"alignment":"right"
}
],
"rows":[
{
"fields":[
{
"displayType":"text",
"width":20,
"label":"First Name",
"alignment":"left",
"value":"Aaron"
},
{
"displayType":"text",
"width":20,
"label":"Last Name",
"alignment":"left",
"value":"Adams"
},
{
"displayType":"text",
"width":35,
"label":"Title",
"alignment":"left",
"value":"Demo Builder"
},
{
"displayType":"text",
"width":25,
"label":"Phone",
"alignment":"right",
"value":"1234567890"
}
]
},
{
"fields":[
{
"displayType":"text",
"width":20,
"label":"First Name",
"alignment":"left",
"value":"Bob"
},
{
"displayType":"text",
"width":20,
"label":"Last Name",
"alignment":"left",
"value":"Brown"
},
{
"displayType":"text",
"width":35,
"label":"Title",
"alignment":"left",
"value":"Multi-lingual Expert"
},
{
"displayType":"text",
"width":25,
"label":"Phone",
"alignment":"right",
"value":"1234567890"
}
]
},
{
"fields":[
{
"displayType":"text",
"width":20,
"label":"First Name",
"alignment":"left",
"value":"Charlie"
},
{
"displayType":"text",
"width":20,
"label":"Last Name",
"alignment":"left",
"value":"Chase"
},
{
"displayType":"text",
"width":35,
"label":"Title",
"alignment":"left",
"value":"Flow Builder"
},
{
"displayType":"text",
"width":25,
"label":"Phone",
"alignment":"right",
"value":"1234567890"
}
]
},
{
"fields":[
{
"displayType":"text",
"width":20,
"label":"First Name",
"alignment":"left",
"value":"David"
},
{
"displayType":"text",
"width":20,
"label":"Last Name",
"alignment":"left",
"value":"Davidson"
},
{
"displayType":"text",
"width":35,
"label":"Title",
"alignment":"left",
"value":"Machine Learning Expert"
},
{
"displayType":"text",
"width":25,
"label":"Phone",
"alignment":"right",
"value":"1234567890"
}
]
},
{
"fields":[
{
"displayType":"text",
"width":20,
"label":"First Name",
"alignment":"left",
"value":"Eric"
},
{
"displayType":"text",
"width":20,
"label":"Last Name",
"alignment":"left",
"value":"Eastman Junior"
},
{
"displayType":"text",
"width":35,
"label":"Title",
"alignment":"left",
"value":"Docker Expert"
},
{
"displayType":"text",
"width":25,
"label":"Phone",
"alignment":"right",
"value":"1234567890"
}
]
}
],
"paginationInfo":{
"currentRangeSize":5,
"rangeStart":0,
"nextRangeSize":-3,
"hasPrevious":false,
"hasNext":false,
"totalCount":5,
"rangeSize":8,
"status":"Showing 1-5 of 5 items"
}
}
Response Table-Form Message
This message combines the Table
and Form
message types. It represents a message that returns the results of a query in the form of a table. Each each row of the table has a read-only form in addition to the row information.
It applies the following properties to the Response Message
:
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "tableForm" |
Yes |
headings |
An array of table headings | Array<TableHeading> | Yes |
rows |
An array of table rows each themselves containing an array of fields representing the table cells | Array<TableRow> | Yes |
forms |
An array of form results that correspond to each table row. Each form contains a fields array that represents the form fields. |
Array<Form> | Yes |
paginationInfo |
The paging information for the results in the table form | PaginationInfo | Yes |
formColumns |
The number suggesting the number of columns in which the fields of the form should be grouped. | 1, 2 | No |
showFormButtonLabel |
Label of the button used to show the form layout for a specific row. | string | No |
tableTitle |
The table title | string | No |
Example JSON
{
"type":"tableForm",
"headerText":"A-Team",
"tableTitle":"Document",
"headings":[
{
"width":47,
"label":"First Name",
"alignment":"left"
},
{
"width":47,
"label":"Last Name",
"alignment":"left"
}
],
"rows":[
{
"fields":[
{
"displayType":"text",
"label":"First Name",
"alignment":"left",
"value":"Aaron"
},
{
"displayType":"text",
"label":"Last Name",
"alignment":"left",
"value":"Adams"
}
]
},
{
"fields":[
{
"displayType":"text",
"label":"First Name",
"alignment":"left",
"value":"Bob"
},
{
"displayType":"text",
"label":"Last Name",
"alignment":"left",
"value":"Brown"
}
]
},
{
"fields":[
{
"displayType":"text",
"label":"First Name",
"alignment":"left",
"value":"Charlie"
},
{
"displayType":"text",
"label":"Last Name",
"alignment":"left",
"value":"Chase"
}
]
}
],
"forms":[
{
"title":"View details Aaron Adams",
"fields":[
{
"displayType":"text",
"label":"Title",
"alignment":"left",
"value":"Demo Builder"
},
{
"displayType":"text",
"label":"Phone",
"alignment":"left",
"value":"1234567890"
},
{
"linkLabel":"Open Link",
"displayType":"link",
"label":"Contact",
"alignment":"left",
"value":"https://www.example.com/in/Aaron-adams-4862572"
},
{
"displayType":"text",
"label":"Bio",
"alignment":"left"
}
]
},
{
"title":"View details Bob Brown",
"fields":[
{
"displayType":"text",
"label":"Title",
"alignment":"left",
"value":"Multi-lingual Expert"
},
{
"displayType":"text",
"label":"Phone",
"alignment":"left",
"value":"1234567890"
},
{
"linkLabel":"Open Link",
"displayType":"link",
"label":"Contact",
"alignment":"left",
"value":"https://www.example.com/in/Bobbrown"
},
{
"displayType":"text",
"label":"Bio",
"alignment":"left",
"value":"Bob is a member of the cloud architects team which is specialized in enterprise mobility and cloud development. Bob has been directly involved with Oracle middleware since 2005 during which he held different roles in managing highly specialized teams."
}
]
},
{
"title":"View details Charlie Chase",
"fields":[
{
"displayType":"text",
"label":"Title",
"alignment":"left",
"value":"Flow Builder Fanatic"
},
{
"displayType":"text",
"label":"Phone",
"alignment":"left",
"value":"1234567890"
},
{
"linkLabel":"Open Link",
"displayType":"link",
"label":"Contact",
"alignment":"left",
"value":"https://www.example.com/in/Charlie-chase-97a418"
},
{
"displayType":"text",
"label":"Bio",
"alignment":"left",
"value":"Charlie is a member of the enterprise mobility team. Charlie has 20+ years experience with custom development. Charlie is an expert on mobile cloud services and development tools. He is the creator of productivity tools. His latest passion is building chatbots with a minimum amount of custom code."
}
]
}
],
"formColumns":2,
"paginationInfo":{
"currentRangeSize":3,
"rangeStart":0,
"nextRangeSize":2,
"hasPrevious":false,
"hasNext":true,
"totalCount":5,
"rangeSize":3,
"status":"Showing 1-3 of 5 items"
},
"actions":[
{
"postback":{
"variables":{
},
"action":"system.showMore"
},
"label":"Show More",
"type":"postback"
}
],
"footerText":"Tap on a row to see personal details"
}
Response Edit-Form Message Payload
Represents an Editable Form message. The message consists of an array of fields
.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "editForm" |
Yes |
fields |
A list of fields, this can be both read-only and editable fields. One of fields and formRows is required, they are mutually exclusive |
Array<Field> | Yes |
formRows |
A list of rows displayed in the form. One of fields and formRows is required, they are mutually exclusive |
Array<FormRow> | Yes |
errorMessage |
A form-level error message | string | No |
formColumns |
Number of columns used in form layout, defaults to 1 | number | No |
title |
A representative title for the edit form | string | No |
actions |
An array of actions related to the edit form. This array should include a SubmitFormAction |
Array<Action> | No |
channelExtensions |
A set of channel-specific extension properties | JSONObject | No |
The channelExtensions
object can include a replaceMessage
property that's used to replace the previous Edit-Form message. See Replace Previous Edit‑Form for more details on this feature.
Here's an example:
Example JSON
{
"messagePayload": {
"headerText": "Create Expense",
"type": "editForm",
"title": "Fill in the below form",
"fields": [
{
"displayType": "textInput",
"serverErrorMessage": "Invalid Text Input",
"defaultValue": "Expense",
"minLength": 5,
"id": "Subject",
"label": "Subject",
"placeholder": "Enter subject of the expense",
"clientErrorMessage": "Subject is required and must be between 5 and 15 characters",
"maxLength": 15,
"required": true
},
{
"displayType": "textInput",
"defaultValue": "expense",
"multiLine": true,
"id": "Description",
"label": "Description",
"placeholder": "What is expense justification",
"clientErrorMessage": "Description is required",
"required": true
},
{
"displayType": "datePicker",
"defaultValue": "2023-06-07",
"maxDate": "2023-06-22",
"id": "Date",
"label": "Expense Date",
"placeholder": "Pick a date in the past",
"clientErrorMessage": "Expense date is required and must be in the past.",
"required": true
},
{
"displayType": "timePicker",
"defaultValue": "18:58",
"id": "Time",
"label": "Expense Time",
"placeholder": "What time was the expense",
"clientErrorMessage": "Time is required. Please fill a value",
"required": true
},
{
"displayType": "numberInput",
"minValue": 5,
"defaultValue": 6,
"maxValue": 500,
"id": "Amount",
"label": "Amount",
"placeholder": "Enter expense amount",
"clientErrorMessage": "Amount is required and must be between 5 and 500.",
"required": true
},
{
"autoSubmit": true,
"displayType": "toggle",
"defaultValue": "true",
"labelOn": "Yes",
"id": "TipIncluded",
"label": "Tip Included?",
"valueOff": "false",
"labelOff": "No",
"valueOn": "true"
},
{
"displayType": "singleSelect",
"serverErrorMessage": "Invalid Selection",
"defaultValue": "Public transport",
"options": [
{
"label": "Public transport",
"value": "Public transport"
},
{
"label": "Flight",
"value": "Flight"
}
],
"layoutStyle": "list",
"id": "Type",
"label": "Expense Type",
"placeholder": "Select expense type",
"clientErrorMessage": "Expense type is required",
"required": true
},
{
"displayType": "multiSelect",
"defaultValue": [
"Toff van Alphen"
],
"options": [
{
"label": "Toff van Alphen",
"value": "Toff van Alphen"
},
{
"label": "Roger Federer",
"value": "Roger Federer"
}
],
"layoutStyle": "checkboxes",
"id": "Attendees",
"label": "Attendees",
"placeholder": "Select attendees",
"clientErrorMessage": "Please select at least one attendee",
"required": true
}
],
"formColumns": 1,
"actions": [
{
"postback": {
"system.botId": "6803DE12-DAA9-4182-BD54-3B4D431554F4",
"system.flow": "ExpenseFlow",
"system.state": "editFormMapVar"
},
"label": "Submit",
"type": "submitForm"
}
],
"channelExtensions": {
"replaceMessage": "True"
}
},
"source": "BOT",
"userId": "guest"
}
Oracle Digital Assistant Native Client SDK for Web
F26105-43
Release 25.08
September 2025
Copyright © 2018, 2025, Oracle and/or its affiliates.
This tutorial shows you how to create the infrastructure resources that are required to provision Oracle PaaS service instances in Oracle Cloud Infrastructure.
This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited.
If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software, any programs embedded, installed or activated on delivered hardware, and modifications of such programs) and Oracle computer documentation or other Oracle data delivered to or accessed by U.S. Government end users are "commercial computer software" or "commercial computer software documentation" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, the use, reproduction, duplication, release, display, disclosure, modification, preparation of derivative works, and/or adaptation of i) Oracle programs (including any operating system, integrated software, any programs embedded, installed or activated on delivered hardware, and modifications of such programs), ii) Oracle computer documentation and/or iii) other Oracle data, is subject to the rights and limitations specified in the license contained in the applicable contract. The terms governing the U.S. Government's use of Oracle cloud services are defined by the applicable contract for such services. No other rights are granted to the U.S. Government.
This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Epyc, and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services, except as set forth in an applicable agreement between you and Oracle.