Skip to content

Widget reference

<script src="https://cdn.app.eshasan.com/airfone/widget/widget.js" data-key="af_pk_..." async></script>

The widget renders in a shadow root, so your page’s CSS does not affect it. It is about 8 KB gzipped. Voice code loads only when a visitor presses Talk.

Attribute Values Default
data-key Your publishable key. Required.
data-language en or ne The language set in the console
data-position right or left right
data-color Any CSS color, for the launcher and your visitor’s messages Theme color from the console
data-open true opens the panel on load false
data-launcher false hides the bubble, so you can open it from your own button true
data-api API base, only for testing against another environment https://api.airfone.app

You can also set window.AirFoneSettings = { key, language, api } before the script loads.

After the script loads, window.AirFone has:

Method What it does
AirFone.open() Opens the panel and starts a session.
AirFone.close() Closes the panel.
AirFone.toggle() Opens or closes.
AirFone.identify({ userId, userHash, name, phone, email }) Links the visitor to a known customer.
AirFone.setLanguage('ne') Switches the widget’s language.
AirFone.on(event, handler) Listens for an event. Returns a function that stops listening.
AirFone.shutdown() Removes the widget and closes its connections.

Before the script loads, push calls onto an array and they run in order once it does:

<script>
window.AirFone = window.AirFone || [];
window.AirFone.push(['setLanguage', ['ne']]);
</script>

Without verification, anyone could claim to be any customer. So identify needs userHash: the hex HMAC-SHA256 of userId, keyed with your identity secret from the console. Compute it on your server, never in the browser.

import hmac, hashlib
user_hash = hmac.new(IDENTITY_SECRET.encode(), user_id.encode(), hashlib.sha256).hexdigest()
$userHash = hash_hmac('sha256', $userId, getenv('AIRFONE_IDENTITY_SECRET'));

A visitor with a valid hash is linked to the AirFone contact with that external id, and the assistant can use their records. A wrong hash is ignored: the visitor continues as a guest.

Set color, position, corner radius, greeting and the assistant’s display name in the console under Widget. The preview there uses the real widget. data-color and data-position on the tag win over the console. The panel follows the visitor’s light or dark setting.

Event Detail
ready The widget is on the page.
open, close The panel opened or closed.
message A message was sent or received. Detail is the message.
call.start, call.end A voice call started or ended.
error Something failed. Detail is the error.
AirFone.on('call.end', () => analytics.track('assistant_call'));

The panel is a labelled dialog. Focus moves into it when it opens, Tab stays inside it, and Escape closes it and returns focus. New messages are announced to screen readers. On screens narrower than 520 px the panel fills the screen.

To build your own interface, use @airfone/web, the client the widget is built on:

import { AirFoneClient } from '@airfone/web';
const client = new AirFoneClient({ publishableKey: 'af_pk_...' });
client.on((event) => console.log(event));
await client.send('Do you have rooms on Friday?');
const call = await client.startVoice((state) => console.log(state));