Widget: installation and control from the page

The snippet, dashboard settings, the visitor's entrance and domains, plus commands from the site, events, the invitation and analytics goals.

The snippet #

The script is added once before </body>. Everything else (colour, texts, sound, icon, channels) comes from the server by data-widget-id and is changed in the dashboard without touching the page.

Example call
<script async
  src="https://api.widgetchat.ru/widget/bozex-support-widget.js"
  data-widget-id="wc_9qA…Lk"
></script>

One widget per page. The script is async: it does not block rendering and does not wait for the page to load.

What the widget requests #

GET /widget/config/{widgetId}

The look and the texts. The answer is allowed only for the domains declared in the site card: another page carrying your widget id gets no settings.

Response
{"widgetId": "wc_9qA…Lk", "workspaceKey": "example-ru",
 "apiUrl": "https://api.widgetchat.ru",
 "tokenUrl": "https://api.widgetchat.ru/widget/token/wc_9qA…Lk",
 "appearance": {"color": "#07aa46", "title": "Message us", … }}

The visitor's entrance #

GET /widget/token/{widgetId}?deviceId=…

The widget fetches a signed window token itself and works with it. The token is bound to the site's workspace and lives for a limited time; the visitor is recognised by their device, so the history survives between visits.

There is no programmatic visitor identification yet (passing your own name, email or customer id from the page code). Visitor details appear in a conversation only if the site itself passed them when issuing the token on its side.

Domains #

The list of domains is set in the site card. A widget on an undeclared domain is refused the settings request: that protects you from another page installing your widget id.

Control from the page: commands from the site #

The widget puts a window.WidgetChat object on the page. Use it to open and close the window, show an invitation and subscribe to events. Do not rely on our markup ids: they are internal and change.

CommandWhat it does
WidgetChat.open()Open the chat window
WidgetChat.open({ message: 'text' })Open it and put a prepared question into the input
WidgetChat.close()Close the window
WidgetChat.toggle()Open or close, depending on the current state
WidgetChat.isOpen()true when the window is open
WidgetChat.unreadCount()How many replies the visitor has not read
WidgetChat.showInvite('text')Show the invitation right now
WidgetChat.hideInvite()Remove the invitation
WidgetChat.attention()Make the button call for attention; attention(false) stops it
WidgetChat.on('open', fn)Subscribe to an event; off removes the subscription
WidgetChat.ready(fn)Run once the widget is ready
Example call
<button id="ask">Message us</button>
<script>
  document.getElementById('ask').addEventListener('click', function () {
    WidgetChat.open({ message: 'A question about delivery' })
  })
</script>

The button is clicked before the widget loads #

The widget file loads asynchronously, so for the first seconds the object is not on the page yet. If your button can be clicked during that time, declare a queue stub before the widget snippet: the widget picks it up at start and runs the collected commands.

Example call
<script>
  window.WidgetChat = window.WidgetChat || { q: [] };
  ['open', 'close', 'toggle', 'showInvite', 'hideInvite', 'attention'].forEach(function (name) {
    WidgetChat[name] = WidgetChat[name] || function () {
      WidgetChat.q.push([name, [].slice.call(arguments)]);
    };
  });
</script>

A queued command runs once, when the window is built. There is no need to repeat it.

Events #

Every event arrives two ways: in a WidgetChat.on('name', fn) handler and on window as widgetchat:name. The second one is handy when your code runs before the widget or lives in another script.

EventWhen it firesPayload
readyThe widget is built and accepts commandsversion
openThe window was opened, by a person or by your commandempty
closeThe window was closedempty
inviteThe invitation was showntext
sentThe visitor's message was accepted by the serverfirst: whether it is the first one
messageSupport repliedtext, from
unreadThe number of unread replies changedcount
goalThe widget sent a goal to the site's analyticsgoal, params
Example call
window.addEventListener('widgetchat:sent', function (event) {
  if (event.detail.first) console.log('first conversation from this page')
})

Invitation to a conversation #

After the given delay a bubble with your text appears next to the button, and the button starts calling for attention. Clicking the bubble opens the chat, the cross dismisses it.

By default the widget stays silent. The invitation is switched on in the dashboard, on the Invitation step, together with its delay and text. Attributes on the script tag win over the dashboard setting: use them to invite earlier and in different words on a particular page, a checkout for example.

AttributeValue
data-invite-delaySeconds before the invitation shows. Without the attribute the widget stays silent; 1 to 300 is allowed
data-invite-textThe invitation text. Without it the widget speaks its own words in the visitor's language
Example call
<script async
  src="https://api.widgetchat.ru/widget/bozex-support-widget.js"
  data-widget-id="wc_9qA…Lk"
  data-invite-delay="15"
  data-invite-text="We can help with stock and delivery dates"
></script>

The invitation shows once per tab and never on top of an open chat or a fresh reply. A dismissal is remembered for the visit; until the visitor opens the chat the widget writes nothing to the browser.

Goals for analytics #

The widget sends goals to the counters already present on the page: Yandex.Metrica via reachGoal, Google Tag Manager via dataLayer and gtag. The counter number is not needed: Metrica knows its own counters. In the Metrica dashboard create the goal as a JavaScript event with the same identifier.

GoalWhen it fires
widgetchat_openThe visitor opened the chat window
widgetchat_first_messageThe visitor's first message, which starts the conversation
widgetchat_messageEvery message from the visitor
widgetchat_replySupport replied
widgetchat_invite_shownThe invitation was shown
widgetchat_invite_clickThe invitation was accepted
widgetchat_closeThe window was closed
Example call
<script async
  src="https://api.widgetchat.ru/widget/bozex-support-widget.js"
  data-widget-id="wc_9qA…Lk"
  data-metrika-id="12345678"
  data-goals="off"
></script>

data-metrika-id is only needed when the page carries several counters and the goals must go to a particular one. data-goals="off" turns the sending off completely.