@kavchat/widget 0.0.1 → 0.0.3

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 CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  The embeddable chat that your visitors see on your website. It loads the bot you published in the
4
4
  Kavchat dashboard and runs the whole conversation in the browser with the shared `@kavchat/core` engine.
5
- No LLM, no third-party requests, about 19 KB gzip.
5
+ No LLM, no third-party requests, about 22 KB gzip (live chat with a representative is a separate file, loaded only
6
+ when it is turned on).
6
7
 
7
8
  ## Install
8
9
 
@@ -20,7 +21,7 @@ The public key (`pk_live_...`) is safe to put in a page. Never put the secret ke
20
21
  |---|---|---|
21
22
  | `data-key` | (required) | Your public key. |
22
23
  | `data-api` | `https://api.kavchat.com` | API base URL. |
23
- | `data-locale` | the browser language | Language of the widget chrome (buttons, form, notices): `he`, `en`, `ar`, `ru`, `es`, `fr`, `de`, `pt`, `it`, `tr`. If the language has no translation, the bot locale is used. The script content is always shown as you wrote it. `he` and `ar` render right to left. |
24
+ | `data-locale` | the browser language | Language of the widget chrome (buttons, form, notices): `he`, `en`, `ar`, `ru`, `es`, `fr`, `de`, `pt`, `it`, `tr`, `th`. If the language has no translation, the bot locale is used. The script content is always shown as you wrote it. `he` and `ar` render right to left. |
24
25
  | `data-user-token` | none | Identity token for a signed-in user (see below). |
25
26
  | `data-user-name` | none | Shown in the greeting (`{name}`) and prefilled in the contact form. |
26
27
  | `data-open` | `false` | `"true"` opens the chat as soon as it loads. |
@@ -42,7 +43,7 @@ Kavchat.init({
42
43
  { id: 'orders', label: 'My orders' },
43
44
  { id: 'product', label: 'Product page', needsTarget: true },
44
45
  ],
45
- onEvent(event) {}, // optional: ready, unavailable, open, close, effect, ticket
46
+ onEvent(event) {}, // optional: ready, unavailable, open, close, effect, ticket, live
46
47
  });
47
48
  Kavchat.open();
48
49
  Kavchat.close();
@@ -82,6 +83,7 @@ and runs the call immediately, so the same code works in both cases.
82
83
  | `open`, `close` | | The panel opened or closed. |
83
84
  | `effect` | `effect` | A button asked for the contact form, a link or a screen. |
84
85
  | `ticket` | `id`, `number` | A contact request was created. |
86
+ | `live` | `state`, `id` | The live chat with a representative changed state: `queued`, `active`, `closed` or `ticket`. |
85
87
 
86
88
  ### Script actions
87
89
 
@@ -128,10 +130,43 @@ its styles into its own Shadow DOM `<style>` element; if your CSP restricts `sty
128
130
  * **Isolation**: everything renders inside a Shadow DOM. Your CSS does not reach the widget and the widget's CSS does not reach your page.
129
131
  * **Caching**: the published bot is saved in `localStorage` per public key with its ETag. Each load sends `If-None-Match`; when nothing changed the server answers 304. When the network is down the saved copy is used and a notice is shown.
130
132
  * **Sessions**: a random session id is kept in `sessionStorage`, so moving between pages keeps the same conversation.
133
+ * **Live chat**: an open chat with a representative is kept in `localStorage` (see above) and restored on the next page.
131
134
  * **Analytics**: the conversation path is reported about 2 seconds after each action, and on page hide with `fetch(..., { keepalive: true })`.
132
135
  * **Free plan**: the "Powered by Kavchat" badge is shown unless your plan removes branding.
133
136
  * **Accessibility**: the panel is a labelled dialog, focus moves into it and back, Esc closes it, buttons are real buttons, new bot messages are announced, and motion is reduced when the visitor asks for it.
134
137
 
138
+ ## Live chat with a representative
139
+
140
+ There is nothing to configure on your site. When live chat is turned on in the dashboard (the release has
141
+ `liveChat.enabled`), the widget loads a second file, `kavchat-live.js`, from the same CDN folder and the same
142
+ version as `kavchat.js` (`kavchat.<rev>.js` loads `kavchat-live.<rev>.js`). Sites without live chat never download it.
143
+ The protocol is in `docs/live-chat-protocol.md`; the state, ordering and texts come from `@kavchat/core`.
144
+
145
+ * **The option**: next to "Talk to our team" the bot shows "Talk to a representative", only after
146
+ `GET /live/availability` says a representative is available (checked again after 30 seconds). When the team is
147
+ outside business hours or everyone is busy, only the contact form is offered, with a short line saying why (and
148
+ when the team is back, when known). When the monthly quota is used up, the form is shown without an explanation.
149
+ * **The request**: guests leave an email or a phone (in case nobody answers in time), a name and an optional
150
+ first message, and choose a department when more than one is open. Signed-in users (`userToken`) skip the
151
+ contact fields; the token goes in the request body. If nobody can take the chat, the contact form opens with
152
+ what the visitor already typed.
153
+ * **Waiting**: "Waiting for a representative" with a countdown to the server's wait limit, "Leave a message
154
+ instead", and "End chat". Messages can be sent while waiting. When the time is up the chat becomes a request
155
+ automatically, and the visitor sees that nobody was free in time and the request number.
156
+ * **The chat**: the agent's name, messages, typing indicator, transfers to another agent ("X joined the chat"),
157
+ end chat. Everything from the server is rendered as plain text (`textContent`), never as HTML or links.
158
+ New agent messages and system lines are announced to screen readers; the launcher shows a dot for messages that
159
+ arrive while the panel is closed.
160
+ * **Real time**: Server-Sent Events with a single-use stream ticket, then automatic reconnects with backoff
161
+ (1, 2, 4, 8, 16, 30 seconds, plus or minus 30%) and a sync of everything after the last sequence number, so
162
+ nothing is lost or shown twice. When `EventSource` is missing or the stream is blocked (three failures in a row),
163
+ it falls back to long-poll. Each message has a client id, so retries never create duplicates; a message shows
164
+ as sending, and a failed one can be retried with a tap.
165
+ * **No preflight**: live calls send no custom headers at all; POST bodies are JSON strings (sent as `text/plain`).
166
+ * **Reload**: the chat credential is kept in `localStorage` per public key and conversation (never in a URL), for
167
+ up to 12 hours or until the chat ends, so a reload or a new page restores the whole chat: the bot part, then the
168
+ conversation with the representative.
169
+
135
170
  ## AI answers (Premium)
136
171
 
137
172
  There is nothing to configure on your site. When AI answers are turned on in the dashboard (on your own
@@ -155,7 +190,7 @@ widget.open();
155
190
  ## Development
156
191
 
157
192
  ```bash
158
- yarn build # dist/kavchat.js (IIFE for the CDN) and dist/index.mjs (ESM)
193
+ yarn build # dist/kavchat.js and dist/kavchat-live.js (IIFE for the CDN), dist/index.mjs (ESM)
159
194
  yarn test # vitest + jsdom
160
195
  yarn tsc --noEmit
161
196
  ```