@onedeskpro/chatbot-core 0.1.0 → 0.2.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
@@ -1,6 +1,6 @@
1
1
  # @onedeskpro/chatbot-core
2
2
 
3
- Framework-independent core for the [Onedesk Pro](https://onedeskpro.com) chatbot. Ships the chat engine, the session manager, the API client, and a self-contained widget you can drop into any page — no framework required.
3
+ Framework-independent core for the [Onedesk Pro](https://onedeskpro.com) chatbot. Ships the chat engine, visitor identification, AI-to-human handoff, the API and socket clients, and a self-contained widget you can drop into any page — no framework required.
4
4
 
5
5
  Using React? Install [`@onedeskpro/chatbot-react`](https://www.npmjs.com/package/@onedeskpro/chatbot-react) instead.
6
6
 
@@ -28,7 +28,36 @@ await chatbot.init({
28
28
  });
29
29
  ```
30
30
 
31
- `init` mounts the widget and connects to the Onedesk Pro API. Only `apiKey` is required.
31
+ `init` mounts the widget and connects to the Onedesk Pro API. Only `apiKey` is required — use the publishable workspace API key, never a server secret.
32
+
33
+ ### Visitor identification
34
+
35
+ A visitor must identify with a name and phone number before chatting. The widget shows its own form for this (name, phone with a country picker, optional email), so with the built-in UI there is nothing to wire up.
36
+
37
+ On success the API returns a visitor token. The SDK stores it and verifies it on the next `init`, so a returning visitor goes straight to the chat. While `getState().needsIdentify` is `true`, nothing is sent and `sendMessage` rejects.
38
+
39
+ If you build your own UI, collect the details yourself and call `submitIdentify`:
40
+
41
+ ```ts
42
+ await chatbot.submitIdentify({
43
+ name: 'Ada Lovelace',
44
+ phone: '+8801712345678', // international format, with country code
45
+ email: 'ada@example.com', // optional
46
+ });
47
+ ```
48
+
49
+ ### Human handoff
50
+
51
+ Every conversation runs in one of four modes, exposed as `getState().mode`:
52
+
53
+ | Mode | Meaning |
54
+ | --- | --- |
55
+ | `ai` | The AI agent is answering. This is the default. |
56
+ | `waiting` | A human was requested and no agent has picked the conversation up yet. |
57
+ | `human` | A human agent is replying. Their messages arrive live with `type: 'agent'`. |
58
+ | `closed` | The conversation was closed. Sending is disabled until `resetSession()`. |
59
+
60
+ The widget shows a "Request human agent" control once a conversation has started, and a banner for the `waiting`, `human`, and `closed` modes. From your own UI call `requestHuman()`. The mode also changes on its own — when the AI escalates, an agent takes over, hands back to the AI, or closes the conversation — so follow the `ticket-status` or `state-change` event rather than assuming the result of your own call.
32
61
 
33
62
  ### Script tag / CDN
34
63
 
@@ -50,12 +79,14 @@ The IIFE build exposes a `window.OnedeskProChatbot` global:
50
79
  | Method | Description |
51
80
  | --- | --- |
52
81
  | `init(options)` | Mounts the widget and loads remote config. Returns a promise. |
53
- | `sendMessage(text)` | Sends a message and appends the reply. Returns a promise. |
82
+ | `submitIdentify({ name, phone, email? })` | Identifies the visitor and unlocks the chat. Returns a promise. |
83
+ | `sendMessage(text)` | Sends a message and, in `ai` mode, appends the reply. Returns a promise that rejects if the visitor has not identified. |
84
+ | `requestHuman()` | Escalates the conversation to a human agent. Does nothing unless the mode is `ai` and a conversation has started. Returns a promise. |
54
85
  | `open()` / `close()` / `toggle()` | Control widget visibility. |
55
- | `resetSession()` | Clears the conversation and starts a new session. |
86
+ | `resetSession()` | Clears a `closed` conversation so the visitor can start a new one. Does nothing in any other mode. |
56
87
  | `getState()` | Returns a readonly `ChatbotState` snapshot. |
57
88
  | `on(event, listener)` | Subscribes to an event. Returns an unsubscribe function. |
58
- | `destroy()` | Unmounts the widget and releases listeners. |
89
+ | `destroy()` | Unmounts the widget, disconnects the socket, and cancels any in-flight `init`. |
59
90
 
60
91
  ### Options — `ChatbotInitOptions`
61
92
 
@@ -70,19 +101,37 @@ The IIFE build exposes a `window.OnedeskProChatbot` global:
70
101
  | `welcomeMessage` | `string` | — |
71
102
  | `placeholder` | `string` | — |
72
103
  | `autoOpen` | `boolean` | `false` |
73
- | `sessionId` | `string` | generated and persisted |
74
104
  | `requestTimeoutMs` | `number` | `30000` |
75
105
 
106
+ `sessionId` is deprecated and ignored: visitor tokens replace client session ids.
107
+
108
+ ### State — `ChatbotState`
109
+
110
+ | Field | Type | Meaning |
111
+ | --- | --- | --- |
112
+ | `isOpen` | `boolean` | The panel is showing. |
113
+ | `isLoading` | `boolean` | A send, identify, or human request is in flight. |
114
+ | `isReady` | `boolean` | Config loaded and the agent can answer. |
115
+ | `needsIdentify` | `boolean` | The visitor has not identified yet. |
116
+ | `blockReason` | `ChatbotBlockReason` | Why the agent cannot answer, or `null`. |
117
+ | `messages` | `ChatMessage[]` | The conversation so far. `message.type` is `'human'`, `'ai'`, or `'agent'`. |
118
+ | `visitorToken` | `string \| null` | The identified visitor's token. |
119
+ | `visitorName` | `string \| null` | The identified visitor's name. |
120
+ | `mode` | `ChatbotTicketMode` | `'ai'`, `'waiting'`, `'human'`, or `'closed'`. |
121
+ | `error` | `string \| null` | The last error message. |
122
+
76
123
  ### Events — `ChatbotEventMap`
77
124
 
78
125
  | Event | Payload | Fires when |
79
126
  | --- | --- | --- |
80
- | `message` | `ChatMessage` | A message is added — human and AI alike. |
127
+ | `message` | `ChatMessage` | A message is added — visitor, AI, and human agent alike. |
81
128
  | `state-change` | `ChatbotState` | Any state changes, including `isLoading` while a reply is in flight. |
82
129
  | `ready` | — | Init finished and readiness has been checked. |
83
130
  | `open` / `close` | — | The panel is shown or hidden. |
84
- | `error` | `Error` | A send failed, including on timeout. |
85
- | `session-reset` | — | The conversation was cleared. |
131
+ | `ticket-status` | `TicketStatusData` | The mode changed — on restore, after a send, or pushed live. |
132
+ | `human-requested` | — | `requestHuman()` succeeded. |
133
+ | `error` | `Error` | A send, identify, or human request failed (including on timeout), or the live connection could not be established. |
134
+ | `session-reset` | — | A closed conversation was cleared. |
86
135
 
87
136
  Prefer `state-change` when you are mirroring state into your own UI — it is the only event that covers every transition.
88
137
 
@@ -93,13 +142,29 @@ off(); // unsubscribe
93
142
 
94
143
  ## Also exported
95
144
 
96
- `ApiClient`, `EventEmitter`, `SessionManager`, `DEFAULT_API_BASE_URL`, `DEFAULT_REQUEST_TIMEOUT_MS`, the `ChatbotRequestError` type, and every type from `@onedeskpro/chatbot-types`.
145
+ `ApiClient`, `SdkSocket`, `resolveSdkSocketUrl`, `EventEmitter`, `SessionManager`, `isChatbotRequestError`, `DEFAULT_API_BASE_URL`, `DEFAULT_REQUEST_TIMEOUT_MS`, the `ChatbotRequestError` and `SdkSocketConnectOptions` types, and every type from `@onedeskpro/chatbot-types`.
146
+
147
+ `SessionManager` is deprecated. It is now the visitor token store and is kept only so existing imports keep resolving.
97
148
 
98
149
  ## Notes
99
150
 
100
- Requests abort after `requestTimeoutMs` (30s by default) and surface as an `error` event with `code: 'TIMEOUT'`, so a hung network never leaves the widget stuck. Errors thrown by the client carry `status` and a structured `apiError`.
151
+ Requests abort after `requestTimeoutMs` (30s by default) and surface as an `error` event with `code: 'TIMEOUT'`, so a hung network never leaves the widget stuck. Errors thrown by the client carry `status` and a structured `apiError`; narrow them with `isChatbotRequestError`.
152
+
153
+ The visitor token persists in `localStorage`, scoped per agent, where storage is available and falls back to in-memory when it is not — private browsing, blocked site data, or a sandboxed iframe. A token the API no longer accepts is discarded and the visitor is asked to identify again.
154
+
155
+ Once the visitor has identified, the SDK opens a Socket.IO connection to the API for live mode changes and human agent messages. It reconnects on its own and re-reads the mode when it does.
156
+
157
+ Earlier messages are not restored on reload. A returning visitor keeps their identity and mode but starts with an empty message list.
158
+
159
+ ## Upgrading from 0.1
160
+
161
+ 0.2.0 is a breaking release. The API no longer accepts the `sessionId`-based chat requests that 0.1 sends, so 0.1 cannot chat against the current API.
101
162
 
102
- Session ids persist in `localStorage` where it is available and fall back to in-memory when it is not — private browsing, blocked site data, or a sandboxed iframe.
163
+ - With the built-in widget, upgrading is enough: the identify form and handoff controls are included.
164
+ - With a custom UI, add an identify step (`needsIdentify` and `submitIdentify`) before the first `sendMessage`, and render `'agent'` messages alongside `'human'` and `'ai'`.
165
+ - `ChatbotState.sessionId` is replaced by `visitorToken`, and the `sessionId` init option is ignored.
166
+ - `ApiClient.fetchHistory` is removed.
167
+ - `resetSession()` now only clears a `closed` conversation.
103
168
 
104
169
  ## License
105
170