49 Oracle Web
The Digital Assistant Client SDK for Oracle Web provides you with a widget that enables you to run a skill in a web page. Using the SDK, you can customize the look and behavior of this widget.
Note:
The Oracle Web Channel doesn't store messages when the client has disconnected from the server. It only delivers messages to connected clients. The SDK does not support multi-device login; it supports only one client per user.What Do You Need?
- An Oracle Web Channel. Creating the channel generates the Channel ID and the Secret Key that you need to initialize the chat app.
- The URL of the Oracle Chat Server.
- The Oracle Web SDK (located under Oracle Native Client SDKs for OCI Native Environments) from Oracle Technology Network’s ODA and OMC download page. Download this ZIP and extract it to your local system. This ZIP includes a user guide that describes the SDK's classes and a sample app that demonstrates many of its features.
Configure the Oracle Web Channel
-
Authentication is enforced using JSON Web Tokens (JWT). The customer's backend server generates the JWT token, which is then passed to the Oracle Web SDK. This token is used for each request to an ODA speech, text, or attachment server.
Note:
To protect access to the channel, the token must always be generated by a remote server. It must never be generated within the client browser.Tip:
This article steps you through running the SDK with an authenticated channel. - Unauthenticated mode – Use the unauthenticated mode when the client can't generate signed JWT tokens, when no authentication mechanism is in place, or when the client widget is already secured and visible to authenticated users.
- Choose Development, then Channels from the menu.
- Choose Users.
- Click Add Channel and then Oracle Web as the channel type.
- Complete the dialog:
- Enter the channel name.
- For authenticated connections:
- Switch on the Client Authentication Enabled toggle to determine whether the SDK is connecting to a client authentication-enabled channel.
- The channel will only communicate with the sites
from the domains that you add as a comma-separated list. For
example,
*.corp.example.com
,*.hdr.example.com
. Entering a single asterisk (*) allows unrestricted access to the channel from any domain. Typically, you'd only enter a single asterisk during development. For production, you would add an allowlist of domains. - In the Max. Token Expiration (Minutes) field, set the maximum amount of time for the JWT token.
- For unauthenticated connections:
- Switch off Client Authentication Enable toggle.
- Enter a comma-separated list of domains that can
access the channel. If the domains in this allowlist includes
asterisks (
*.hdr.example.com
) or if the allowlist is not completely known, then you might consider an authenticated connection.
- Set the Session expiration time.
- Click Create. Oracle Digital Assistant will generate the Channel ID and the Secret Key that you need to initialize the SDK. Keep these close at hand because you'll need them when configuring the HTML page to host the chat widget.
- Route the channel to your skill or digital assistant.
- Switch Channel Enabled to On.
Tutorial: Secure Your Oracle Web SDK Chat
You can get a hands-on look at securing the Web chat widget through this tutorial: Secure Your Oracle Web SDK Chat.
Install the SDK
- In the extracted ZIP file of the downloaded Oracle Web SDK, locate
the
web-sdk.js
file (located in thenative-client-sdk-js
directory). - Save
web-sdk.js
(located in thenative-client-sdk-js
directory of the extracted ZIP) in your project directory. Note the file location, because you'll need it to define the<WebSDK URL>
property in the<script>
tag's code. - Create a JavaScript file with the following function that
initializes the SDK. We call this file
settings.js
in the sample that ships with the SDK.//settings.js var chatSettings = { URI: '<Server URI>', channelId: '<Channel ID>', userId: '<User ID>' }; function initSDK(name) { // If WebSDK is not available, reattempt later if (!document || !WebSDK) { setTimeout(function() { initSDK(name); }, 2000); return; } // Default name is Bots if (!name) { name = 'Bots'; } setTimeout(function() { var Bots = new WebSDK(chatSettings); // Initiate library with configuration var isFirstConnection = true; Bots.on(WebSDK.EVENT.WIDGET_OPENED, function() { if (isFirstConnection) { Bots.connect() // Connect to server .then(function() { console.log('Connection Successful'); }) .catch(function(reason) { console.log('Connection failed'); console.log(reason); }); isFirstConnection = false; } }); window[name] = Bots; }, 0); }
- Define the following properties:
URI
- The URI of the Oracle Chat Server. This is a required property.channelId
- The Channel ID that's generated when you create the Oracle Web channel. This property is required because connects the widget to the underlying skill.userId
- A user ID. You can provide this value, but the SDK will generate this value if you haven't already provided it. This property is optional for unauthenticated connections.
- In your HTML page, reference the locations of both the your JS file
(
setting.js
in the following example) theweb-sdk.js
library and the Web SDK namespace, which is typicallyBots
. Use this namespace to invoke the public APIs. For example, if you set the namespace toBots
, then you invoke the APIs asBots.<API>()
. To find out more about the various functions and events, refer to the user guide (available as both a readme and HTML doc) that's included in the Oracle Web SDK ZIP file.<script src="scripts/settings.js"></script> <script src="scripts/web-sdk.js" onload="initSdk('Bots')"></script>
Import the Library Using the Asynchronous Module Definition API
requirejs(['<path of the web-sdk>'], function(WebSDK) {
var settings = {
URI: '<Server URI>',
channelId: '<Channel ID>',
userId: '<User ID>'
};
Bots = new WebSDK(settings);
Bots.connect();
});
Import the Library Dynamically with JavaScript
function fetchSDK(src, onloadFunction, name) {
var script = document.createElement('script');
script.type = 'application/javascript';
script.async = true; // load the script asynchronously
script.defer = true; // fallback support for browsers that does not support async
script.onload = function() {
onloadFunction(name);
};
document.head.appendChild(script);
script.src = src;
}
fetchSDK('<path of the web-sdk>', initSDK, '<WebSDK namespace>');
Configure Client Authentication
In addition to using lists of allowed domains, client authentication is enforced by signed JWT tokens.
The token generation and signing must be done by the client in the backend server (
preferably after user/client authentication) which is capable of maintaining the
keyId
and keySecret
safe.
When the SDK needs to establish a connection with the ODA server, it first requests a JWT token from the client and then sends it along with the connection request. The ODA server validates the token signature and obtains the claim set from the JWT payload to verify the token to establish the connection.
clientAuthEnabled: true
must be passed in the SDK settings
parameter, and a token generator function must be passed as the second parameter. The
function must return a Promise, which is resolved to return a signed JWT token
string.//settings.js
var chatSettings = {
URI: '<Server URI>',
clientAuthEnabled: true
};
function generateToken() {
return new Promise(function(resolve) {
fetch('https://yourbackend.com/endpointToGenerateJWTToken')
.then(function(token) {
resolve(token);
})
.catch(function(error) {
console.log('Token generation error:', error);
});
});
}
function initSDK(name) {
// If WebSDK is not available, reattempt later
if (!document || !WebSDK) {
setTimeout(function() {
initSDK(name);
}, 2000);
return;
}
// Default name is Bots
if (!name) {
name = 'Bots';
}
setTimeout(function() {
var Bots = new WebSDK(chatSettings, generateToken); // Initiate library with configuration
var isFirstConnection = true;
Bots.on(WebSDK.EVENT.WIDGET_OPENED, function() {
if (isFirstConnection) {
Bots.connect() // Connect to server
.then(function() {
console.log('Connection Successful');
})
.catch(function(reason) {
console.log('Connection failed');
console.log(reason);
});
isFirstConnection = false;
}
});
window[name] = Bots;
}, 0);
}
The JWT Token
iat
- issued at timeexp
- expiry timechannelId
- channel IDuserId
- user ID
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzY3NDcyMDUsImV4cCI6MTU3Njc1MTExNywiY2hhbm5lbElkIjoiNDkyMDU5NWMtZWM3OS00NjE3LWFmOWYtNTk1MGQ2MDNmOGJiIiwidXNlcklkIjoiSm9obiIsImp0aSI6ImQzMjFjZDA2LTNhYTYtNGZlZS05NTBlLTYzZGNiNGVjODJhZCJ9.lwomlrI6XYR4nPQk0cIvyU_YMf4gYvfVpUiBjYihbUQ
- Header:
{ "typ": "JWT", "alg": "HS256" }
- Payload:
{ "iat": 1576747205, "exp": 1576748406, "channelId": "4920595c-ec79-4617-af9f-5950d603f8bb", "userId": "John" }
Customize the Chat Widget
Tip:
This article gets you acquainted with the various customization properties.Network Configuration
scripts/settings.js
file.
Property Name | Description | Required? | Default Value |
---|---|---|---|
URI |
The URL of the Oracle Chat Server | Yes | N/A |
channelId |
The Channel ID of the Oracle Web Channel | Yes | N/A |
userId |
A unique identifier for the user. If you don't provide this, Oracle Digital Asssistant generates one. | No | A randomly generated value |
clientAuthEnabled |
Determines whether the SDK connectes to a channel
where client authentication has been enabled. As described in Configure Client Authentication, you set this to true to connect
to channel with authentication enabled and use the JWT
token.
|
Yes | false |
Feature Flags
- Secure connections
- Pill-shaped action buttons
- Audio narration of skill responses.
- Attachment sharing
- Disabling clicks on previous (out of focus) messages
- Autocomplete user input
<script>
var chatWidgetSettings = {
enableTimestamp: true,
showConnectionStatus: true,
conversationBeginPosition: 'bottom',
openChatOnLoad: true,
position: {bottom: '2px', right: '2px'},
displayActionAsPills: true,
initUserHiddenMessage: 'Hello',
embedded: true,
targetElement: 'chat-container',
embedTopScrollId: 'top-text',
customHeaderElementId: 'custom-header',
botButtonIcon: 'images/bot-button.png',
logoIcon: 'images/bot-white.png',
botIcon: 'images/bot-green.png',
personIcon: 'images/user-icon.png',
URI: YOUR_URI,
channelId: YOUR_CHANNELID,
};
...
</script>
Tip:
Starting with Release 22.08, the chat widget configuration settings schema is available in a standard JSON schema format through a CDN (https://static.oracle.com/cdn/oda/22.8.0/settings-schema.json
),
which can be used to create dynamic configuration screens.
Property Name | Description | Required? | Default Value |
---|---|---|---|
defaultGreetingTimeout |
The default timeout, in seconds, after which a default greeting message displays. | No | 5 |
defaultWaitMessageInterval |
The default interval, in seconds, that the default wait message displays. | No | 5 |
disablePastActions |
Disables interactions (button clicks) with the
messages that users have already interacted with. The allowed values
are all , none , or
postback . The behavior enabled by this property
is independent of the digital assistant-level configuration for
disabling the selection of past actions. You
need to set the two separately.
|
No | all |
displayActionsAsPills |
Displays pill-shaped action buttons. | No | false |
enableAttachment |
Configures attachment sharing. | No | true |
enableAttachmentSecurity |
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 an
authorization header.
Do not enable this setting if the skill connects to an ODA instance that's Version 20.08 or runs on any version prior to 20.08. This property only applies to client auth-enabled connections to Versions 20.12 and higher of the ODA platform. |
No | false |
enableAutocomplete |
Set to true to enable the skill to
autocomplete the user request using the idealized user requests
entered as Autocomplete Suggestions in the Create Intent page. The skill ouputs these
suggestions when the user enters three or more characters. It also
sets off the words in the user input that match the suggested
phrases in bold.
|
No | false |
enableBotAudioResponse |
Configures the skill responses. The skill responses
are read aloud by the Web API. To select the voice for reading
messages from a skill or digital assistant aloud, set this proprety
to true and then define the skillVoices
array.
|
No | false |
enableClearMessage |
Enables the clear message button in the chat widget header. | No | false |
enableDraggableButton |
Enables users to drag the launch button out of the way when it's blocking content on the web page. This feature also works for Android and iOS Safari browsers. | No | false |
enableHeadless |
Enables you to use the Oracle Web SDK without its UI so that you can develop your own chat UI. | No | false |
enableLocalConversationHistory |
Enables the previous conversation that's associated
with a given userId to be loaded in the browser
when the widget has been initialized.
|
No | false |
enableLongPolling |
Use HTTP requests when the websocket fails to connect. | No | false |
enableSecureConnection |
Configures secure communication
(https v. http and
wss v. ws ).
|
No | true |
enableSpeech |
When set to true , this property
enables the microphone for voice recognition. For
example:
|
No | false |
enableSpeechAutoSend |
When set to true (the default), the
user's speech response is automatically sent to the chat server (and
displays as a sent message in the chat widget). When set to
false , the user's speech response is rendered
in the message text field before it's sent to the chat server so
that the user can modify it before sending it manually, or delete
the message.
|
No | true |
enableTimestamp |
Enables the timestamp for messages and the "read"
symbol, which is a tick mark ('✓'). Use readMark to
change this symbol. This feature is deprecated in Release
22.02.
|
No | true |
focusOnNewMessage |
Sets the focus on either the user input field, or on
the first action button in a message when a new message is
received.
|
No | input |
multiLangChat |
Enables the chat widget to both detect a user’s
language and allow the user to select a preferred language from a
dropdown menu in the header. You define the menu with an object that
defines the primary language and an array of two or more language
tags (the supportedLangs array, described in Multi-Lingual Chat).
|
No | N/A |
name |
The name for the instance. Provides a namespace to the instance and is used as prefix for the CSS classnames and element IDs. | No | oda-chat |
openChatOnLoad |
Expands the chat widget when the page is loaded. | No | false |
openLinksInNewWindow |
Overrides the user's browser preference by opening links in a new window. This setting applies to all links present in the conversation, including action buttons, fallback links for attachments, and card links. | No | false |
showConnectionStatus |
Enables the connection status to display in the chat widget header. | No | false |
showPrevConvStatus |
Displays status messages at the end of older messages from previous conversations. | No | true |
showTypingIndicator |
Displays a chat bubble when waiting for a response. | No | true |
Functionality
- Imitate a skill-initiated conversation.
- Embed content to the top and bottom of the chat window that either scrolls, or is stationary (sticky).
- Set the locale.
- Set debug mode.
- Set the locale and voice for speech synthesis.
Property Name | Description | Required? | Default Value |
---|---|---|---|
customHeaderElementId |
Names the ID of the <div>
element that's added to the header of the chat widget.
|
No | N/A |
delegate |
An object that sets a delegate to receive callbacks
before certain events occur in a conversation. The
delegate object allows code to interact with
both user messages and skill responses before messages are sent and
responses get displayed.
|
No | N/A |
embedBottomScrollId |
The ID of the element that's added as the scrolling content at the bottom of the chat. Use this property to add custom content in the chat widget's conversation view. | No | N/A |
embedBottomStickyId |
The ID of the element used for the sticky content that appears at the bottom of the chat. Use this property to add custom content in the chat widget's conversation view. | No | N/A |
embedded |
Setting this to true , activates the
embedded mode for the chat widget. In
addition to setting this property, you need to name the
div element that houses the widget in the
targetElement property.
|
No | false |
embeddedVideo |
Enables the embedding of YouTube and Oracle Hub Vidoe links in a text message. | No | false |
embedTopscrollId |
The ID of the div element that's
added as a scrolling content at the top of the chat widget.
|
No | N/A |
embedTopStickyId |
The ID of the div element that's
used for the sticky content that appears at the top of the chat
widget. Use this property to add custom content in the chat widget's
conversation view. For example, the top-text
div element in the following snippet is referenced
as embedTopStickyId: 'top-text' :
The
Web SDK tutorial describes how to configure
this property and set scrolling and non-scrolling for chat widget
elements.
|
No | N/A |
enableAgentSneakPreview |
Sends the user-entered text along with typing status to the agent. | No | false |
enableAutocompleteClientCache |
Enables client side caching to minimize server calls when the autocomplete feature is in use. | No | false |
enableDefaultClientResponse |
When set to true , the client
displays default responses when the skill response has been delayed,
or when there's no response from the skill.
|
No | false |
enableEndConversation |
Enables the user to end the conversation and reset the chat session. It also clears the local conversation history, disconnects from the chat server and minimizes the widget | No | true |
enableHeaderActionCollapse |
Collapses the header actions into a menu button if the icon count is more than two. | No | true |
enableSendTypingStatus |
Sends the typing status of the user to the live agent. | No | false |
enableTabsSync |
Synchronizes conversation messages across different
tabs for a given userId and
channelId .
|
No | true |
i18n |
An object that contains locale fields. Each locale
maintains i18n key-value pairs for the text strings
used in the widget.
|
No | {'en-us':{…}} For
example:
|
initBotAudioMuted |
Initializes the skill message utterance in muted
mode. This feature can only be activated when you set
enableBotAudioResponse to
true .
|
No | true |
initMessageOptions |
Whereas initUserHiddenMessage sends
the initial "hidden" message only after the client has connected to
the skill and the chat widget has been expanded, you can use this
setting to send messages as soon as the client has connected to the
skill, regardless of whether the widget is expanded or not. This
setting accepts an object that has a sendAt
property. The sendAt property can have one of the
two values: 'init' , or 'expand' .
If you set 'init' , then the init messages are sent
as soon as connection is made. If you set 'expand' ,
then the init messages are sent only when the widget is expanded. In
the following snippet, the message is set when the connection is
established because of sendAt:
'init' : Bear
in mind that billing starts when the init message has been sent,
even if the widget is still closed (as would be the case with
sendAt: 'init ').
|
||
initUserHiddenMessage |
A message that's used to initiate a conversation.
This message, can be a text string or a message payload. For
example: initUserHiddenMessage: 'Hi' . These
messages are not dependent on the user history. This message is sent
in every session after the client has connected to the skill and the
chat widget has been expanded. To send the first message only when
the conversation history is empty, you must bind event listeners
using the Bots.on() method. For example, you can
accomplish this by binding the WIDGET_OPENED and
NETWORK events, which are described
in the SDK docs.
|
No | N/A |
initUserProfile |
Updates the user profile before the start of a
conversation. The format of the profile payload must be {
profile: {...} } . For
example: This
function updates the user context after the client is connected to
the skill and the chat widget has been expanded. As a result, the
user profile can be reflected in the first response message to the
user. For example, the skill can greet the user with a message like
"Welcome back, John Smith! Your last order was a medium pepperoni
pizza." These messages are sent after the client has connected to
the skill and the chat widget is expanded.These user profile
messages are sent after the client has connected to the skill and
the chat widget is expanded. A user profile message is still sent
before the initial "hidden" message if
initUserHiddenMessage is also passed.
You can only pass the |
No | N/A |
isDebugMode |
Enables debug mode. | No | false |
linkHandler |
An object that overrides the configuration for
handling the clicks on the links that are embedded in the skill's
responses. There are two ways that this object handles links:
target , which accepts a string, and
onclick , which accepts a function. You can set
either target or onclick , but not
both. When you want all links to open in a WebView, pass linkHandler: { target:
'oda-chat-webview' } .
|
No |
|
locale |
The default locale for the widget's text strings. The
locale passed during initialization has a higher preference over
users’ browser locales. If there isn’t an exact match, then the SDK
attempts to match the closest language. For example, if the locale
is 'da-dk' , but i18n translations are provided only
for 'da' , then the 'da'
translation is used. In absence of translations for passed locale,
translations are searched for and applied for the browser locales.
In absence of translations for any of them, the default locale,
'en' is used for translations.
|
No | en-us |
messageCacheSizeLimit |
The maximum number of messages that get save in
localStorage at a time.
|
No | 2000 |
readMark |
Sets the symbol that denotes that a skill's messages
have been read. By default, this is indicated by a tick mark ('✓')
when enableTimestamp is set to
true , but you can substitute another symbol by
defining this property. This symbol, whether the default or custom,
can only accompany the timestamp, so it is hidden when
enableTimestamp is set to
false . The read mark does not display for
absolute timestamps.
|
No | A tick mark
( ) |
reconnectMaxAttempts |
The number of attempts made by the chat widget to reconnect when the initial connection fails. | No | 5 |
shareMenuItems |
The menu items in the share popup menu. This property
accepts an array with string values that are mapped to menu
items:
['audio', 'file'] , for example). All of the
menu items are available when the array is empty, when the items in
the array are incorrect (['audio', 'visuil'] , or
when shareMenuItems has not been defined.
|
No |
|
skillVoices |
An array containing the preferred voices that used
for narrating responses. Each item in the array should be an object
with two fields: lang , and name .
name is optional. The first item that matches a
voice that’s available in the system will be used for the narration.
|
No | System language |
speechLocale |
The expected locale of the user's speech that's used
for voice recognition. US English ('en-US' ) is the
default locale. The other supported locales are: Australian English
('en-au' ), UK English
('en-uk' ), French ('fr-fr' ),
German ('de-de' ), Italian
('it-it' ), Indian-Hindi (hi-in ),
Indian-English (en-in ), Brazilian Portuguese
('pt-br' ), and Spanish
('es-es' ). The speech locale can be set
dynamically by calling the
setSpeechLocale('<locale>') API. Voice
recognition will not work if an unsupported locale has been
passed.
|
No | 'en-us' |
storageType |
The web storage mechanism that's used to store the
conversation history for users whose userId is
passed by the host app. The supported values are
'localStorage' and
'sessionStorage' . Anonymous users’
conversations are always stored in sessionStorage
and are deleted automatically after the browser session has
ended.
|
No | 'localStorage' |
targetElement |
Names the div element where the chat
widget gets embedded in the web page. The
chat-container
div element in the following snippet is referenced
as targetElement:
'chat-container' :
Check out the Web SDK tutorial to find out how to add and
style the div element.
|
No | N/A |
theme |
The primary layout theme. Three themes are available:
'default' , 'redwood-dark' , and
'classic' .
|
No | default |
timestampFormat |
Formats the delivery timestamp that accompanies
messages. Accepts values in a DateTimeFormat
options object or as a pattern string as described
in Customize the Timestamp.
|
No |
|
timestampMode |
Selects the timestamp display mode as either absolute
timestamps that appear on each message, or as a relative timestamp
that appears only on the latest message.
|
No | default (for absolute timestamps),
or relative .
|
ttsService |
Injects a custom speech synthesis service for uttering the skill responses. | No | The text-to-speech (TTS) service on the user device. |
typingIndicatorTimeout |
Sets the number of seconds after which the typing indicator is automatically removed if the chat widget has not yet received the response. | No | 20 |
typingStatusInterval |
Sets the interval, in seconds, to throttle the typing status that's sent to the live agent. | No | 3 |
webViewConfig |
Customizes the in-widget WebView. | No | { referrerPolicy:
'no-referrer-when-downgrade', closeButtonType: 'icon', size:
'tall' } |
Read More and Read Less Buttons for Multi-Paragraph Skill Responses
You can optimize the user experience for multi-paragraph skill messages by
adding Read More and Read Less buttons.
Description of the illustration readmore.png
You can add the client-side code for these buttons, which hide and show
paragraphs, using the delegate
object and custom functions.
- In
settings.js
, define adelegate
object with abeforeDisplay
callback function in thevar chatWidgetSettings
declaration:
If the message is of typedelegate: { beforeDisplay: function (message) { var messagePayload = message && message.messagePayload; if (messagePayload.type === 'text') { messagePayload.text = splitParagraph(messagePayload.text); } return message; } }
text
,beforeDisplay
calls the customsplitParagraph
function to split the text by the first paragraph. - Declare the variables for the custom
splitParagraph
andtoggleParagraph
view functions:var PREFIX_DOTS = 'dots_'; var PREFIX_MORE = 'more_'; var PREFIX_TOGGLE = 'toggle_button';
- Add the
splitParagraph
function expression and thetoggleParagraphView
function.splitParagraph
is an IIFE (Immediately Invoked Function Expression) that isolates theglobalIDCounter
variable so that it can only be accessed by thesplitParagraph
function. The code identifies a paragraph ("\n\n"
) and splits the text accordingly. It then adds three dots (…) to indicate that there is more text to display and a Read More button to unhide the remaining text.var splitParagraph = (function () { var globalIDCounter = 0; return function splitParagraph(text) { var paragraphs = text.split('\n\n'); if (paragraphs.length > 1) { var HTMLText = '<p>' + paragraphs[0] + '<span id="' + PREFIX_DOTS + globalIDCounter + '">...</span></p>' + '<span id="' + PREFIX_MORE + globalIDCounter + '" class="more">'; for (var i = 1; i < paragraphs.length; i++) { HTMLText += '<p>' + paragraphs[i] + '</p>'; } HTMLText += '</span><button id="' + PREFIX_TOGGLE + globalIDCounter + '" class="readMore" onclick="toggleParagraphView(' + globalIDCounter + ')">Read More</button>'; globalIDCounter++; return HTMLText; } else { return text; } } })(); function toggleParagraphView(elemID) { var dots = document.getElementById(PREFIX_DOTS + elemID); var textMore = document.getElementById(PREFIX_MORE + elemID); var buttonToggle = document.getElementById(PREFIX_TOGGLE + elemID); if (!dots || !textMore || !buttonToggle) { return; } if (dots.style.display === 'none') { dots.style.display = 'inline'; buttonToggle.innerText = 'Read More'; textMore.style.display = 'none'; } else { dots.style.display = 'none'; buttonToggle.innerText = 'Read Less'; textMore.style.display = 'inline'; } }
- You can optionally style the Read More and Read Less buttons. The
CSS includes a
display:none
style to show or hide buttons according to the state of the long text display.<style> .readMore { color: #fff !important; background-color: red; font-size: 12pt; padding: 4px; outline: 0; -moz-outline: 0; border: 0; } .readMore:hover { color: #fff !important; background-color: #606060 !important; } .more { display: none; } </style>
Layout
- Set the position of the widget within the web page.
- Set chat widget's dimensions, colors, and font style.
- Set the padding for the messages within the widget.
- Set the position of the notification badge icon with respect to bot button.
- Set the starting position for the conversation within the widget.
<script>
var chatWidgetSettings = {
URI: YOUR_URI,
channelId: YOUR_CHANNELID,
font: '14px "Helvetica Neue", Helvetica, Arial, sans-serif', //layout modification property
height: '60vh', //layout modification property
width: '20vw', //layout modification property
"colors": { //custom colors property
"branding": "#01538A",
"text": "#B20637"
},
}
...
</script>
Property | Description | Required? | Default Value |
---|---|---|---|
actionsLayout |
Sets the layout direction for the local actions.
When you set this as horizontal , these buttons are
laid out horizontally and will wrap if the content
overflows.
|
No | vertical |
badgePosition |
The position of the badge icon with respect to the icon button. | No | {"top": "0", "right": "0"} |
cardActionsLayout |
Sets the layout direction for the card actions. When
you set this as horizontal , these buttons are laid
out horizontally and will wrap if the contents.
|
No | vertical |
colors |
The colors used in the chat widget. | No | {"branding": "#1B8FD2", "text": "#212121",
"textLight": "#737373"} |
conversationBeginPosition |
The starting position for conversation in the widget.
If set to top , the first messages appear at the top
of the widget. If set to bottom , then the
conversation starts at the bottom.
|
No | bottom |
font |
The font used in the chat widget. | No | 16px "Oracle Sans", -apple-system,
BlinkMacSystemFont, "Segoe UI", "Helvetica Neue |
fontFamily |
The font family used for all of the text in the chat
widget. This setting precedence over the font
configuration.
|
No | "Oracle Sans", -apple-system,
BlinkMacSystemFont, "Segoe UI", "Helvetica
Neue" |
fontSize |
The font size to use for the header,bubble, and
footer text in the widget. This setting takes precedence over the
font configuration.
|
No | 16px |
globalActionsLayout |
Sets the layout direction for the global actions. If set 'horizontal' the buttons are laid horizontally and will wrap if the content overflows. | No | vertical |
height |
The height of a chat width as set by one of the <length> data type values. | No | 70vh |
messagePadding |
The padding around messages in the chat widget. | No | 15px |
position |
The placement of the chat widget in the browser window. This should be passed as a JSON object. | No | {bottom: '20px', right:
'20px'} |
width |
The width of the chat widget as set to one of the <length> data type values. | No | 30vw |
Custom Header Button Icons



colors.headerButtonFill
property in the initial settings.
Note:
The color customization may not work for all SVGs, as they can be multi-colored or have their own stroke and fill colors.Icon | Function | Feature Flag | Customization |
---|---|---|---|
Clear Message | Clears both the current and older messages in the conversation. | enableClearMessage: true |
'<image URL | SVG string>' |
Audio response | Toggles the audio of skill responses as they are received. Because this a toggle button, it has two states, utterance on, where responses are spoken, and utterance off, where responses are not spoken. | enableBotAudioResponse:
true |
|
Close | Collapses the widget and displays the launch button
![]() |
None: This icon is always enabled in the chat widget. It's not displayed in the embedded mode. | closeIcon : '<image URL | SVG
string>' |
Custom Colors
- You can pass the
colors
config:colors: { "branding": "#e00", "text": "#545454" },
- Or you can use CSS variables defined on the chat wrapper
(
.oda-chat-wrapper
):.oda-chat-wrapper { --color-branding: '#e00'; --color-text: '#545454'; } }
Tip:
We recommend changing colors using CSS variables.CSS Variable | Key | Description |
---|---|---|
N/A | recognitionViewBackground |
The background color for the view where the recognized
text displays when users activate the voice mode. If you don't
define this color, then the color defined for
headerBackground is used instead.
|
N/A | recognitionViewButtonFill |
The SVG fill color for the voice-text mode toggle when users switch to the voice mode. |
N/A | shareMenuText |
The color used for the share menu items. This color overrides the value set for the text key, if passed. |
N/A | userMessageBackgound |
The background color of the bubble used for user messages. |
--color-actions-background |
actionsBackground |
The background color for the action buttons |
--color-actions-background-focus |
actionsBackgroundHover |
The background color of the action buttons on hover |
--color-actions-background-hover |
actionsBackgroundFocus |
The background color for the action buttons when they're in focus. |
--color-actions-border |
actionsBorder |
The border color for the action buttons |
--color-actions-text |
actionsText |
The text color for the action buttons |
--color-actions-text |
actionsTextFocus |
The text color for the action buttons on focus |
--color-actions-text-focus |
actionsTextHover |
The text color for the action buttons on hover |
--color-bot-text |
botText |
The color for the text in a message sent by the skill |
--color-branding |
branding |
The primary color for the widget branding. This color is used as the header background and as the hover color on footer buttons. |
--color-card-background |
cardBackground |
The background color used for a card. |
--color-conversation-background |
conversationBackground |
The color used for the background of the conversation pane. |
--color-error-border |
N/A | The border color of an error message bubble |
--color-error-message-background |
N/A | The background color of an error message bubble |
--color-error-text |
N/A | The description color of an error message content |
--color-error-title |
N/A | The title color of an error message content |
--color-footer-background |
footerBackground |
The color used for the backgound of the footer. |
--color-footer-button-background-hover |
N/A | The background color of the footer buttons on hover |
--color-footer-button-fill |
footerButtonFill |
The fill color of an SVG icon used in the buttons that are located in the chat footer. |
--color-footer-button-fill-hover |
N/A | The fill color of the header footer on hover |
--color-global-actions-background |
globalActionsBackground |
The background color of the global action buttons |
--color-global-actions-background-focus |
globalActionsBackgroundFocus |
The background color of the global action buttons when they're in focus. |
--color-global-actions-background-hover |
globalActionsBackgroundHover |
The background color for the hover over the global action buttons. |
--color-global-actions-border |
globalActionsBorder |
The border color of the global action buttons |
--color-global-actions-text |
globalActionsText |
The text color of the global action buttons |
--color-global-actions-text-focus |
globalActionsTextFocus |
The color of the text in the global action buttons when they're in focus. |
--color-global-actions-text-hover |
globalActionsTextHover |
The color of the text in the global action buttons when users hover over them. |
--color-header-background |
headerBackground |
The background color of the chat widget’s header |
--color-header-button-background-hover |
N/A | The background color of the header buttons on hover |
--color-header-button-fill |
headerButtonFill |
The fill color of the SVG icons used for the buttons in the chat header |
--color-header-button-fill-hover |
N/A | The fill color of the header buttons on hover |
--color-header-text |
headerText |
The color of the chat header title |
--color-input-background |
inputBackground |
The message input field background color in the chat footer |
--color-input-border |
N/A | The border color of the input field |
--color-input-text |
inputText |
The message input text color in the chat footer |
--color-links |
links |
The color for the links that are embedded in skill messages |
--color-user-links |
N/A | The color of the links that are embedded in user messages. |
--color-notification-badge-background |
notificationBadgeBackground |
The background color for the message notification badge |
--color-notification-badge-text |
notificationBadgeText |
The text color for the message count in the notification badge |
--color-popup-background |
N/A | The background color of prompts and popups |
--color-popup-button-background |
N/A | The background color of popup buttons |
--color-popup-button-text |
N/A | The text color of popup buttons |
--color-popup-horizontal-rule |
N/A | The horizonatal rule color for separator for multi-lang chat menu action |
--color-popup-item-background-hover |
N/A | The background color on hover of popup list items |
--color-popup-text |
N/A | The text and icon color of prompts and popups |
--color-rating-star |
ratingStar |
The color that's applied to the rating stars in a
feedback message when users hover over them or select them. If you
do not specify a color, the branding color is used
instead.
|
--color-recognition-view-text |
recognitionViewText |
The color used for the text that's recognized from the
user's voice input. If you don't define this color, then color
defined for text is used instead.
|
--color-table-background |
N/A | The background color of tables |
--color-table-header-background |
N/A | The background color of table headers |
--color-table-separator |
N/A | The separator color of table rows |
--color-table-text |
N/A | The text color of tables |
--color-text |
text |
The text color for messages in the chat widget. |
-color-text-light |
textLight |
The text color of the secondary text in the messages, such as the card descriptions in the chat widget. |
--color-timestamp |
timestamp |
The color for the relative timestamp. |
--color-typing-indicator |
typingIndicator |
The background fill color used for the typing indicator. |
--color-user-message-background |
botMessageBackground |
The color for the background of the skill's response message bubble |
--color-user-text |
userText |
The color for the text in a message sent by the user. |
--color-visualizer |
visualizer |
The color used for the bars in the visualizer graph.
If you don't define this color, then the color defined for
branding is used instead.
|
--color-visualizer-container-background |
visualizerContainerBackground |
The background color for the container of the voice
visualizer that displays when users toggle to the voice mode. If you
don't define this color, then the color defined for
userMessageBackgound is used instead.
|
Note:
You can set an image forconversationBackground
,
headerBackground
, and footerBackground
. These
fields can accept any parameters that can be passed to the CSS background background property. For
example:colors: {conversationBackground: 'no-repeat url("https://images.unsplash.com/photo-1582580470647-e3be5274d6a0?ixlib=rb-1.2.1&auto=format&fit=crop&w=668&q=80")'},
Custom Icons
You can customizes the icons, including the ones for the skill icon, the chat logo icon, and the avatar icons for the skill and user.
Tip:
SVG strings load faster than image assets. They also let you animate the image and change its color. The layout defined for thetheme
property is applied to SVG
strings for attachment, send, and mic buttons, but not for the other image
assets.
icons
property to group all of the custom icons into a single field. The pre-21.10 icons are
still supported, but the values passed with the icons
object take
precedence. All fields within the icons
object support both image
resource paths and raw SVG
strings.var settings = {
URI: '<URI>',
channelId: '<channel ID>',
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>'
},
Property (21.10 Release) | Property (Prior Releases) | Description | SVG String Compatible? |
---|---|---|---|
avatarAgent |
agentAvatar |
For skills integrated with live agents, this icon
displays alongside messages from the live agent. The
avatarBot (or agentAvatar )
appears if this property is not defined.
|
Yes |
avatarbot |
botIcon |
The icon that displays alongside the skill's reponse message. This skill icon only displays if you provide this icon. Otherwise, no icon displays. | Yes |
avatarUser |
personIcon |
The icon that displays alongside user messages. This icon does not display by default: it only displays if you define it. | Yes |
clearHistory |
clearMessageIcon |
The clear message button icon that's located in the widget header | Yes |
close |
N/A | The icon that's displayed for the close button in error message banners, expanded image previews, and the in-widget WebView. | Yes |
collapse |
closeIcon |
The icon for the button, located in the chat view header, that minimizes the chat view. | Yes |
download |
downloadIcon |
The icon used for the attachment download button that appears on each attachment message sent by the skill. | download – Yes
|
error |
errorIcon |
The URL for the image used for the error icon. |
|
expandImage |
expandImageIcon |
The icon used for the image expand control that appears on each image attachment message sent by the skill. | expandImage – Yes
|
fileAudio |
audioIcon |
The audio attachment icon, displayed when attachment source URL is not reachable. |
|
fileGeneric |
fileIcon |
The file attachment icon. |
|
fileImage |
imageIcon |
The image attachment icon, which is displayed when the attachment source cannot be reached. |
|
fileVideo |
videoIcon |
The video attachment icon, which is displayed when the attachment source URL cannot be reached. |
|
keyboard |
keyboardIcon |
The keyboard icon, displayed in button that switches the mode from voice to keyboard mode. | Yes |
launch |
botButtonIcon |
The skill bot button, displayed when the chat widget is minimized. |
|
logo |
logoIcon |
The chat logo icon which is displayed in the header of the chat widget. |
|
mic |
micIcon |
The mic button icon in the footer of the chat widget that appears when | Yes |
rating |
N/A | The icon displayed for the feedback action buttons in the ratings component. For the best user experience for the hover action, pass a filled SVG icon string. | rating – Yes
|
send |
sendIcon |
The send message button icon | Yes |
shareMenu |
attachmentIcon |
The attachment upload icon | Yes |
shareMenuAudio |
N/A | The icon for the audio menu item in the share menu popup. | Yes |
shareMenuFile |
N/A | The icon for the file menu item in the share menu popup. | Yes |
shareMenuLocation |
N/A | The icon for the share menu button in the share menu popup. | Yes |
shareMenuVisual |
N/A | The icon for the image/video menu item in the share menu popup | Yes |
ttsOff |
audioResponseOffIcon |
The icon for the toggle button when audio responses are turned off. | Yes |
ttsOn |
audioResponseOnIcon |
The icon for the toggle button when audio responses are turned on. | Yes |
typingIndicator |
chatBubbleIcon |
The animated icon in conversation pane that indicates a response being sent from skill. | Yes |
chatBubbleIcon
).
Property Name | Description | Required? | Default Value |
---|---|---|---|
chatBubbleIconHeight |
The height of the loading chat bubble icon. | No | 42px |
chatBubbleIconWidth |
The width of the loading chat bubble icon. | No | 56px |
Custom Strings
en-us
. If you don't, then en-us
translations are
displayed for the missing
values."i18n": {
"fr": {
"chatTitle": "Soutien"
},
"en-us": {
"chatTitle": "Support"
},
"es": {
"chatTitle": "Apoyo"
},
"zh-cn": {
"chatTitle": "支持"
}
}
Key | Description | Default Value |
---|---|---|
attachment_audio |
The text that's used for the TTS utterance of an audio attachment. | 'Audio attachment' |
attachment_file |
The text that's used for the TTS utterance of a file attachment. | 'File attachment' |
attachment_image |
The text that's used for the TTS utterance of an image attachment. | 'Image attachment' |
attachment_video |
The text that's used for the TTS utterance of a video attachment. | 'Video attachment' |
attachmentAudioFallback |
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 for downloading the file.
|
Your browser does not support embedded audio.
However you can {0}download it{/0}. |
attachmentVideoFallback |
The fallback message that is displayed in place of
an video attachment if the video can not be rendered by the client.
The text between {0} and {/0} is
set to a link for downloading the file.
|
Your browser does not support embedded video.
However you can {0}download it{/0} .
|
audioResponseOn |
The tooltip that appears when the user hovers over the audio utterance "off" button in header. | Turn audio response on |
avatarAgent |
The alternative text used for the agent icon that displays alongside the agent messages. | Agent icon |
avatarBot |
The alternative text used for the skill icon that's displayed alongside the skill messages. | Bot icon |
avatarUser |
The alternative text used for the user icon that's displayed alongside the user messages. | User icon |
card |
The identifier for the card. | 'Card {0}' . You can localize the
string by placing the ordinal placeholder ({0} )
before or after the word. We will continue to support the
'Card' string used in prior releases that does
not include the ordinal placeholder. For this string, the ordinal is
placed after the word. If you want to mute the utterance, pass an
empty string (card: '' ).
|
cardImagePlaceholder |
The placeholder text that displays while the card image is fetched and loaded. | Loading image |
cardImagePlaceholder |
The placeholder text that displays while the card image is fetched and loaded. | Loading image |
cardNavNext |
The label for the card navigation button for displaying the next card in a horizontal layout. | Next card |
cardNavPrevious |
The label for the card navigation button for displaying the previoust card in a horizontal layout. | Previous card |
chatSubtitle |
Sets the subtitle of the chat view, which is
displayed below the title on the chat view header. If the subtitle
flag is set and either (or both) the
showConnectionStatus and
showTypingIndicator flags are set to true, then
the subtitle is displayed instead of either the connection status or
the typing indicator.
|
N/A |
chatTitle |
The title of the chat widget that is displayed in the header. | Ask |
clear |
The tooltip that appears when the user hovers over the Clear Messages button in the header. | Clear |
close |
The tooltip that appears when the user hovers over the close widget button in the header. | Close |
closing |
The status text that displays while the connection between chat widget and server is closing. | Closing |
connected |
The status text that displays while the connection between chat widget and server is established. | Connected |
connecting |
The status text that displays when the chat widget connects to the chat server. | Connecting |
connectionFailureMessage |
The failure message that displays when the widget can't connect to skill. | Sorry, the assistant is unavailable right
now. If the issue persists, contact your help
desk. |
connectionRetryLabel |
The label of the retry connection button. | Try Again |
defaultGreetingMessage |
The default client greeting response displayed when
the skill response has not been received within the number of
seconds set by defaultGreetingTimeout. .
|
Hey, Nice to meet you! Allow me a moment to
get back to you. |
defaultSorryMessage |
The default client response when the skill response
has not been received the number of seconds set by
typingIndicatorTimeout .
|
Unfortunately, I am not able to get you the
right content. Please try again. |
defaultWaitMessage |
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
|
I\'m still working on your request. Thank
you for your patience! |
disconnected |
The status text that displays when the connection between chat widget and server has closed. | Disconnected |
download |
The accessibility text for the download button that appears on each attachment message sent by the skill. | Download |
endConversation |
The tooltip that appears when hovering over the end conversation header button. | End Conversation |
endConversationConfirmMessage |
The confirmation message that displays when a user clicks the end conversation button. | Are you sure you want to end the
conversation? |
endConversationDescription |
The description message that displays along with the confirm message in the end conversation prompt. | This will also clear your conversation
history. |
errorSpeechInvalidUrl |
The error message that's displayed when the speech server URL is not set. | ODA URL for connection is not set. Please
pass \'URI\' parameter during SDK
initialization. |
errorSpeechMultipleConnection |
The error message that's displayed when multiple speech connections are attempted wihtin a short interval. | Another voice recognition is ongoing. Can\'t
start a new one.' |
errorSpeechTooMuchTimeout |
The error message that's displayed when a user provides voice message that's too long to be recognized. | Too much voice input to recognize. Can not
generate recognized text. |
errorSpeechUnsupportedLocale |
The error message that's displayed when a recording is attempted and an unsupported locale has been configured for voice recognition. | The set speech locale is not supported.
Cannot start recording. |
imageViewerClose |
The accessibility text for the button that closes the expanded image. | Close image viewer |
imageViewOpen |
The accessibility text for the button that expands the image. | Open image viewer |
inputPlaceholder |
The placeholder text that appears in the user input field. | Type a message |
itemIterator |
Item identifier in a list of items in a
Table , Form , or
Table-Form message. The text
({0} ) is replaced by the item index.
|
Item {0} |
linkField |
The replacement utterance text for a link field in a
Table , Form , or
Table-Form message. The placeholder
({0} ) is replaced with the
linkLabel of the field.
|
Click on the highlighted text to open Link
for {0} |
noSpeechTimeout |
The status text that's displayed when the Chat Server is unable to recognize the voice. | Could not detect the voice, no message
sent. |
noText |
The label for the No confirmation button. | No |
openMap |
The label for the action button that's used to open a location map. | Open Map |
previousChats |
The status text that displays at the end of older messages. | Previous conversations |
ratingStar |
The tooltip text that's displayed for each rating
star in a feedback message. The placeholder `{0}`
is replaced by number of stars that the user has selected.
|
Rate {0} star |
recognitionTextPlaceholder |
When voice mode is activated, this is the placeholder text that's displayed in the recognition text field. | Speak your message |
relTimeDay |
The relative timestamp that displays every day since
the previous message was received. {0} is replaced
by the number of days that have passed.
|
{0}d ago |
relTimeHr |
The relative timestamp that displays every hour for
the first 24 hours after the previous message was received.
{0} is replaced by the number of hours that
have passed.
|
{0}hr ago |
relTimeMin |
The relative timestamp that displays every minute
since the last message was received. {0} is
replaced by the number of minutes that have passed.
|
{0}min ago |
relTimeMoment |
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. | A few seconds ago |
relTimeMon |
The relative timestamp that displays every month
since the previous message was received. {0} is
replaced by the number of months that have passed.
|
{0}mth ago |
relTimeNow |
The relative timestamp that displays for a new message. | Now |
relTimeYr |
The relative timestamp that displays each year after
the previous message was received. {0} is replaced
by the number of years that have passed.
|
{0}yr ago |
requestLocation |
The text that displays while the user location is requested. | Requesting location |
requestLocationDeniedPermission
|
The error message that's displayed when the permission to access location is denied. | Location permission denied. Please allow
access to share your location, or else type in your
location. |
requestLocationDeniedTimeout |
The error message that's displayed when the location request is not resolved because of a timeout. | Taking too long to get your current location.
Please try again, or else type in your
location. |
requestLocationDeniedUnavailable |
The error message displayed when the location request is denied because the current location of the client device is unavailable. | Your current location is unavailable. Please
try again, or else type in your location. |
requestLocationString |
The error text that displays when the user denies the location request. | Cannot access your location. Please allow
access to proceed further. |
retryMessage |
The text that displays when the user message has not been sent to the server. | Try again |
send |
The tooltip appears when the user hovers over the send button in the footer. | Send |
shareAudio |
The menu item text in the share the popup for sharing an audio file | Share Audio |
shareFailureMessage |
The error message that's displayed when the share action button in a message is clicked, but the share API is unavailable in the client device, or the share request has been rejected. | Sorry, sharing is not available on this
device. |
shareFile |
The menu item text in the share popup for sharing a generic file | Share File |
shareLocation |
The menu item text for sharing a location in the popup | Share Location |
shareVisual |
The menu item text in the share popup for sharing an image or video file | Share Image/Video |
skillMessage |
A skill message indicator for screen readers. It's spoken by the screen readers before the skill responses. | Skill says |
speak |
The tooltip that appears when the user hovers over the speak button in the footer. | Speak |
typingIndicator |
The accessibility text for the typing indicator. It is spoken by the screen readers. | Waiting for response |
upload |
The tooltip that appears when the user hovers over the upload button in the footer. | Share popup |
uploadFailed |
The error text that displays when an upload fails. | Upload Failed. |
uploadFileSizeLimitExceeded |
The error text that displays when the size of the upload file exceeds the limit. | Upload Failed. File size should not be more
than 25MB. |
uploadFileSizeZeroByte |
The error text that displays when upload file size is 0 bytes. | Upload Failed. Files of size zero bytes
cannot be uploaded. |
uploadUnsupportedFileType |
The error text that displays when an upload is attempted for an unsupported file type. | Upload Failed. Unsupported file
type. |
userMessage |
A user message indicator for screen readers. It's spoken by the screen readers before the user messages. | I say |
utteranceGeneric |
The fallback description for the response message that's used in utterance. | Message from skill. |
webViewAccessibilityTitle |
The default accessibility title for webview that's read aloud by screen readers. | In-widget WebView to display
links |
webViewClose |
The default label/tooltip title for
webview close button.
|
Done |
webViewErrorInfoDismiss |
The tooltip for the dismiss button that's used to close the fallback link inside the webview. | 'Dismiss' |
webViewErrorInfoText |
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.
|
Sorry, we can\'t open this page in the chat
window. Click {0}here{/0} to open it in your
browser. |
yesText |
The label for the Yes confirmation button. | Yes |
Configure Share Menu Options
- visual media files (images and videos)
- audio files
- general files like documents, PDFs, and spreadsheets
- location
The
shareMenuItems
setting allows you to restrict the items
that display in the share menu. The setting accepts a string array with keys that are
mapped to the share menu items: 'visual'
for the Share
Image/Video item, 'audio'
for the Share
Audio item, 'file'
for the Share
File item, and 'location'
for the Share
Location item. You can use these keys, which are not case-sensitive, to
specify which items are available in the menu (['visual', 'location']
,
for example). All of the menu items are available when the array is empty, or when an
invalid value is passed.
Note:
You can disable the attachment functionality by settingenableAttachment
to
false
.
Note:
Do not enable this setting if the skill connects to an ODA instance that's Version 20.08 or runs on any version prior to 20.08. This property only applies to client auth-enabled connections to Versions 20.12 and higher of the ODA platform.Custom Share Menu Items
shareMenuItems
array:
{
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
menu item can be passed with or without the string
category.
Tip:
To support labels in multiple languages, we recommend using i18n instead of thelabel
tag.
shareMenuItems
array in the settings
variable. You set the labels by passing them with share_
keys, which
are illustrated in this snippet as well. You can set the label for a wild card
(*
) using the share_all
i18n
key.var settings = {
shareMenuItems: [ {
type: 'pdf',
label: 'Upload PDF',
}, {
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'
}
}
}
Customize CSS Classes
Class | Component |
---|---|
oda-chat-button |
The collapsed chat component button |
oda-chat-button-clear |
The clear messages button |
oda-chat-button-close |
The close widget button |
oda-chat-button-narration |
The skill's audio response toggle button |
oda-chat-button-send |
The send message button |
oda-chat-button-upload |
The upload file button |
oda-chat-card |
The card message |
oda-chat-closing |
Applied as a sibling to
oda-chat-connection-status when the widget is
disconnecting from server
|
oda-chat-connected |
Applied as a sibling to
oda-chat-connection-status when the widget is
connected to server
|
oda-chat-connecting |
Applied as a sibling to
oda-chat-connection-status when the widget is
connecting to server
|
oda-chat-connection-status |
The connection status. Each connection value has its
own class as well, such as oda-chat-connected ,
oda-chat-disconnected , or
oda-chat-connecting .
|
oda-chat-conversation |
The container for the conversation |
oda-chat-disconnected |
Applied as a sibling to
oda-chat-connection-status when the widget is
disconnected from server
|
oda-chat-footer |
The chat widget footer |
oda-chat-footer-button |
The common class for all footer buttons |
oda-chat-header |
The chat widget header |
oda-chat-header-button |
The common class for all header buttons |
oda-chat-icon-wrapper |
The wrapper for the skill or for a person that's displayed alongside the message. |
oda-chat-left |
The wrapper for the skill message |
oda-chat-logo |
The logo on the widget header |
oda-chat-message |
The common wrapper class for all chat messages |
oda-chat-message-action-location |
The location request action button |
oda-chat-message-action-postback |
The postback action button |
oda-chat-message-actions |
The action buttons wrapper |
oda-chat-message-bubble |
The message bubble |
oda-chat-message-global-actions |
The global action buttons wrapper |
oda-chat-message-icon |
The image for the skill or for a person that's displayed alongside the message. |
oda-chat-notification-badge |
The notification badge for messages that haven't been viewed. |
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-right |
The wrapper for the user message |
oda-chat-title |
The title on the widget header |
oda-chat-user-input |
The user input text area |
oda-chat-widget |
The expanded chat component, which wraps the widget header, conversation, and footer. |
oda-chat-wrapper |
The wrapper for entire chat component |
Customize the Timestamp
By default, the timestamp that displays in the header when
enableTimestampdates
is set to
true
displays the format as the locale's day of the
week, month, date, year, and time (am and pm). For example, Thursday, August
13, 2020, 9:52:22 AM. You can configure this timestamp by passing formatting
options in the timestampFormat
setting. You can format the
timestamp by either passing a pattern string of formatting tokens, or by
passing an object containing Intl.DateTimeFormat
options.
Format the Date-Time with Pattern Strings
timestampFormat: 'hh:mm:ss a'
sets the timestamp
as 09:30:14 pm.
Note:
These tokens are case-sensitive, so for example, passingyyyy
instead of
YYYY
would prevent the year from displaying.
Component | Token | Output |
---|---|---|
Day of the month |
|
|
Day of the week |
|
|
Month |
|
|
Year |
|
|
Hour |
|
|
Minute |
|
|
Second |
|
|
Fractional Second |
|
|
AM/PM |
|
|
Timezone |
|
|
Format the Timestamp with Intl.DateTimeFormat Objects
Property | Values |
---|---|
dateStyle |
'full' | 'long' | 'medium' | 'short' |
timeStyle |
'full' | 'long' | 'medium' | 'short' |
weekday |
|
day |
|
month |
|
year |
|
era |
|
hour |
|
minute |
|
second |
|
timeZoneName |
|
timeZone |
The time zone. All implementations must recognize
UTC . The default value 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). Values
are true and false .
|
Customize the Feedback Message Rating Gauge
The feedback component message enables you to collect user feedback. If you're using the 21.10 SDK, the default presentation of the feedback component is a star rating system, a horizontal row of stars that are highlighted as users hover over and select them. You can change the behavior of the component using the User Feedback component, but you can customize the components' appearance using the SDK settings.
rating
icon in the
icons
field.
Tip:
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'
}
})
Tip:
You can customize the prompts output by the User Feedback component by the editing the Feedback-related resource bundles accessed through the Resource Bundle Configuration page or by editing thesystemComponent_Feedback_
keys in an exported resource bundle
CSV file.
Send the Initial Message when the Conversation History is Empty
initUserHiddenMessage
messages are sent regardless of the
user's conversation history; they are sent the first time the chat widget is opened for
every session. To send the initial message when the conversation history is empty, you
need to bind an event listener to the Bots.on()
method. For
example:Bots = new WebSDK(chatWidgetSettings);
var isHandled = false;
var message = ;
Bots.on(WebSDK.EVENT.WIDGET_OPENED, function() {
if (!isHandled && Bots.isConnected() && !Bots.getConversationHistory().messagesCount) {
Bots.sendMessage(message, { hidden: true });
isHandled = true;
}
});
Bots.on(WebSDK.EVENT.NETWORK, function(state) {
if (!isHandled && Bots.isConnected() && Bots.isChatOpened() && !Bots.getConversationHistory().messagesCount) {
Bots.sendMessage(message, { hidden: true });
isHandled = true;
}
});
Bots.connect();
Speech Synthesis Service Injection
- You're often limited to unnatural, generic-sounding voices that can undermine your branding.
- A user's device may not support gender-specific voices.
- Some native frameworks (Cordova and ReactNative among them) require third-party libraries for TTS services because their webviews do not expose the native speech synthesis APIs that are required by the Web SDK.
ttService
feature flag or by calling the
setTTSService
method (described in the documentation that
accompanies the SDK). You can use your own TTS, or one provided by a third
party.
Speech Synthesis Service Interface
SpeechSynthesisService
interface for the
TTS service instance that you're going to
inject./**
* Interface for the speech synthesis service; this can be used to define a service that can be
* injected into the SDK to perform speech synthesis on behalf of the skill or assistant
*/
interface SpeechSynthesisService {
/**
* Adds a phrase to the utterance queue to be spoken
* @param phrase string
*/
speak(phrase: string): void;
/**
* Cancels any ongoing speech synthesis utterance
*/
cancel(): void;
/**
* Returns a Promise that resolves into a list of SpeechSynthesisServiceVoice objects representing
* the available voices
*
* @return {*} {Promise<SpeechSynthesisServiceVoice[]>}
*/
getVoices(): Promise<SpeechSynthesisServiceVoice[]>;
/**
* 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(voices: SpeechSynthesisServiceVoice[]): Promise<void>;
/**
* Returns the voice that is used for speaking the utterances
*/
getVoice(): SpeechSynthesisServiceVoice;
}
/**
* Represents a voice that the SpeechSynthesisService supports. Every SpeechSynthesisServiceVoice has
* its own relative speech service including information about language, name and optionally more.
*/
interface SpeechSynthesisServiceVoice {
/**
* Returns a BCP 47 language tag indicating the language of the voice
*/
readonly lang: string;
/**
* Returns a human-readable name that represents the voice
*/
readonly name: string;
/**
* Pitch of the voice, can range between 0 and 2, default is 1
* Optional
*/
pitch?: number;
/**
* Speed at which the utterance is spoken at, can range between 0.1 and 10, default is 1
* Optional
*/
rate?: number;
/**
* Volume at which the utterance is spoken at, can range between 0 and 1, default is 1
* Optional
*/
volume?: number;
}
Once
your TTS service is mapped to an object that implements the Speech Synthesis API, it can
be passed to the SDK for injection of the TTS service. The service can be injected when
this object is passed to the ttsService field during initialization, or it can be
injected dynamically by passing the object to the
setTTSService(service)
method.
After the TTS service has been injected, the SDK handles the calls to the service methods
for uttering the messages. However, you can call these methods directly, or you can use
the TTS methods exposed by the SDK for any requirement. In headless mode, for example,
you can call the Bots.speakTTS(message)
method to pass a message as it
is received from the skill. The SDK handles both the parsing of the utterable text from
the message and the passing of this text to the TTS service so that it can be uttered.
Features
Absolute and Relative Timestamps
- Feature flag:
timestampFormat: 'none'
Note:
enableTimestamp: true
(default:true
) has been deprecated. - Feature configuration:
timestampFormat
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 seconds, days, hours, months, or
years ago relative to the previous message.
Description of the illustration relative_v_absolute_timestamps.png
The precision afforded by absolute timestamps make 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, days, hours, months, or
years ago, you don't need to convert them for timezones.
How Relative Timestamps Behave
timestampMode: 'relative'
or timestampMode:
'default'
), an absolute timestamp displays before the first message of the
day as a header. This header displays when the conversation has not been cleared and
older messages are still available in the history. A relative timestamp then displays on each new message.

Description of the illustration most_recent_message_timestamp.png
This timestamp is updated at following regular intervals (seconds, minutes, etc.) until a new message is received.
- For 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 first year
Add a Relative Timestamp
- Enable timestamps –
enableTimestamp: true
Note:
This feature flag has been deprecated in Release 22.02 in favor oftimestampFormat: 'none'
. - Enable relative timestamps –
timestampMode: 'relative'
- Optional steps:
- Set the color for the relative timestamp –
timestamp
: '<a hexadecimal color value>
' - For multi-lingual skills, localize the timestamp text using
these keys:
Key Default Text Description relTimeNow
Now
The initial timestamp, which displays for the first 9 seconds. This timestamp also displays when the conversation is reset. relTimeMoment
a few moments ago
Displays for 10 to 60 seconds. relTimeMin
{0}min ago
Updates every minute relTimeHr
{0}hr ago
Updates every hour relTimeDay
{0}d ago
Updates every day for the first month. relTimeMon
{0}mth ago
Updates every month for the first twelve months. relTimeYr
{0}yr ago
Updates every year. - Use the
timeStampFormat
settings to change the format of the absolute timestamp that displays before the first message of each day.
- Set the color for the relative timestamp –
Autocomplete
- Feature flag:
enableAutocomplete: true
(default:false
) - Enable client side caching:
enableAutocompleteClientCache
Autocomplete minimizes user error by providing effective phrases that can be used as
both direct input and as suggestions. To enable this feature, update the widget settings
with enableAutocomplete: true
and add a set of optimized user messages
to the Create Intent page. Once enabled, a popup displays these
messages after users enter three or more characters. The words in the suggested messages
that match the user input are set off in bold. From there, users can enter their own
input, or opt for one of the autocomplete messages instead.
Description of the illustration autocomplete_phrase_list.png
When a digital assistant is associated with the Oracle Web channel, all of the sample utterances configured for any of the skills registered to that digital assistant can be used as autocomplete suggestions.
Automatic RTL Layout
When the host page's base direction is set with <html dir="rtl">
to accomodate right-to-left (RTL) languages, the chat widget automatically renders on
the left side. Because the widget is left-aligned for RTL langauges, its icons and text
elements are likewise repositioned. The icons are in the opposite positions from where
they would be in a left-to-right (LTR) rendering. For example, the send, mic and
attachment icons are flipped so that the mic and send icons occupy the left side of the
input field (with the directional send icon pointing left) while the attachment icon is
on the right side of the input field. The alignment of the text elements, such as
inputPlaceholder
and chatTitle
, is based on
whether the text language is LTR or RTL. For RTL languages, the inputPlaceHolder text
and chatTitle appear on the right side of the input field.
Avatars
avatarBot
- The URL of the image source, or the source string of the SVG image that's displayed alongside the skill messages.avatarUser
- The URL of the image source, or the source string of the SVG image that's 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's isplayed alongside the agent messages. If this value is not provided, butavatarBot
is set, then theavatarBot
icon is used instead.
Note:
These settings can only be passed in the initialization settings. They cannot be modified dynamically.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>'
}
})
Cross-Tab Conversation Synchronization
Feature flag: enableTabsSync: true
(default:
true
)
Users may need to open the website in multiple tabs for various reasons. With
enableTabsSync: true
, you can synchronize and continue the user's
conversation from any tab, as long as the connections parameters (URI
,
channelId
, and userId
) are the same across all
tabs. This feature ensures that users can view messages from the skill on any tab and
respond from the same tab or any other one. Additionally, if the user clears the
conversation history in one tab, then it's deleted from the other tabs as well. If the
user updates the chat language on one tab, then the chat language gets synchronized to
the other tabs.
- A new tab synchronizes with existing tab(s) for the new messages between the user and the skill on opening. If you have not configured the SDK to display messages from the 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. Setting
disablePastActions
toall
orpostback
, may prevent interaction with the actions for messages in the new tab. - The Safari browser currently does not support this feature.
Custom Message Rendering
Feature flag: delegate.render: (message) => boolean (default:
undefined)
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.samples
directory to check how you can use this feature with such
frameworks like React, Angular, and Oracle JavaScript Extension Toolkit (JET).
Default Client Responses
Feature flag: enableDefaultClientResponse: true
(default:
false
)
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 the defaultGreetingTimeout
flag,
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 the typingIndicatorTimeout
flag, 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.
Delegation
Feature configuration: delegate
delegate
parameter, or
use the setDelegate
method. The delegate object may optionally contain
the beforeDisplay
, beforeSend
,
beforePostbackSend
, beforeEndConversation
and
render
delegate
functions.var 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') {
// Perform custom rendering for card using msgId
return true;
}
return false;
}
}
beforeDisplay
The beforeDisplay
delegate allows a skill's 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 of the message returned by the delegate. Use the
beforeDisplay
delegate to selectively apply the in-widget WebView linking behavior.
beforeSend
The beforeSend
delegate allows a user message to be modified before
it is sent to the chat server as part of sendMessage
. The message
returned by the delegate is sent to the skill instead of the original message. The
message returned by the delegate is not set if the delegate returns a falsy value like
null
, undefined
, or false
, then
the message is not sent. If it errors out, the original message will be sent instead of
the message returned by the delegate.
beforePostbackSend
The beforePostbackSend
delegate is similar to
beforeSend
, just applied to postback messages from the user. The
postback returned by the delegate is sent to the skill. If it returns a falsy value,
like null
, undefined
, or false
, then
no message is sent.
beforeEndConversation
beforeEndConversation
delegate allows an interception at the
end of a conversation flow if some pre-exit activity must be performed. The
function
receives the exit message as its input parameter and 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....
beforeEndConversation: function(message) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(message);
}, 2000);
});
}
render
The render
delegate allows you 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 the default message rendering. To identify the placeholder,
add 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.
Draggable Launch Button
Feature flag: enableDraggableButton: true
(default:
false
)
Sometimes, particularly on mobile devices where the screen size is limited, the chat
widget's launch button can block content in a web page. By setting
enableDraggableButton: true
, you can enable users to drag the
launch button out of the way when it's blocking the view. This flag only affects the
location of the launch button, not the chat widget: the widget will still open from its
original location.
Dynamic Typing Indicator
Feature flag: showTypingIndicator: 'true'
A typing indicator tells users to hold off on sending a message because the skill is
preparing a response. By default, skills display the typing indicator only for their
first response when you initialize the SDK with showTypingIndicator:
'true'
. For an optimal user experience, the skill should have a dynamic
typing indicator, which is a typing indicator that displays after each skill response.
Besides making users aware the skill has not timed out but is still actively working on
a response, displaying the typing indicator after each skill response ensures that users
won’t attempt to send messages prematurely, as might be the case when the
keepTurn
property directs the skill to reply with a series of
separate messages that don’t allow user to interject a response.
- Initialize the SDK with
showTypingIndicator
set totrue
. - Call the
showTypingIndicator
API
showTypingIndicator
can only enable the display of the
dynamic typing indicator when:
- The widget is connected to the Oracle Chat Server. The dynamic typing indicator will not appear when the connection is closed.
- The SDK has been initialized with
showTypingIndicator
set totrue
.Note:
This API cannot work when the SDK is used in headless mode.
typingIndicatorTimeout
, that has default setting of 20 seconds. If
the API is called while a typing indicator is already displaying, then the timer is
reset and the indicator is hidden.
The typing indicator disappears as soon as the user receives the skill’s messages. The typing indicator moves to the bottom of the chat window if a user enters a message, or uploads an attachment, or sends a location, while it’s displaying.
Control Embedded Link Behavior
- Custom handling:
linkHandler: { onclick: <function>, target: '<string>' }
- In the In-widget webview :
linkHandler: { target: 'oda-chat-webview' }
- In a new window:
openLinksInNewWindow: 'true'
openLinksInNewWindow: true
, or the default behavior of opening
links in a new tab when this option is set to false
, you can also open
links which overlay the widget’s web page. To enable this and other overrides to the
linking behavior, initialize the SDK with
linkHandler: {
target: '_blank', // open link in a new page
onclick: (event) => { // some operation }
}
Use
linkHander
to:
- Control
iframe
navigation so that it can continue to overlay the page without having to include the widget in every page, reopening it upon navigation, and maintaining the same user ID. - Open some links in a new window, while opening others in the same tab.
- Performing an action when a link is clicked.
- Preventing a link from opening.
- Opening a link in a webview.
openLinksInNewWindow
setting, you must define one, or both, of these attributes:
target
– Names the browsing location context, such as tab, a window, or aniFrame
. Define theiFrame
location as thetarget
attribute of an anchor element (<a>
). You can define the target’s_self
,_blank
,_parent
and_top
attributes.onclick
- Accepts a callback function that is called when the link is clicked. The callback is passed theMouseEvent
that's received on the click, and can be used to perform an action, or even prevent the link from opening.
Embedded Mode
- Feature flag:
embedded: true
(default:false
) - Pass the ID of target container element:
targetElement
- Adding
embedded: true
. - Defining the
targetElement
property with the ID of the DOM element (an HTML component) that's used as the widget's container (such as'container-div'
in the following snippet).
<head>
<meta charset="utf-8">
<title>Oracle Web SDK Sample</title>
<script src="scripts/settings.js"></script>
<script>
var chatWidgetSettings = {
URI: YOUR_URI,
channelId: YOUR_CHANNELID,
embedded: true,
targetElement: 'container-div'
...
</script>
</head>
<body>
<h3 align="center">The Widget Is Embedded Here!</h3>
</body>
<div id="container-div"
style="height: 600px; width: 380px; padding: 0; text-align: initial">
</div>
Note:
The widget occupies the full width and height of the container. If it can't be accommodated by the container, then the widget won't display in the page.End the Conversation Session
Feature flag: enableEndConversation: true
(default:
true
)
Starting with Version 21.12, the SDK adds a close button to the chat widget header
by default (enableEndConversation: true
) that enables users to end the
current session.
endConversationConfirmMessage
and
endConversationDescription
keys. When a user dismisses the prompt
by clicking Yes, the SDK sends the skill an event message that
marks the current conversation session as ended. The instance then disconnects from the
skill, collapses the chat widget, and erases the current user's conversation history. It
also raises a chatend
event that you can register
for:Bots.on('chatend', function() {
console.log('The conversation is ended.');
});
Opening the chat widget afterward starts a new conversation session.Note:
You can also end a session by calling theBots.endChat()
method (described in the reference that
accompanies the Oracle Web SDK that's available from the Downloads page). Calling this method may be
useful when the SDK is initialized in headless mode.
Focus on the First Action in a Message
Feature flag: focusOnNewMessage: 'action'
(default:
'input'
)
For users who prefer keyboard-based navigation (which includes power users), you
can shift the focus from the user input field to the first (or left most),
action button in a message. By default, the chat widget sets the focus back
to the user input field with each new message (focusOnNewMessage:
'input'
). This works well for dialog flows that expect a
lot of textual input from the user, but when the dialog flow contains a
number of messages with actions, users can only select these actions through
mousing or reverse tab navigation. For this use case, you can change the
focus to the first action button in the skill message as it's received by
setting focusOnNewMessage: 'action'
. If the message does
not contain any actions, the focus is set to the user input field.
Headless SDK
Feature flag: enableHeadless: true
(default: false
)
enableHeadless:
true
in the initial settings. The communication can be implemented as
follows:
- Sending messages - Calls
Bots.sendMessage(message)
to pass any payload to server. - Receiving messages - Responses can be listened for using
Bots.on('message:received', <messageReceivedCallbackFunction>)
. - Get connection status update - Listens for updates on the status of
the connection using
Bots.on('networkstatuschange', <networkStatusCallbackFunction>)
. The callback has a status parameter that is updated with values from 0 to 3, each of which maps to WebSocket states:0
:WebSocket.CONNECTING
1
:WebSocket.OPEN
2
:WebSocket.CLOSING
3
:WebSocket.CLOSED
- Return suggestions for a query – Returns a Promise that
resolves to the suggestions for the given query string. The Promise is
rejected if it takes too long (which is approximately 10 seconds) to
fetch the suggestion.
Bots.getSuggestions(utterance) .then((suggestions) => { const suggestionString = suggestions.toString(); console.log('The suggestions are: ', suggestionString); }) .catch((reason) => { console.log('Suggestion request failed', reason); });
Note:
To use this API, you need to enable autocomplete (
) and configure autocomplete for the intents.enableAutocomplete: true
Multi-Lingual Chat
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. Users can switch between languages, but only in between conversations, not during a conversation because the conversation gets reset whenever a user selects a new language.
Enable the Language Menu
multiLangChat
property with an object
containing the supportedLangs
array, which is comprised of language
tags (lang
) and optional display labels (label
).
Outside of this array, you can optionally set the default language with the
primary
key (primary: 'en'
in the following
snippet).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.
Tip:
You can add an event listener for thechatlanguagechange
event (described
in the reference that accompanies the Oracle Web SDK that's available from the Downloads page), 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);
});
- You need to define a minimum of two languages to enable the dropdown menu to display.
- The
label
key is optional for the natively supported languages:fr
displays as French in the menu,es
displays as Spanish, and so on. - Labels for the languages can be set dynamically by passing the
labels with the
i18n
setting. You can set the label for any language by passing it to itslanguage_<languageTag>
key. This pattern allows setting labels for any language, supported or unsupported, and also allows translations of the label itself in different locales. For example:
If thei18n: { en: { langauge_de: 'German', language_en: 'English', language_sw: 'Swahili', language_tr: 'Turkish' }, de: { langauge_de: 'Deutsche', language_en: 'Englisch', language_sw: 'Swahili', language_tr: 'Türkisch' } }
i18n
property includes translation strings for the selected language, then the text for fields like the input placeholder, the chat title, the hover text for buttons, and the tooltip titles automatically switch to the selected language. The field text can only be switched to a different language when there are translation strings for the selected language. If no such strings exist, then the language for the field text remains unchanged. - The widget automatically detects the language in the user profile and activates
the Detect Language option if you omit the
primary
key. - While
label
is optional, if you've added a language that's not one of the natively supported languages, then you should add a label to identify the tag, especially when there is no i18n string for the language. For example, if you don't definelabel: 'हिंदी'
, for thelang: hi
, then the dropdown displays hi instead, contributing to a suboptimal user experience.
Disable Language Menu
Starting with Version 21.12, 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
Note:
If you omit theprimary
key, 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'}
.
setPrimaryChatLanguage(lang)
API even when the dropdown menu has
not been configured. For
example:Bots.setPrimaryChatLanguage('fr')
You
can dynamically update the language irrespective of whether the chat language is
initially configured or not.Note:
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 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.
|
In-Widget Webview
You can configure the link behavior in chat messages to allow users to access web pages from within the chat widget. Instead of having to switch from the conversation to view a page in a tab or separate browser window, a user can remain in the chat because the chat widget opens the link within a Webview.
Configure the Linking Behavior to the Webview
- To open all links in the webview, pass
linkHandler: { target: 'oda-chat-webview' }
in the settings. This sets the target of all links tooda-chat-webview
, which is the name of theiframe
in the webview. - To open only certain links in the webview while ensuring that other
links open normally in other tabs or windows, use the
beforeDisplay
delegate. To open a specific message URL action in the webview, replace theaction.type
field’s'url'
value with'webview'
. When the action type is'webview'
in thebeforeDisplay
function, the action button will open the link in the webview when clicked.
Open Links from Within the Webview
Links that are embedded within a page that displays within the WebView can only be
opened within the WebView when they are converted into an anchor element
(<a>
), with a target attribute defined as
target="oda-chat-webview"
.
Customize the WebView
webViewConfig
setting
which accepts an object. For
example:{ referrerPolicy: 'no-referrer-when-downgrade', closeButtonType: 'icon', size: 'tall'
The
fields within this object are optional. Note:
The configuration can also by updated dynamically by passing awebViewConfig
object in the
setWebViewConfig
method. Every property in the object is
optional.
Field | Value | Description |
---|---|---|
accessibilityTitle |
String | The name of the WebView frame element for Web Accessibility. |
closeButtonIcon |
String | The image URL/SVG string that is used to display the close button icon. |
closeButtonLabel |
String | Text label/tooltip title for the close button. |
closeButtonType |
|
Sets how the close button is displayed in the WebView. |
referrerPolicy |
ReferrerPolicy |
Indicates which referrer to send when fetching the frame's
resource. The referrerPolicy policy value must be a
valid directive. The default
policy applied is
'no-referrer-when-downgrade' .
|
sandbox |
A String array | An array of of valid restriction strings that allows for the
exclusion of certain actions inside the frame. The restrictions that
can be passed to this field are included in the description of the
sandbox attribute in MDN Web Docs.
|
size |
|
The height of the WebView compared to the height of the chat
widget. When set to 'tall' , it is set as 80% of the
widget's height, when set to 'full' it equals the
widget's height.
|
title |
String | The title that's displayed in the header of the WebView container. |
- Pages which provide response header
X-frame-options: deny
orX-frame-options: sameorigin
may not open in the WebView due to server-side restrictions that prevent the page from being opened inside iframes. In such cases, the WebView presents the link back to the user so that they can open it in a new window or tab. - Due to server-side restrictions, authorization pages like IDCS,
Google Login, and FaceBook Login cannot opened inside the WebViews, as
authorization pages always return
X-frame-options: deny
to prevent a clickjacking attack. - External links, which can't open correctly within the WebView. Only
links embedded in the conversation messages can be opened in the WebView.
Note:
Because external messages are incompatible with the WebView, do not target any external link to be opened in the WebView.
webViewErrorInfoText
i18n translation
string:settings = {
URI: 'instance',
//...,
i18n: {
en: {
webViewErrorInfoText: 'This link can not be opened here. You can open it in a new page by clicking {0}here{/0}.'
}
}
}
Long Polling
Feature flag: enableLongPolling: true
(default:
false
)
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 because the SDK must
continuously call, or poll, the server to fetch the latest messages from skill. This
fallback feature can be enabled by passing enableLongPolling: true
in
the initial settings.
Response Narration
- Feature flag:
enableBotAudioResponse: true
(default:false
) - Feature configuration:
enableSpeechAutoSend
enableBotAudioResponse
to
true
and then by defining the skillVoices
array,
which prioritizes the voice preferences. The objects in this array use a
lang
field and an optional name
field to describe
the voices that the device can use for spoken content. The following example illustrates
a skillVoices
array for iPhone voices.
const settings = {
...,
enableBotAudioResponse: true,
skillVoices: [{
lang: 'en-US',
name: 'Samantha'
}, {
lang: 'en-US',
name: 'Alex'
}, {
lang: 'en-UK'
}]
}
The SDK searches for these voices in the order that they are passed. It then selects
the first complete match to be the voice of the narrator. If the SDK can't find an exact
match, then it selects the first match based on the lang
value alone.
If there's no matching lang
value, then the SDK uses the device’s
default language.
Typing Indicator for User-Agent Conversations
Feature flag: enableSendTypingStatus
: boolean (default:
false
)
This feature allows agents to ascertain if users are still engaged in the
conversation by sending the user status to the live agent. When
enableSendTypingStatus
is set to true
, the SDK
sends a RESPONDING
typing status event along with the text that is
currently being typed by the user to Oracle Fusion
Cloud B2C Service (Oracle B2C
Service). This, in turn, displays a typing indicator on the agent console. When the user has
finished typing, the SDK sends a LISTENING
event to Oracle B2C
Service 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.
enableAgentSneakPreview
(which by default is
false
) must be set to true
and Sneak Preview must
be configured in Oracle B2C
Service. For more details, refer to Oracle B2C
Service
Sneak Preview configuration.
Note:
You do not have to configure live typing status on the user side. The user can see the typing status of the agent by default. When the agent is typing, the SDK receives aRESPONDING
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 a
LISTENING
status message which hides the typing
indicator.
Voice Recognition
Feature flag: enableSpeech: true
(default: false
)
Setting enableSpeech: true
enables the microphone button to
display in place of the send button whenever the user input field is empty.
Your skill can also utilize voice recognition with the
startVoiceRecording(onSpeechRecognition, onSpeechNetworkChange)
method to start recording and the stopVoiceRecording
method to stop
recording. (These methods are described in the User's Guide that's included with the
SDK.)
Using the enableSpeechAutoSend
flag, you can configure
whether or not to send the text that’s recognized from the user’s voice directly to the
chat server with no manual input from the user. By setting this property to
true
(the default), you allow the user’s speech response to be
automatically sent to the chat server. By setting it to false
, you
allow the user to edit the message before it's sent to the chat server, or delete
it.
Voice Visualizer
Feature configuration: enableSpeechAutoSend

Note:
Voice mode is indicated when the keyboard

Description of the illustration voice_visualizer.png
enableSpeechAutosend
is
true
(enableSpeechAutoSend: true
), messages are
sent automatically after they're recognized. Setting enableSpeechAutoSend:
false
switches the input mode to text after the voice message is
recognized, allowing users to edit or complete their messages using text before sending
them manually. Alternatively, users can complete their message with voice through a
subsequent click of the voice icon before sending them manually.
Note:
The voice visualizer is created using AnalyserNode. You can implement the voice visualizer in headless mode using thestartVoiceRecording
method. Refer to the SDK to find out more about
AnalyserNode and frequency levels.
Message Model
To use features like headless mode and delegate, you need to understand both user and skill messages. Everything that's received or sent from the Oracle Chat Server is represented as a message, one that's sent from the user to the skill, or from the skill to the user.
Base Types
Attachment
Name | Description | Type | Required? |
---|---|---|---|
title |
The attachment title | string | No |
type |
The attachment type | string (valid values: audio, file, image, video) | Yes |
url |
The download URL for the attachment | string | Yes |
{
"title": "Oracle Open World Promotion",
"type": "image",
"url": "https://www.oracle.com/us/assets/hp07-oow17-promo-02-3737849.jpg"
}
Location
Name | Description | Type | Required? |
---|---|---|---|
title |
The location title | string | No |
url |
The URL for displaying the location on a map | string | No |
latitude |
The GPS coordinate's longitude value | double | Yes |
longitude |
The GPS coordinate's latitude value | double | Yes |
{
"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
}
Action
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | string | Yes |
label |
The descriptive label text for the action. | string | At least one of label or
imageUrl will be present.
|
imageUrl |
The image for the action | string | At least one of label or
imageUrl will be present.
|
PostbackAction
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "postback" | Yes |
postback |
The postback that's returned when the user selects an action. | A string or JSON object | Yes |
{
"type": "postback",
"label": "Large Pizza",
"imageUrl": "https://example.com/images/gallery/locations/11.jpg",
"postback": {
"state": "askSize",
"action": "getCrust"
}
}
CallAction
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "call" | Yes |
phoneNumber |
The phone number to call | string | Yes |
{
"type": "call",
"label": "Call Support",
"imageUrl": "http://example.com.ar/files/2016/05/cuidado.jpg",
"phoneNumber": "18005555555"
}
urlAction
Requests the client to open a website in a new tab or in an in-app browser.
Name | Description | Type | Required? |
---|---|---|---|
type |
The action type | "call" | Yes |
url |
The URL of the website that's displayed. | string | Yes |
Conversation Message
Name | Description | Type | Required? |
---|---|---|---|
messagePayload |
The message payload | Message | Yes |
userId |
The user ID | string | Yes |
{
"messagePayload": {
"text": "show menu",
"type": "text"
},
"userId": "guest"
}
Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | string | Yes |
User Message
Represents a message sent from the user to the skill.
User Text Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "text" |
Yes |
text |
The message text | string | Yes |
{
"messagePayload": {
"text": "Order Pizza",
"type": "text"
},
"userId": "guest"
}
User Postback Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "postback" |
Yes |
text |
The postback text | string | No |
postback |
The postback of the selected action | A string or JSON object | Yes |
{
"messagePayload": {
"postback": {
"variables": {
"pizza": "Small"
},
"system.botId": "69BBBBB-35BB-4BB-82BB-BBBB88B21",
"system.state": "orderPizza"
},
"text": "Small",
"type": "postback"
},
"userId": "guest"
}
User Attachment Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "attachment" |
Yes |
attachment |
The 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
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "location" |
Yes |
location |
The user location information | Location | Yes |
{
"messagePayload": {
"location": {
"latitude": 45.9285271,
"longitude": 132.6101925
},
"type": "location"
},
"userId": "guest"
}
Skill Message
Represents the message sent from the skill to the user.
Bot Text Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "text" |
Yes |
text |
The message text | string | Yes |
actions |
An array of actions related to the text. | array | No |
globalActions |
An array of global actions related to the text. | array | No |
{
"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"
}
Skill Location Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "location" |
Yes |
location |
The location | Location | Yes |
actions |
An array of actions related to the text. | array | No |
globalActions |
An array of global actions related to the text. | array | No |
Skill Attachment Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "attachment" |
Yes |
attachment |
The attachment sent | Attachment | Yes |
actions |
An array of actions related to the text. | array | No |
globalActions |
An array of global actions related to the text. | array | No |
Note:
File uploads from the host site may fail and throw a console error similar to the following:https://<oda-instance>/chat/v1/attachments from origin <client site> has been blocked by CORS policy: No Access-Control-Allow-Origin header is present on the requested resource
This
is because the host site's CORS (Cross-Origin Resource Sharing) settings, which block all
cross-origin HTTP requests, may also block upload requests from the client instance to
the Oracle Digital Assistant attachment server. If you run into this problem, update the
host site's security policy to allow the domain for the Digital Assistant instance.
Because the conversation uses WebSocket connections, CORS does not impact the
conversation.
Passing File Names
x-oda-meta-file-name
x-oda-meta-file-type
Feedback Messages
channelExtensions
object field that is set as { "displayType": "stars" }
.
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "text" |
Yes |
text |
The message text | string | Yes |
actions |
An array of actions representing the postback information for each rating. | array<action> | Yes |
globalActions |
An array of global actions related to the text | array<action> | No |
channelExtensions |
An object describing extensions to the payload. | { “displayType”: “stars” } |
Yes |
{
"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>"
}
Skill Card Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "card" |
Yes |
layout |
Whether to display the messages horizontally or vertically. | string (values: horizontal ,
vertical )
|
Yes |
cards |
An array of cards to be rendered. | array | Yes |
headerText |
The cards' header text | string | No |
actions |
An array of actions related to the text. | array | No |
globalActions |
An array of global actions related to the text. | array | No |
Card
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 |
The URL of the image that is displayed. | string | No |
url |
The website URL that's opened by a tap. | string | No |
actions |
An array of actions related to the text | array | No |
{
"messagePayload": {
"type": "card",
"layout": "horiztonal",
"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"
}
Skill Postback Message
Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "postback" |
Yes |
text |
The message text | string | No |
postback |
The postback | A string or a JSON object | Yes |
actions |
An array of actions that are related to the text | array | No |
globalActions |
An array of global actions related to the text | array | No |
Skill Form Message
fields
array with key-value pairs that represent a field.
Note:
This message type is used for SQL dialogs.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<Row> | 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 |
actions |
An array of actions related to the form | Array<Action> | No |
globalActions |
An array of global actions | Array<Action> | No |
{
"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"
}
]
}
Skill Table Message
fields
array that represents individual cells.
Note:
This message type is used for SQL dialogs.Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "table" |
Yes |
headings |
An array of table headings | Array<Heading> | Yes |
rows |
An array of table rows. Each row contains a
fields array that represents the table cells.
|
Array<Row> | Yes |
paginationInfo |
The paging information for the results in the table |
PaginationInfo |
No |
actions |
An array of actions related to the table | Array<Action> | No |
globalActions |
An array of global actions | Array<Action> | No |
{
"type":"table",
"headerText":"A-Team",
"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"
}
}
Skill Table-Form Message
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.
Note:
This message type is used for SQL dialogs.Name | Description | Type | Required? |
---|---|---|---|
type |
The message type | "tableForm" |
Yes |
headings |
An array of table headings | Array<Heading> | Yes |
rows |
An array of table rows. Each row contains an array of fields that represent the table cells. | Array<Row> | 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 |
formColumns |
The number suggesting the number of columns in which the fields of the form should be grouped. | 1, 2 | Yes |
paginationInfo |
An array of global actions related to the text | Array<Action> | No |
actions |
An array of actions related to the table form | Array<Action> | No |
globalActions |
An array of global actions | Array<Action> | No |
{
"type":"tableForm",
"headerText":"A-Team",
"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"
}
Embed Chat in Visual Builder Apps
<oj-oda-chat>
Web Component, you can embed chat in
Oracle Visual Builder apps. This component, which is available from the Component
Exchange that's associated with your instance, provides the following:
- Support for Common Response component-based conversations
- Speech integration
- Attachment sharing
- Connection to authentication-enabled channels
- Audio response for skill messages
- Delegate
- Theming
Tutorial: Access a Skill from Your Website
You can get a hands-on look at setting up the Oracle Web Channel, embedding the widget in a web page, customizing the widget's look and feel, and enabling autocomplete through this tutorial: Access a Skill from Your Website.
Oracle Web Channel Extensions
For Oracle Web channels, you can extend the functionality of Common Response components with capabilities that are specific to the JavaScript SDK.
You access the extensions by using the channelCustomProperties
element in Common Response components and setting the appropriate properties. The code has the
following format:
...
channelCustomProperties:
- channel: "websdk"
properties:
PROPERTY_NAME: "PROPERTY_VALUE"
...
You can apply channelCustomProperties
in the component's
metadata at the level of globalActions
, responseItems
, and
elements of responseItems
, depending on the given property.
Here are the available custom properties for Oracle Web channels:
Name | Allowed Values | Applies To... | Description |
---|---|---|---|
mediaType |
|
|
The media type of the attachment. For example, image/jpeg . If not specified, the media type will be resolved from the attachment URL.
|
For more information on using channelCustomProperties
, see Channel-Specific Extensions.