Directly RTM Docs
About RTM
RTM (Real Time Messaging) is a web widget tool to integrate Directly services on your website.
Getting started
- Signup for Directly and create a company
- Ask your Account Manager to setup an RTM instance for you
- Get the RTM widget embed code. It should look something like this:
<script>
(function(d, i, r, e, c, t, l, y) {
i[r] = i[r] || function () {
(i[r].cq = i[r].cq || []).push(arguments)
};
l = d.createElement("script");
l.id = "directlyRTMScript";
l.src = e;
l.async = 1;
y = d.head || d.getElementsByTagName("head")[0];
if (d.readyState === "complete" || d.readyState === "loaded" || d.readyState === "interactive") {
y.appendChild(l);
} else if (i.addEventListener) {
i.addEventListener("DOMContentLoaded", function() { y.appendChild(l); });
} else {
i.attachEvent("onload", function() { y.appendChild(l); });
}
})(document, window, "DirectlyRTM", "https://app.directly.com/widgets/rtm/embed.js");
DirectlyRTM("config", {
id: "your-rtm-widget-uuid"
});
</script>
- Paste the widget code into your website, before the closing
</body>
tag of your page. See below for more integration use cases. - Your users can now start using RTM and sending you questions.
Advanced configuration
RTM accepts several configuration parameters:
Configuration parameters
Property name | Data Type | Default Value | Description |
---|---|---|---|
id | string | n/a | ID of the widget |
active | boolean | true* | Enables or disables the widget |
displayAskQuestion | boolean | true | Wether to display or not the RTM bubble at the bottom right corner of the browser |
disableAskNewQuestionFromUi | boolean | true | Wether to display or not any button and/or links which takes the user to the ask form |
questionCategory | string | n/a | The question category to assign |
metadata | object | n/a | Additional metadata that will be assigned to the question |
userName | string | n/a | Name of the person asking a question. This is used by our experts to address users. Use this only for your logged in users. |
userEmail | string | n/a | Email of the person asking a question |
userPhone | string | n/a | Phone number of the person asking a question |
showDisclaimer | boolean | false* | Whether to display or not a disclaimer that users have to opt-in to ask questions |
forceRecaptcha | boolean | false* | Whether to display or not a captcha before a user can ask a question |
lang | string | "en" | Language to use in the widget. It must be enabled in your company configuration |
i18n | object | n/a | Custom text to use in some labels by language in RTM |
* Default value may be overwritten by server configuration.
See the full example below for usage.
Deferred configuration
You can decouple the embed widget code from the config code. In this way, you can have the widget code preloaded when you need to trigger it.
<script>
(function(d, i, r, e, c, t, l, y) {
i[r] = i[r] || function () {
(i[r].cq = i[r].cq || []).push(arguments)
};
l = d.createElement("script");
l.id = "directlyRTMScript";
l.src = e;
l.async = 1;
y = d.head || d.getElementsByTagName("head")[0];
if (d.readyState === "complete" || d.readyState === "loaded" || d.readyState === "interactive") {
y.appendChild(l);
} else if (i.addEventListener) {
i.addEventListener("DOMContentLoaded", function() { y.appendChild(l); });
} else {
i.attachEvent("onload", function() { y.appendChild(l); });
}
})(document, window, "DirectlyRTM", "https://app.directly.com/widgets/rtm/embed.js");
</script>
DirectlyRTM("config", {
id: "your-rtm-widget-uuid"
});
Javascript API
You can interact with Directly RTM widget programmatically using its Javascript API. Run commands or listen to events to adapt the RTM experience to your users.
Commands
Change a configuration option
DirectlyRTM("set", <option>, <value>);
DirectlyRTM("set", "displayAskQuestion", true|false)
DirectlyRTM("set", "showDisclaimer", true|false)
DirectlyRTM("set", "metadata", { "browser: "Chrome" })
DirectlyRTM("set", "questionCategory", "custom_category")
You can set any item from the table in Advanced Configurations except id
, userName
, userEmail
and userPhone
.
Open the Ask Question Form
DirectlyRTM("openAskForm");
Maximize widget
DirectlyRTM("maximize");
Minimize widget
DirectlyRTM("minimize");
Ask a question
DirectlyRTM("askQuestion", {
questionText: "How can I merge two accounts?",
name: "Jane",
email: "jane@directly.com",
questionCategory: "my-category",
});
If the user is logged in, you can ignore the name
and email
parameters.
Update question metadata
DirectlyRTM("updateMetadata", {
questionUuid: "0e953a3f-c04e-419d-9f0d-00a5cbfe65c7",
metadata: { "os": "windows" },
});
Reroute a question to the company
DirectlyRTM("reroute", {
questionUuid: "0e953a3f-c04e-419d-9f0d-00a5cbfe65c7",
},
function(data) {
// Do something
// Example:
// console.log(data.success);
}
);
The callback function passed to reroute
is optional. It receives a single parameter of { success: <boolean_value> }
, which indicates whether the reroute request succeeded. This request is asynchronous, and the actual reroute will happen in the near future. The onReroute
command action will fire when the question actually reroutes.
Navigate to a specific view
DirectlyRTM("navigate", path);
Possible values of path
:
/ask
: Ask Question Form/list
: List of questions/question/$questionId
: Specific question/minimized
: Minimized view
Get data about current session and state
DirectlyRTM("getState", function(params) {
// Do something
});
The callback function passed to getState
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
session | n/a | boolean | Returns wether the user has a session or not |
questions | n/a | object | Returns an object with the number of open, closed and total questions |
Note: you can not call this method on page load. If you need access to session and state data when the page loads, please use the onReady
command.
Finish current session
DirectlyRTM("logout");
Event listeners
You can define callbacks for some events triggered by RTM.
Widget Ready
Triggered only after the RTM widget has finished loading completely.
DirectlyRTM("onReady", function() {
// Do something
});
The callback function passed to onReady
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
config | n/a | object | The configuration object passed to DirectlyRTM("config") |
session | n/a | boolean | Returns wether the user has a session or not |
questions | n/a | object | Returns an object with the number of open, closed and total questions |
Question asked
Triggered when the user asks a new question.
DirectlyRTM("onAskQuestion", function(questionData) {
// Do something
});
// Sample questionData
{
questionBody: "How do I reset my password?"
questionUuid: "b34ff943-366d-4be9-8d65-c614743959c5"
dateCreated: "2021-01-21T19:57:23Z"
}
The callback function passed to onAskQuestion
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
questionBody | n/a | string | Text of the question |
questionUuid | n/a | string | Unique ID of the question |
dateCreated | n/a | string | Timestamp of question creation in ISO 8601 format (e.g. 2021-01-21T19:57:23Z) |
Navigation (view changed)
Triggered when the view has changed. The possible views are /minimized
, /ask
, /list
, /question
.
DirectlyRTM("onNavigate", function(path) {
// Do something
// path is the view path, for example `/ask` or `/list`
});
// Sample path value:
{
path: "/ask"
}
Message posted
Triggered when a new message appears in the conversation. The message can be from a poster, an expert, the system, or a bot.
DirectlyRTM("onMessage", function(messageData) {
// Do something
});
// Sample messageData value:
{
messageText: "What happens when you click that link?"
messageTextHtml: "What happens when you click that link?"
authorType: "EXPERT"
messageType: "Answer"
messageUuid: "c42904d8-a69a-410d-af4a-674c27df8ef2"
responseUuid: "66aa7481-1a59-4208-bc16-4afec1cf0556"
questionUuid: "b34ff943-366d-4be9-8d65-c614743959c5"
questionStatus: 0
dateCreated: "2021-01-21T20:26:44Z"
}
The callback function passed to onMessage
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
messageText | n/a | string | Raw text of the message |
messageTextHtml | n/a | string | Text of the message, with markdown converted to HTML |
authorType | n/a | string | Type of the author. Possble values are "POSTER", "EXPERT", "BOT" or "SYSTEM". |
messageType | n/a | string | Type of the message. Possble values are "Answer", "ResponseMessage", and "AutoResponseMessage", as well as many system messages types (listed below). |
messageUuid | n/a | string | Unique ID of the message |
responseUuid | n/a | string | Unique ID of the response |
questionUuid | n/a | string | Unique ID of the question |
questionStatus | n/a | number | A number from 0 to 7 that indicates the status. 0 is unresolved/open and 1 is resolved. |
dateCreated | n/a | string | Timestamp of message creation in ISO 8601 format (e.g. 2021-01-21T19:57:23Z) |
Here are the possible system messageType
s:
CustomerReroutePromptSystemMessage
AcceptResponseSystemMessage
AcceptResponseConfirmationMessage
AutoResponseConfirmationMessage
RejectedAutoResponseMessage
RejectedByUserBlockedQuestionSystemMessage
RejectedAutoResponseMessageChatbotPing
OpenedAutoResponseMessage
NotifyingExpertsSystemMessage
QuestionExpiredSystemMessage
QuestionRejectedByKeywordSystemMessage
QuestionRejectedByMetadataSystemMessage
QuestionRejectedByPredictiveRoutingSystemMessage
QuestionRejectedByDomainSystemMessage
QuestionRejectedByBudgetSystemMessage
QuestionRejectedByBlockedUser
QuestionRejectedByIpAddress
QuestionReroutedSystemMessage
AcceptedResponseSystemMessage
RateResponseSystemMessage
AddTestimonialSystemMessage
AddedTestimonialSystemMessage
MarkAsResolvedMessage
ContestedMarkAsResolvedMessage
ApprovedMarkAsResolvedMessage
QuestionFlagSystemMessage
ContactInfoPromptSystemMessage
ContactInfoConfirmSystemMessage
TranslationNoticeSystemMessage
Question solved
Triggered when the user accepts the answer.
DirectlyRTM("onSolved", function(solvedData) {
// Do something
});
// Sample solvedData value:
{
questionUuid: "b34ff943-366d-4be9-8d65-c614743959c5"
questionStatus: 1
dateCreated: "2021-01-21T20:56:45Z"
}
The callback function passed to onSolved
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
questionUuid | n/a | string | Unique ID of the question |
questionStatus | n/a | number | A number from 0 to 7 that indicates the status. Should always be 1, which is solved. |
dateCreated | n/a | string | Timestamp of question creation in ISO 8601 format (e.g. 2021-01-21T19:57:23Z) |
Answer rated
Triggered when the user rates the answer.
DirectlyRTM("onRated", function(ratingData) {
// Do something
});
// Sample ratingData value:
{
rating: "POSITIVE_3"
sentiment: "positive"
responseUuid: "66aa7481-1a59-4208-bc16-4afec1cf0556"
questionUuid: "b34ff943-366d-4be9-8d65-c614743959c5"
questionStatus: 1
dateCreated: "2021-01-21T20:56:46Z"
}
The callback function passed to onRated
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
rating | n/a | string | Rating the user gave to the answer. Possible values are "POSITIVE_3" or "NEUTRAL_3" |
sentiment | n/a | string | Sentiment of the rating. Value can be "positive", "neutral", or "negative". |
responseUuid | n/a | string | Unique ID of the response |
questionUuid | n/a | string | Unique ID of the question |
questionStatus | n/a | number | A number from 0 to 7 that indicates the status. 0 is unresolved/open and 1 is resolved. |
dateCreated | n/a | string | Timestamp of question creation in ISO 8601 format (e.g. 2021-01-21T19:57:23Z) |
Question rerouted
Triggered when the question is rerouted by the poster, the expert, or the system.
DirectlyRTM("onReroute", function(rerouteData) {
// Do something
});
// Sample rerouteData value:
{
questionStatus: 0
questionUuid: "27888245-0c8f-4f34-84e3-9b9d1597cb01"
reroutedByExpert: true
reroutedByPoster: false
rerouteReason: "Requires user account details"
rerouteReasonLabel: "Account",
rerouteReasonCode: "account",
dateCreated: "2021-01-21T22:48:54Z"
}
The callback function passed to onReroute
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
rerouteReason | n/a | string | Explanation of reroute. Can be written by the expert or set by the system. |
reroutedByPoster | n/a | boolean | Whether the question was rerouted by the poster |
reroutedByExpert | n/a | boolean | Whether the question was rerouted by the expert |
questionUuid | n/a | string | Unique ID of the question |
questionStatus | n/a | number | A number from 0 to 7 that indicates the status. Should always be 0, which is unresolved. |
dateCreated | n/a | string | Timestamp of question creation in ISO 8601 format (e.g. 2021-01-21T19:57:23Z) |
Here are the general buckets for reroutes, although there are various subtypes and rerouteReason
s within each bucket:
- Reroute by poster
- Reroute by expert
- Reroute by time
- Reroute by language
- Reroute by lack of experts
Question rejected
Triggered when the system rejects the question for various reasons, including matching keywords or personally identifiable information.
DirectlyRTM("onRejection", function(rejectionData) {
// Do something
});
// Sample rejectionData value:
{
rejectionType: "QuestionRejectedByKeywordSystemMessage"
questionUuid: "6f4df026-16dc-495e-a475-6a3eb8eff05c"
questionStatus: 0
dateCreated: "2021-01-21T23:27:12Z"
}
The callback function passed to onRejection
will have access to the following parameters:
Parameters
Name | Param Type | Data Type | Description |
---|---|---|---|
rejectionType | n/a | string | Type of rejection |
questionUuid | n/a | string | Unique ID of the question |
questionStatus | n/a | number | A number from 0 to 7 that indicates the status. 0 is unresolved/open and 1 is resolved. |
dateCreated | n/a | string | Timestamp of question creation in ISO 8601 format (e.g. 2021-01-21T19:57:23Z) |
Here are the possible rejectionType
s:
RejectedByKeywordQuestionNotification
RejectedByDomainQuestionNotification
RejectedByPredictiveRoutingQuestionNotification
RejectedByUserBlockedQuestionNotification
RejectedByMetadataQuestionNotification
RejectedByIpAddressQuestionNotification
RejectedByBudgetQuestionNotification
RejectedQuestionNotification
i18n
The RTM widget supports internationalization (18n). You can specify a language to use or let the widget use browser detection.
For example, to render the widget in Spanish:
<script>
(function(d, i, r, e, c, t, l, y) {
...
})(document, window, "DirectlyRTM", "https://app.directly.com/widgets/rtm/embed.js");
DirectlyRTM("config", {
id: "your-rtm-widget-uuid",
lang: "es"
});
</script>
Languages must be specified in ISO 639-1 format.
The supported languages are at the moment:
- English - en
- Spanish - es
- German - de
- Dutch - nl
- Chinese - zh
- Korean - ko
- Japanese - ja
- Italian - it
- French - fr
- Portuguese - pt
- Russian - ru
- Turkish - tr
Check with your Account Manager about adding more languages.
Text customization
You can customize the RTM texts to adapt the experience for your users.
<script>
DirectlyRTM("config", {
id: "your-rtm-widget-uuid",
i18n: {
es: {
button: {
ask_our_experts: "Preguntar...",
send_to_our_experts: "Enviar a los expertos",
},
header: {
how_can_we_help_you: "Como podemos ayudarte?"
}
},
de: {
button: {
ask_our_experts: "Hilfe\nnötig?",
send_to_our_experts: "An unsere Experten senden",
},
header: {
how_can_we_help_you: "Wie können wir helfen?"
}
}
}
});
</script>
Check the reference for a comprehensive list of strings you can customize.
Examples
Basic integration
To get RTM working out of the box, you can just drop the following code (with your config.id
) to your html page.
<script>
(function(d, i, r, e, c, t, l, y) {
i[r] = i[r] || function () {
(i[r].cq = i[r].cq || []).push(arguments)
};
l = d.createElement("script");
l.id = "directlyRTMScript";
l.src = e;
l.async = 1;
y = d.head || d.getElementsByTagName("head")[0];
if (d.readyState === "complete" || d.readyState === "loaded" || d.readyState === "interactive") {
y.appendChild(l);
} else if (i.addEventListener) {
i.addEventListener("DOMContentLoaded", function() { y.appendChild(l); });
} else {
i.attachEvent("onload", function() { y.appendChild(l); });
}
})(document, window, "DirectlyRTM", "https://app.directly.com/widgets/rtm/embed.js");
DirectlyRTM("config", {
id: "your-rtm-widget-uuid"
});
</script>
On page load, the widget will display at the bottom right corner.
Full configuration
<script>
(function(d, i, r, e, c, t, l, y) {
i[r] = i[r] || function () {
(i[r].cq = i[r].cq || []).push(arguments)
};
l = d.createElement("script");
l.id = "directlyRTMScript";
l.src = e;
l.async = 1;
y = d.head || d.getElementsByTagName("head")[0];
if (d.readyState === "complete" || d.readyState === "loaded" || d.readyState === "interactive") {
y.appendChild(l);
} else if (i.addEventListener) {
i.addEventListener("DOMContentLoaded", function() { y.appendChild(l); });
} else {
i.attachEvent("onload", function() { y.appendChild(l); });
}
})(document, window, "DirectlyRTM", "https://app.directly.com/widgets/rtm/embed.js");
DirectlyRTM("config", {
id: "your-rtm-widget-uuid",
displayAskQuestion: true,
questionCategory: "your-question-category",
metadata: {
foo: "bar",
page: {
url: "http://example.com",
existingUser: true
}
}
});
</script>
User data prepropulated
If you are using RTM in pages where your users are already logged in, you can prepopulate the user information so RTM won't ask for it.
<script>
(function(d, i, r, e, c, t, l, y) {
...
})(document, window, "DirectlyRTM", "https://directly.com/widgets/rtm/embed.js");
DirectlyRTM("config", {
id: "your-rtm-widget-uuid",
displayAskQuestion: true,
questionCategory: "your-question-category",
metadata: {
foo: "bar",
page: {
url: "http://example.com",
existingUser: true
}
},
userName: "John Doe",
userEmail: "john.doe@directly.com"
}
</script>
Use your own custom form
You can send users to an RTM experience from your custom form. A common use case is sending only some categories of questions to RTM.
This can be done by calling the askQuestion
command.
<!DOCTYPE html>
<html>
<head>
<title>Sample RTM Form</title>
</head>
<body>
<form onsubmit="submitForm()">
<!-- Your form content -->
</form>
<script>
(function(d, i, r, e, c, t, l, y) {
i[r] = i[r] || function() {
(i[r].cq = i[r].cq || []).push(arguments)
};
l = d.createElement("script");
l.id = "directlyRTMScript";
l.src = e;
l.async = 1;
y = d.head || d.getElementsByTagName("head")[0];
if (d.readyState === "complete" || d.readyState === "loaded" || d.readyState === "interactive") {
y.appendChild(l);
} else if (i.addEventListener) {
i.addEventListener("DOMContentLoaded", function() { y.appendChild(l); });
} else {
i.attachEvent("onload", function() { y.appendChild(l); });
}
})(document, window, "DirectlyRTM", "https://app.directly.com/widgets/rtm/embed.js");
DirectlyRTM("config", {
id: "your-rtm-widget-uuid",
displayAskQuestion: false
});
function submitForm() {
DirectlyRTM("askQuestion", {
questionText: "How can I merge two accounts?",
name: userName,
email: userEmail,
questionCategory: valueSelectedFromFormDropdown
});
}
</script>
</body>
</html>
When the user submits a question on the form, it'd send that question to the RTM widget and pop it up.
Contact
If you have any questions about integrating Directly, please contact your Account Manager.