@moveo-ai/web-client 0.112.0 → 0.113.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +217 -9
- package/dist/63.min.js.LICENSE.txt +1 -1
- package/dist/752.min.js.LICENSE.txt +1 -1
- package/dist/882.min.js.LICENSE.txt +1 -1
- package/dist/929.min.js.LICENSE.txt +1 -1
- package/dist/audio-client.min.js +1 -1
- package/dist/audio-client.min.js.LICENSE.txt +1 -1
- package/dist/iframe.min.js +1 -1
- package/dist/iframe.min.js.LICENSE.txt +1 -1
- package/dist/index.html +1 -1
- package/dist/preview/index.html +2 -2
- package/dist/preview.css.min.js.LICENSE.txt +1 -1
- package/dist/telnyx-client.min.js +1 -1
- package/dist/telnyx-client.min.js.LICENSE.txt +1 -1
- package/dist/web-client.min.js +1 -1
- package/dist/web-client.min.js.LICENSE.txt +1 -1
- package/dist/webrtc-client.min.js +1 -1
- package/dist/webrtc-client.min.js.LICENSE.txt +1 -1
- package/package.json +8 -9
- package/web-client.d.ts +75 -0
package/README.md
CHANGED
|
@@ -219,8 +219,16 @@ payload listed below.
|
|
|
219
219
|
|
|
220
220
|
`onAnalyticsEvent` receives every interaction the widget tracks, identified by
|
|
221
221
|
the `event` field: `session_start`, `session_end`, `message_sent` (the user sent
|
|
222
|
-
a message — never carries the text), `launcher_clicked`,
|
|
223
|
-
|
|
222
|
+
a message — never carries the text), `launcher_clicked`,
|
|
223
|
+
`teaser_quick_reply_clicked` (a teaser reply the visitor tapped, carrying its
|
|
224
|
+
configured `label`), `teaser_composer_submitted` (the visitor sent their own
|
|
225
|
+
line from the teaser — carries no properties, because the text is theirs),
|
|
226
|
+
`rating_submitted`, and the rest of the `AnalyticsEvent` enum in
|
|
227
|
+
`src/hooks/useAnalytics.ts`.
|
|
228
|
+
|
|
229
|
+
No event carries message text. `properties` is forwarded verbatim by
|
|
230
|
+
integrations to their own analytics vendors, so anything the visitor typed stays
|
|
231
|
+
out of it — only copy the integration itself configured appears there.
|
|
224
232
|
|
|
225
233
|
It also receives one event that is not an interaction: **`widget_loaded`**,
|
|
226
234
|
raised as soon as the widget renders on the page. It carries no `session_id`,
|
|
@@ -324,6 +332,200 @@ MoveoAI.init({
|
|
|
324
332
|
});
|
|
325
333
|
```
|
|
326
334
|
|
|
335
|
+
### Teaser
|
|
336
|
+
|
|
337
|
+
The teaser is the invitation shown beside the closed launcher. `variant` picks
|
|
338
|
+
its shape, and each variant declares only the fields it renders, so a
|
|
339
|
+
placeholder on a variant with no input is a compile error rather than a silent
|
|
340
|
+
no-op.
|
|
341
|
+
|
|
342
|
+
| Variant | Needs | Renders |
|
|
343
|
+
| ---------------- | --------------- | ------------------------------------------------------------------- |
|
|
344
|
+
| `callout` | `message` | The line in the bubble. The default, and the teaser as it is today. |
|
|
345
|
+
| `question_chips` | `quick_replies` | Tappable questions **in place of** the line, at most three. |
|
|
346
|
+
| `composer` | `message` | The line with an input under it. |
|
|
347
|
+
| `none` | — | Launcher only. |
|
|
348
|
+
|
|
349
|
+
```javascript
|
|
350
|
+
MoveoAI.init({
|
|
351
|
+
integrationId: 'YOUR_INTEGRATION_ID',
|
|
352
|
+
teaser: {
|
|
353
|
+
variant: 'question_chips',
|
|
354
|
+
quick_replies: ['Compare products', 'Help me choose'],
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
MoveoAI.init({
|
|
359
|
+
integrationId: 'YOUR_INTEGRATION_ID',
|
|
360
|
+
teaser: {
|
|
361
|
+
variant: 'composer',
|
|
362
|
+
message: 'Tell me what you sell and I will narrow it down.',
|
|
363
|
+
placeholder: 'e.g. a two-till bakery',
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
With no `variant`, replies mean `question_chips` and their absence means
|
|
369
|
+
`callout`, so the shorthand `{ quick_replies: [...] }` keeps working.
|
|
370
|
+
|
|
371
|
+
#### A different teaser per page
|
|
372
|
+
|
|
373
|
+
`teaser.pages[]` varies the teaser by URL. The **first** entry whose `url`
|
|
374
|
+
appears in the page's URL wins, so specific paths belong above general ones, and
|
|
375
|
+
the `teaser` block itself covers everywhere else.
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
MoveoAI.init({
|
|
379
|
+
integrationId: 'YOUR_INTEGRATION_ID',
|
|
380
|
+
teaser: {
|
|
381
|
+
// The block is the teaser wherever no `pages[]` entry matches.
|
|
382
|
+
variant: 'callout',
|
|
383
|
+
message: 'Anything I can help with?',
|
|
384
|
+
pages: [
|
|
385
|
+
{
|
|
386
|
+
url: '/products/flex',
|
|
387
|
+
variant: 'question_chips',
|
|
388
|
+
quick_replies: ['Explain Flex to me', 'Compare Flex and Station Duo'],
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
url: '/shop',
|
|
392
|
+
variant: 'composer',
|
|
393
|
+
message: 'Nine systems here. Tell me what you sell.',
|
|
394
|
+
placeholder: 'e.g. a two-till bakery',
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
`url` is **a hint, not a pattern**: it matches when it appears anywhere in the
|
|
402
|
+
page's URL, compared case-insensitively. Nothing is escaped and nothing is
|
|
403
|
+
compiled, so a stray `.` or `(` cannot change what matches or throw. This is the
|
|
404
|
+
one thing `pages[]` does differently from the `page_triggers` it replaces, whose
|
|
405
|
+
keys were compiled with `new RegExp`.
|
|
406
|
+
|
|
407
|
+
`pages[]` is an array and not a map keyed by URL so that precedence is visible
|
|
408
|
+
to whoever wrote it. `variant: 'none'` on the block, with a `pages[]` entry that
|
|
409
|
+
opts back in, gives a teaser on those pages and nowhere else.
|
|
410
|
+
|
|
411
|
+
**It follows the visitor.** `clientUrl` is read once when the widget loads, so on
|
|
412
|
+
a single-page app it names the page the visitor arrived on for the rest of the
|
|
413
|
+
visit. When `pages[]` is configured the loader watches for navigation and relays
|
|
414
|
+
the new URL, and the teaser re-resolves. An integration that configures no
|
|
415
|
+
`pages[]` is not watched at all, because the watcher patches `history` and never
|
|
416
|
+
restores it.
|
|
417
|
+
|
|
418
|
+
**Chips replace the line, they do not sit under it.** Asking the question and
|
|
419
|
+
offering the answers says the same thing twice, and a bubble above
|
|
420
|
+
content-width chips leaves a ragged edge.
|
|
421
|
+
|
|
422
|
+
**Chips carry no dismiss.** `callout` and `composer` keep theirs, because both
|
|
423
|
+
cover part of the page. A chip is cheap to ignore, and a close control in the
|
|
424
|
+
stack reads as a fourth, broken chip. `close_opening_message_click` therefore
|
|
425
|
+
does not fire for `question_chips`.
|
|
426
|
+
|
|
427
|
+
**A variant degrades rather than rendering an empty surface.**
|
|
428
|
+
`question_chips` with no replies falls back to `callout`; `callout` or
|
|
429
|
+
`composer` with no line resolves to `none`.
|
|
430
|
+
|
|
431
|
+
#### Sending
|
|
432
|
+
|
|
433
|
+
A tapped chip and a typed composer line take the same path: the widget opens
|
|
434
|
+
and the text is sent as the visitor's first message, once the session is ready
|
|
435
|
+
and the visitor form, if any, is done. It replaces the configured
|
|
436
|
+
`welcome_trigger_message` for that conversation, so the visitor's own words
|
|
437
|
+
open it.
|
|
438
|
+
|
|
439
|
+
#### While the visitor is reading
|
|
440
|
+
|
|
441
|
+
A configured teaser steps out of the way as the host page scrolls, and fades
|
|
442
|
+
back a second after it stops. It is out of reach while it is out of sight, so a
|
|
443
|
+
keyboard cannot land on a chip nobody can see.
|
|
444
|
+
|
|
445
|
+
This applies only to an integration that sets a `teaser`. An integration with
|
|
446
|
+
nothing but a `welcome_message` keeps the opening message it has always had,
|
|
447
|
+
sitting still, and no scroll listener is attached to its pages.
|
|
448
|
+
|
|
449
|
+
#### When it appears, and when it gives up
|
|
450
|
+
|
|
451
|
+
Two optional clocks, both **off unless set**, so an integration that configures
|
|
452
|
+
neither behaves exactly as it does today — the teaser appears as soon as it has
|
|
453
|
+
something to say, and stays.
|
|
454
|
+
|
|
455
|
+
```javascript
|
|
456
|
+
MoveoAI.init({
|
|
457
|
+
integrationId: 'YOUR_INTEGRATION_ID',
|
|
458
|
+
teaser: {
|
|
459
|
+
message: 'Anything I can help with?',
|
|
460
|
+
show_after: 8, // wait 8s before inviting
|
|
461
|
+
hide_after: 45, // retire after 45s on screen
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
| Field | Unit | Off | Clamped to | Means |
|
|
467
|
+
| ------------ | ------- | --- | ---------- | ----------------------------------------------------- |
|
|
468
|
+
| `show_after` | seconds | `0` | 1–60 | Wait this long before the teaser appears. |
|
|
469
|
+
| `hide_after` | seconds | `0` | 5–300 | Retire it after this long, for the rest of the visit. |
|
|
470
|
+
|
|
471
|
+
Both are **block-level**, not per-page: they describe the visit, not the page. A
|
|
472
|
+
`pages[]` entry with its own delay would restart the clock on every navigation
|
|
473
|
+
of a single-page app, so the teaser would arrive later on each page and, past a
|
|
474
|
+
few, never at all.
|
|
475
|
+
|
|
476
|
+
`show_after` counts **settled** seconds, and any scroll starts it over: the
|
|
477
|
+
invitation waits for a calm moment rather than arriving in the middle of a
|
|
478
|
+
gesture. The trade is that a visitor who scrolls more often than the delay never
|
|
479
|
+
settles for long enough and never sees the teaser at all — pick the number
|
|
480
|
+
against how the page is actually read, because a long delay on a page people
|
|
481
|
+
scan continuously invites nobody.
|
|
482
|
+
|
|
483
|
+
It is counted from the moment the teaser has something to say, not from the page
|
|
484
|
+
loading — the config arrives over postMessage, so a clock started earlier would
|
|
485
|
+
come out shortest on exactly the slow pages a delay matters on. A
|
|
486
|
+
`showTeaserMessage()` call is never held behind it: the host asking for the
|
|
487
|
+
teaser means now.
|
|
488
|
+
|
|
489
|
+
`hide_after` counts the time the teaser is **on screen**. The clock pauses while
|
|
490
|
+
the visitor scrolls it out of the way and resumes with what is left, so a
|
|
491
|
+
visitor who spent the budget scrolling has not spent it ignoring the teaser.
|
|
492
|
+
Once retired, the teaser is gone for the visit; the launcher is not.
|
|
493
|
+
|
|
494
|
+
A malformed value — negative, non-numeric, infinite — reads as off rather than
|
|
495
|
+
being clamped up to the minimum, so a bad config cannot start hiding a teaser
|
|
496
|
+
the integration can see today.
|
|
497
|
+
|
|
498
|
+
#### The line
|
|
499
|
+
|
|
500
|
+
Precedence, highest first:
|
|
501
|
+
|
|
502
|
+
1. A line handed to **`showTeaserMessage('...')`**, for as long as it is set.
|
|
503
|
+
Calling it with no argument clears the override and hands the teaser back to
|
|
504
|
+
the config.
|
|
505
|
+
2. **`page_triggers[].opening_message`** for this URL.
|
|
506
|
+
3. **`teaser.message`** (or the `pages[]` entry's).
|
|
507
|
+
4. The deprecated top-level **`welcome_message`**.
|
|
508
|
+
|
|
509
|
+
`message` supersedes `welcome_message`, which is still read when `message` is
|
|
510
|
+
absent. The two legacy sources above it stay ahead of `teaser.message` on
|
|
511
|
+
purpose: per-page copy an integration already relies on, or a line the host
|
|
512
|
+
asked for by name, must not be replaced by a default someone adds later.
|
|
513
|
+
|
|
514
|
+
`page_triggers` is **deprecated and frozen**. It still varies the line and the
|
|
515
|
+
auto-sent opener by URL for the five integrations that set it, and it is not
|
|
516
|
+
removed, because one of them is a live customer. New work belongs on
|
|
517
|
+
`teaser.pages[]`.
|
|
518
|
+
|
|
519
|
+
`manual_teaser_mode` and `showTeaserMessage()` keep their meaning.
|
|
520
|
+
|
|
521
|
+
#### Restyling it
|
|
522
|
+
|
|
523
|
+
The teaser follows the accent out of the box. The bubble reads
|
|
524
|
+
`--color-opening-message-background` and
|
|
525
|
+
`--color-opening-message-foreground`, and the chips and the composer field
|
|
526
|
+
read the `--color-options-*` set. All five are in
|
|
527
|
+
[CSS Variables](#css-variables), and are set through `setCSSVariables()`.
|
|
528
|
+
|
|
327
529
|
### Inactivity Timeout
|
|
328
530
|
|
|
329
531
|
The widget opens an inactivity modal once the visitor goes quiet, and asks
|
|
@@ -447,15 +649,21 @@ A colour that says "defaults to" follows `--color-accent` — or the colour name
|
|
|
447
649
|
— until you set it. So an accent alone restyles the links, the rating, the send
|
|
448
650
|
icon and the launcher, and `--color-chat-background` follows the background.
|
|
449
651
|
|
|
450
|
-
|
|
652
|
+
Six more colours have no `theme_colors` key, so they are set through
|
|
451
653
|
`setCSSVariables()` only:
|
|
452
654
|
|
|
453
|
-
| Variable
|
|
454
|
-
|
|
|
455
|
-
| `--color-chat-background`
|
|
456
|
-
| `--color-options-background`
|
|
457
|
-
| `--color-options-foreground`
|
|
458
|
-
| `--color-options-border`
|
|
655
|
+
| Variable | Controls |
|
|
656
|
+
| ------------------------------------ | ------------------------------------------------------------------- |
|
|
657
|
+
| `--color-chat-background` | The area behind the messages; follows the background |
|
|
658
|
+
| `--color-options-background` | Quick reply buttons, and the teaser chips and composer field |
|
|
659
|
+
| `--color-options-foreground` | Quick reply labels, the teaser composer text, and a chip under the pointer or the focus ring; defaults to the accent |
|
|
660
|
+
| `--color-options-border` | Quick reply borders, the teaser composer field, and a chip under the pointer or the focus ring; defaults to the accent |
|
|
661
|
+
| `--color-opening-message-background` | The teaser bubble, on `callout` and `composer`; defaults to the accent |
|
|
662
|
+
| `--color-opening-message-foreground` | The teaser bubble text; defaults to the visitor's own bubble text colour |
|
|
663
|
+
|
|
664
|
+
The two `opening-message` names are the teaser's, from before it was called
|
|
665
|
+
one. They are the only lever that moves the bubble off the accent, so an
|
|
666
|
+
integration whose accent is too dark to invite anybody sets them here.
|
|
459
667
|
|
|
460
668
|
#### Renamed variables
|
|
461
669
|
|