@askly/widget 2.9.0 → 2.10.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 CHANGED
@@ -163,8 +163,8 @@ Askly.init({ appId: "YOUR_APP_ID", greeting: { message: "Need a hand?", delayMs:
163
163
  <script src="…/widget.js" data-app-id="YOUR_APP_ID" data-greeting="false" async></script>
164
164
  ```
165
165
 
166
- The widget dispatches `askly:greeting:shown`, `askly:greeting:clicked` and
167
- `askly:greeting:dismissed` on `window` for analytics.
166
+ For analytics, listen for `greeting:shown`, `greeting:clicked` and `greeting:dismissed` with
167
+ `Askly.on()` (see the JavaScript API below).
168
168
 
169
169
  ### Live replies
170
170
 
@@ -227,7 +227,63 @@ Notes:
227
227
  - **Optimized:** on non-matching pages the path check runs *before* anything mounts, so there's no DOM node, no React root, and no config network request — the SDK does essentially nothing.
228
228
  - The decision is evaluated once at init; it's a UX targeting tool, not a security boundary (the script can still be loaded on any page).
229
229
 
230
- ## Lifecycle Callbacks
230
+ ## JavaScript API
231
+
232
+ Everything below is on the global `Askly` (script tag) or the default export (npm). Calls made
233
+ straight after `Askly.init()` are held and carried out once the widget has mounted.
234
+
235
+ ### Controlling the widget
236
+
237
+ | Method | What it does |
238
+ | :--- | :--- |
239
+ | `Askly.open()` / `Askly.show()` | Open the chat panel. |
240
+ | `Askly.close()` / `Askly.hide()` | Close it. |
241
+ | `Askly.toggle()` | Open if closed, close if open. |
242
+ | `Askly.showSpace(space)` | Open on `"home"`, `"messages"` or `"help"`. |
243
+ | `Askly.showNewMessage(text?)` | Open the chat with the message box focused, optionally pre-filled. Nothing is sent. |
244
+ | `Askly.sendMessage(text)` | Open the chat and send `text` as the visitor. It passes the same checks as a typed message; if one is pending (email required, security check) it waits in the message box. |
245
+ | `Askly.showArticle(id)` | Open a help article by id. |
246
+ | `Askly.update(config)` | Change display settings without re-initialising, e.g. `{ themeColor, theme, organizationName, welcomeMessage, buttonShape }`. |
247
+ | `Askly.isOpen()` | `true` while the panel is open. |
248
+ | `Askly.getUnreadCount()` | Agent replies the visitor has not seen (the launcher badge). |
249
+ | `Askly.getVisitorId()` | This browser's anonymous visitor id (`""` before mount). |
250
+ | `Askly.ready()` | A promise that resolves once the widget has mounted and applied its configuration. |
251
+
252
+ ```javascript
253
+ document.querySelector("#contact-sales").addEventListener("click", () => {
254
+ Askly.showNewMessage("Hi, I'd like to talk about the Business plan.");
255
+ });
256
+ ```
257
+
258
+ ### Events
259
+
260
+ `Askly.on(name, handler)` returns a function that removes the listener; `Askly.off(name, handler)`
261
+ and `Askly.once(name, handler)` are also available. A handler that throws is logged and does not
262
+ affect the widget.
263
+
264
+ | Event | Payload | When |
265
+ | :--- | :--- | :--- |
266
+ | `ready` | `{ visitorId }` | The widget has mounted and applied its configuration. |
267
+ | `open` / `close` | none | The panel was opened or closed. |
268
+ | `message:sent` | `{ text, conversationId }` | The visitor sent a message. |
269
+ | `message:received` | `{ text, conversationId, from, messageId }` | A reply arrived; `from` is `"ai"` or `"agent"`. |
270
+ | `unread` | `{ count }` | The number of unseen agent replies changed. |
271
+ | `escalated` | `{ conversationId }` | The conversation was handed to a human. |
272
+ | `lead:captured` | none | The visitor left an email address. |
273
+ | `identify:success` / `identify:error` | `{ userId, status? }` | The server accepted or refused `identify()`. |
274
+ | `greeting:shown` / `greeting:clicked` / `greeting:dismissed` | none | Greeting bubble activity. |
275
+ | `error` | `{ message, status? }` | A message could not be sent. |
276
+
277
+ ```javascript
278
+ Askly.on("message:received", ({ from }) => analytics.track("support_reply", { from }));
279
+ Askly.on("unread", ({ count }) => { document.title = count ? `(${count}) Acme` : "Acme"; });
280
+ ```
281
+
282
+ TypeScript users can import the payload types: `import type { AsklyEventMap } from "@askly/widget"`.
283
+
284
+ ### Callbacks at init (older style)
285
+
286
+ These still work and are called alongside the events above.
231
287
 
232
288
  Callbacks are functions, so they can only be attached in code (not from the portal):
233
289
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type AsklyEventMap, type AsklyEventName, type AsklyEventHandler, type AsklySpace } from "./core/events";
1
2
  import { type AsklyIdentity } from "./identity";
2
3
  export interface AsklyConfig {
3
4
  appId?: string;
@@ -75,5 +76,42 @@ declare const Askly: {
75
76
  close: () => void;
76
77
  /** Toggle the chat panel. */
77
78
  toggle: () => void;
79
+ /** Aliases of open() / close(). */
80
+ show: () => void;
81
+ hide: () => void;
82
+ /** Whether the chat panel is open right now. */
83
+ isOpen: () => boolean;
84
+ /** Agent replies the visitor has not seen yet (the number on the launcher badge). */
85
+ getUnreadCount: () => number;
86
+ /** This browser's anonymous visitor id, or "" before the widget has mounted. */
87
+ getVisitorId: () => string;
88
+ /**
89
+ * Listen for a widget event. Returns a function that removes the listener.
90
+ *
91
+ * Askly.on("message:received", ({ text, from }) => analytics.track("support_reply", { from }));
92
+ * Askly.on("unread", ({ count }) => setBadge(count));
93
+ */
94
+ on: <K extends keyof AsklyEventMap>(name: K, handler: AsklyEventHandler<K>) => (() => void);
95
+ off: <K_1 extends keyof AsklyEventMap>(name: K_1, handler: AsklyEventHandler<K_1>) => void;
96
+ once: <K_2 extends keyof AsklyEventMap>(name: K_2, handler: AsklyEventHandler<K_2>) => (() => void);
97
+ /** Resolves when the widget has mounted and applied its configuration. */
98
+ ready: () => Promise<void>;
99
+ /** Open the widget on a section: "home", "messages" or "help". */
100
+ showSpace: (space: AsklySpace) => void;
101
+ /** Open the chat with the composer ready, optionally pre-filled. Nothing is sent. */
102
+ showNewMessage: (text?: string) => void;
103
+ /**
104
+ * Open the chat and send a message as the visitor. It goes through the same checks as a
105
+ * typed message; if one is pending (email required, security check) it waits in the composer.
106
+ */
107
+ sendMessage: (text: string) => void;
108
+ /** Open a help article by id, as listed in the Help tab. */
109
+ showArticle: (articleId: string) => void;
110
+ /**
111
+ * Change display settings on the mounted widget without re-initialising: the fields the
112
+ * portal controls, e.g. `{ themeColor, theme, organizationName, welcomeMessage, buttonShape }`.
113
+ */
114
+ update: (config: Record<string, any>) => void;
78
115
  };
79
116
  export default Askly;
117
+ export type { AsklyIdentity, AsklyEventMap, AsklyEventName, AsklyEventHandler, AsklySpace };