@data-netmonk/mona-chat-widget 2.1.37 → 2.3.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 +396 -94
- package/dist/index.cjs +56 -56
- package/dist/index.js +10033 -9911
- package/dist/style.css +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -2,6 +2,83 @@
|
|
|
2
2
|
|
|
3
3
|
Chat widget package developed by Netmonk data & solution team to be imported in Netmonk products
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
### Recent Updates & Breaking Changes
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
**Latest Version Changes:**
|
|
12
|
+
|
|
13
|
+
⚠️ **Breaking Changes:**
|
|
14
|
+
1. **Removed `type` and `agentType` props** - These parameters are no longer used and have been removed from all components
|
|
15
|
+
2. **Renamed `botServerUrl` to `webhookUrl`** - For better clarity and consistency
|
|
16
|
+
3. **`webhookUrl` is now required** - Must be provided as a prop
|
|
17
|
+
4. **`authUrl` and `username` are now direct props** - No longer part of `data` prop for better clarity and type safety
|
|
18
|
+
5. **`userId` is now optional** - Widget automatically generates visitor ID for guest users via browser fingerprinting when `userId` is not provided
|
|
19
|
+
|
|
20
|
+
✨ **New Features:**
|
|
21
|
+
1. **Guest user support** - Users can chat without logging in
|
|
22
|
+
- Automatic visitor ID generation using browser fingerprinting (FingerprintJS + SHA256)
|
|
23
|
+
- `auth: false` flag automatically added to API requests for guest users
|
|
24
|
+
- Persistent sessions across page reloads for anonymous visitors
|
|
25
|
+
2. **Authentication support** - Automatic token management with refresh on 401 errors
|
|
26
|
+
- Pass `authUrl` as a direct prop
|
|
27
|
+
- Widget handles token lifecycle automatically
|
|
28
|
+
3. **Enhanced user authentication handling** - Smart detection of authenticated vs guest users
|
|
29
|
+
- Compares `userId` with visitor ID to determine authentication status
|
|
30
|
+
- Automatic `auth` flag management in all API requests
|
|
31
|
+
4. **Enhanced data prop** - Support for custom variables passed to backend via `data` prop
|
|
32
|
+
5. **Improved error handling** - Better fallback mechanisms and error messages
|
|
33
|
+
6. **Direct `username` prop** - Pass username as a top-level prop instead of in data string
|
|
34
|
+
|
|
35
|
+
📝 **Migration Guide:**
|
|
36
|
+
```jsx
|
|
37
|
+
// Old usage (deprecated)
|
|
38
|
+
<ChatWidget
|
|
39
|
+
userId="user123"
|
|
40
|
+
sourceId="source456"
|
|
41
|
+
type="prime"
|
|
42
|
+
botServerUrl="https://api.example.com"
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
// Previous version (with data prop)
|
|
46
|
+
<ChatWidget
|
|
47
|
+
userId="user123"
|
|
48
|
+
sourceId="source456"
|
|
49
|
+
webhookUrl="https://api.example.com/webhook"
|
|
50
|
+
data="authUrl=https://api.example.com/login/chatwidget~username=John"
|
|
51
|
+
/>
|
|
52
|
+
|
|
53
|
+
// New usage - Authenticated user (current - recommended)
|
|
54
|
+
<ChatWidget
|
|
55
|
+
userId="user123"
|
|
56
|
+
sourceId="source456"
|
|
57
|
+
webhookUrl="https://api.example.com/webhook"
|
|
58
|
+
authUrl="https://api.example.com/login/chatwidget"
|
|
59
|
+
username="John"
|
|
60
|
+
data="email=john@example.com~phone=+1234567890"
|
|
61
|
+
/>
|
|
62
|
+
|
|
63
|
+
// New usage - Guest user (without login)
|
|
64
|
+
<ChatWidget
|
|
65
|
+
sourceId="source456"
|
|
66
|
+
webhookUrl="https://api.example.com/webhook"
|
|
67
|
+
username="Guest"
|
|
68
|
+
/>
|
|
69
|
+
// Widget automatically generates visitor ID and adds auth: false flag
|
|
70
|
+
|
|
71
|
+
// New usage - Conditional (handles both logged-in and guest users)
|
|
72
|
+
<ChatWidget
|
|
73
|
+
userId={currentUser?.id} // undefined for guests
|
|
74
|
+
sourceId="source456"
|
|
75
|
+
webhookUrl="https://api.example.com/webhook"
|
|
76
|
+
username={currentUser?.name || "Guest"}
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
5
82
|
## 🚅 Quick start
|
|
6
83
|
|
|
7
84
|
### Prerequisites
|
|
@@ -10,7 +87,7 @@ Chat widget package developed by Netmonk data & solution team to be imported in
|
|
|
10
87
|
|
|
11
88
|
1. Install dependencies
|
|
12
89
|
```
|
|
13
|
-
npm install
|
|
90
|
+
npm install --legacy-peer-deps
|
|
14
91
|
```
|
|
15
92
|
2. Copy .env.example
|
|
16
93
|
```
|
|
@@ -79,7 +156,7 @@ For responses with buttons:
|
|
|
79
156
|
|
|
80
157
|
---
|
|
81
158
|
|
|
82
|
-
1. **How to run Storybook locally** (access at http://localhost:
|
|
159
|
+
1. **How to run Storybook locally** (access at http://localhost:5177)
|
|
83
160
|
|
|
84
161
|
```
|
|
85
162
|
npm run storybook
|
|
@@ -165,10 +242,9 @@ For responses with buttons:
|
|
|
165
242
|
function App() {
|
|
166
243
|
return (
|
|
167
244
|
<ChatWidget
|
|
168
|
-
type="prime"
|
|
169
245
|
userId="user123"
|
|
170
246
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
171
|
-
|
|
247
|
+
webhookUrl="https://your-backend-url.com"
|
|
172
248
|
/>
|
|
173
249
|
);
|
|
174
250
|
}
|
|
@@ -184,22 +260,17 @@ For responses with buttons:
|
|
|
184
260
|
|
|
185
261
|
| Prop | Type | Description |
|
|
186
262
|
|------|------|-------------|
|
|
187
|
-
| `userId` | `string` | **Required.** Unique identifier for the user |
|
|
188
263
|
| `sourceId` | `string` | **Required.** Source/channel identifier for the chat |
|
|
189
|
-
|
|
190
|
-
#### Dynamic Data Prop (NEW!)
|
|
191
|
-
| Prop | Type | Description |
|
|
192
|
-
|------|------|-------------|
|
|
193
|
-
| `data` | `string` | URL-encoded config string (see advanced usage below) |
|
|
194
|
-
|
|
264
|
+
| `webhookUrl` | `string` | **Required.** Backend webhook URL |
|
|
195
265
|
|
|
196
266
|
#### Optional Props
|
|
197
267
|
|
|
198
268
|
| Prop | Type | Default | Description |
|
|
199
269
|
|------|------|---------|-------------|
|
|
200
|
-
| `
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
270
|
+
| `userId` | `string` | Generated visitor ID | Unique identifier for the user. **Optional** - if not provided, a unique visitor ID is automatically generated using browser fingerprinting for guest users |
|
|
271
|
+
| `authUrl` | `string` | - | Authentication endpoint URL for token-based authentication |
|
|
272
|
+
| `username` | `string` | - | Username for the session (sent to backend in variables) |
|
|
273
|
+
| `data` | `string` | - | Additional custom variables in format `key1=value1~key2=value2` |
|
|
203
274
|
| `width` | `string` | `"25vw"` | Widget width (CSS value) |
|
|
204
275
|
| `height` | `string` | `"90vh"` | Widget height (CSS value) |
|
|
205
276
|
| `right` | `string` | `"1.25rem"` | Distance from right edge |
|
|
@@ -210,11 +281,45 @@ For responses with buttons:
|
|
|
210
281
|
|
|
211
282
|
---
|
|
212
283
|
|
|
284
|
+
### Guest User Support
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
The widget now supports **guest users** (users who haven't logged in or before logging in). When `userId` is not provided, the widget automatically generates a unique visitor ID using browser fingerprinting.
|
|
289
|
+
|
|
290
|
+
**How it works:**
|
|
291
|
+
|
|
292
|
+
1. **Browser Fingerprinting**: Uses FingerprintJS to generate a unique identifier based on:
|
|
293
|
+
- Browser characteristics (user agent, screen resolution, timezone, etc.)
|
|
294
|
+
- Incognito/private browsing detection
|
|
295
|
+
- Combined into a SHA256 hash for consistency
|
|
296
|
+
|
|
297
|
+
2. **Automatic Guest Detection**: The widget automatically detects guest users and:
|
|
298
|
+
- Generates a visitor ID if `userId` is not provided
|
|
299
|
+
- Adds `auth: false` flag to all API requests for guest users
|
|
300
|
+
- Uses the visitor ID as the effective user ID throughout the session
|
|
301
|
+
|
|
302
|
+
3. **Persistent Sessions**: The visitor ID remains consistent across page reloads (unless browser fingerprint changes or user clears data)
|
|
303
|
+
|
|
304
|
+
**When to use guest mode:**
|
|
305
|
+
- Public-facing websites where users can chat without logging in
|
|
306
|
+
- Support widgets for anonymous visitors
|
|
307
|
+
- Pre-login customer service interactions
|
|
308
|
+
- Any scenario where user authentication is optional
|
|
309
|
+
|
|
310
|
+
**When to provide userId:**
|
|
311
|
+
- Users who are logged into your application
|
|
312
|
+
- When you need to track chat history across devices
|
|
313
|
+
- When authentication is required for personalized responses
|
|
314
|
+
- Enterprise or internal applications
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
213
318
|
### Usage Examples
|
|
214
319
|
|
|
215
320
|
---
|
|
216
321
|
|
|
217
|
-
#### Basic Usage
|
|
322
|
+
#### Basic Usage (Authenticated User)
|
|
218
323
|
|
|
219
324
|
```jsx
|
|
220
325
|
import { ChatWidget } from "@data-netmonk/mona-chat-widget";
|
|
@@ -225,33 +330,167 @@ function App() {
|
|
|
225
330
|
<ChatWidget
|
|
226
331
|
userId="user123"
|
|
227
332
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
333
|
+
webhookUrl="https://api.example.com/webhook"
|
|
334
|
+
/>
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### Guest User (Without Login)
|
|
340
|
+
|
|
341
|
+
For anonymous visitors or users who haven't logged in:
|
|
342
|
+
|
|
343
|
+
```jsx
|
|
344
|
+
import { ChatWidget } from "@data-netmonk/mona-chat-widget";
|
|
345
|
+
import "@data-netmonk/mona-chat-widget/dist/style.css";
|
|
346
|
+
|
|
347
|
+
function App() {
|
|
348
|
+
return (
|
|
349
|
+
<ChatWidget
|
|
350
|
+
sourceId="691e1b5952068ff7aaeccffc9"
|
|
351
|
+
webhookUrl="https://api.example.com/webhook"
|
|
228
352
|
/>
|
|
229
353
|
);
|
|
230
354
|
}
|
|
231
355
|
```
|
|
232
356
|
|
|
233
|
-
|
|
357
|
+
**What happens:**
|
|
358
|
+
- Widget automatically generates a visitor ID using browser fingerprinting
|
|
359
|
+
- All API requests include `auth: false` in variables to indicate guest user
|
|
360
|
+
- No login required - users can start chatting immediately
|
|
361
|
+
|
|
362
|
+
#### Conditional userId (Logged in or Guest)
|
|
363
|
+
|
|
364
|
+
Handle both logged-in users and guests dynamically:
|
|
365
|
+
|
|
366
|
+
```jsx
|
|
367
|
+
import { ChatWidget } from "@data-netmonk/mona-chat-widget";
|
|
368
|
+
import "@data-netmonk/mona-chat-widget/dist/style.css";
|
|
369
|
+
|
|
370
|
+
function App() {
|
|
371
|
+
const currentUser = getCurrentUser(); // Your auth function
|
|
372
|
+
|
|
373
|
+
return (
|
|
374
|
+
<ChatWidget
|
|
375
|
+
userId={currentUser?.id} // Provide userId if logged in, undefined if not
|
|
376
|
+
sourceId="691e1b5952068ff7aaeccffc9"
|
|
377
|
+
webhookUrl="https://api.example.com/webhook"
|
|
378
|
+
username={currentUser?.name}
|
|
379
|
+
/>
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Behavior:**
|
|
385
|
+
- If `currentUser.id` exists → Uses provided userId (authenticated user)
|
|
386
|
+
- If `currentUser.id` is `null`/`undefined` → Generates visitor ID (guest user)
|
|
387
|
+
- Backend receives `auth: false` flag only for guest users
|
|
388
|
+
|
|
389
|
+
#### With Custom Variables
|
|
390
|
+
|
|
391
|
+
Pass custom user data like email, phone number, etc. to the backend:
|
|
234
392
|
|
|
235
393
|
```jsx
|
|
236
394
|
<ChatWidget
|
|
237
|
-
userId="user123"
|
|
395
|
+
userId="user123"
|
|
238
396
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
239
|
-
|
|
240
|
-
|
|
397
|
+
webhookUrl="https://api.example.com/webhook"
|
|
398
|
+
username="John Doe"
|
|
399
|
+
data="telephone_number=+628123456789~email=john@example.com"
|
|
241
400
|
/>
|
|
242
401
|
```
|
|
243
402
|
|
|
244
|
-
|
|
403
|
+
**Variables sent to backend:**
|
|
404
|
+
```json
|
|
405
|
+
{
|
|
406
|
+
"chat_id": "...",
|
|
407
|
+
"session_id": "...",
|
|
408
|
+
"user_id": "user123",
|
|
409
|
+
"message": "Hello",
|
|
410
|
+
"type": "text",
|
|
411
|
+
"variables": {
|
|
412
|
+
"username": "John Doe",
|
|
413
|
+
"telephone_number": "+628123456789",
|
|
414
|
+
"email": "john@example.com"
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
#### With Authentication (NEW!)
|
|
245
421
|
|
|
246
|
-
|
|
422
|
+
The widget supports automatic authentication with token refresh on expiry:
|
|
247
423
|
|
|
248
424
|
```jsx
|
|
249
425
|
<ChatWidget
|
|
250
|
-
|
|
426
|
+
userId="user123"
|
|
427
|
+
sourceId="691e1b5952068ff7aaeccffc9"
|
|
428
|
+
webhookUrl="https://api.example.com/webhook"
|
|
429
|
+
authUrl="https://api.example.com/login/chatwidget"
|
|
430
|
+
username="John Doe"
|
|
251
431
|
/>
|
|
252
432
|
```
|
|
253
433
|
|
|
254
|
-
**
|
|
434
|
+
**How authentication works:**
|
|
435
|
+
|
|
436
|
+
1. **Initial Authentication**: When the widget loads (on Launcher mount), if `authUrl` is provided as a prop, it automatically calls the auth API:
|
|
437
|
+
```
|
|
438
|
+
POST {authUrl}
|
|
439
|
+
Body: { "user_id": "user123" }
|
|
440
|
+
Response: { "token": "eyJ..." }
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
2. **Session Initialization**: After getting the token, the widget calls the init endpoint to establish the session:
|
|
444
|
+
```
|
|
445
|
+
POST {webhookUrl}/{sourceId}/init
|
|
446
|
+
Body: {
|
|
447
|
+
"session_id": "...",
|
|
448
|
+
"user_id": "user123",
|
|
449
|
+
"token": "eyJ...",
|
|
450
|
+
"username": "John Doe"
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
3. **Automatic Token Refresh**: If the webhook returns **401 Unauthorized** (token expired/revoked), the widget automatically:
|
|
455
|
+
- Calls the `authUrl` again to get a fresh token
|
|
456
|
+
- Re-initializes the session with the new token
|
|
457
|
+
- Updates the `authToken` in variables
|
|
458
|
+
- Retries the failed request with the new token
|
|
459
|
+
- This happens transparently without user interaction
|
|
460
|
+
|
|
461
|
+
**Combined example with auth and custom variables:**
|
|
462
|
+
```jsx
|
|
463
|
+
<ChatWidget
|
|
464
|
+
userId="user123"
|
|
465
|
+
sourceId="691e1b5952068ff7aaeccffc9"
|
|
466
|
+
webhookUrl="https://api.example.com/webhook"
|
|
467
|
+
authUrl="https://api.example.com/login/chatwidget"
|
|
468
|
+
username="John"
|
|
469
|
+
data="email=john@example.com~phone=+628123456789"
|
|
470
|
+
/>
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Auth Flag (`auth` variable):**
|
|
474
|
+
The widget automatically adds an `auth: false` flag to the `variables` object when the user is a guest (not authenticated):
|
|
475
|
+
- When `userId === visitorId` (browser fingerprint), the widget adds `auth: false` to variables
|
|
476
|
+
- When `userId !== visitorId` (authenticated user), no `auth` flag is added to variables
|
|
477
|
+
|
|
478
|
+
**Guest user example** (userId equals browser fingerprint):
|
|
479
|
+
```json
|
|
480
|
+
{
|
|
481
|
+
"chat_id": "...",
|
|
482
|
+
"session_id": "...",
|
|
483
|
+
"user_id": "visitor_abc123",
|
|
484
|
+
"message": "Hello",
|
|
485
|
+
"type": "text",
|
|
486
|
+
"variables": {
|
|
487
|
+
"username": "Guest",
|
|
488
|
+
"auth": false
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**Authenticated user example** (userId is different from browser fingerprint):
|
|
255
494
|
```json
|
|
256
495
|
{
|
|
257
496
|
"chat_id": "...",
|
|
@@ -261,26 +500,25 @@ Pass custom user data like username, phone number, etc. to the backend:
|
|
|
261
500
|
"type": "text",
|
|
262
501
|
"variables": {
|
|
263
502
|
"username": "John Doe",
|
|
264
|
-
"telephone_number": "+628123456789",
|
|
265
503
|
"email": "john@example.com"
|
|
266
504
|
}
|
|
267
505
|
}
|
|
268
506
|
```
|
|
269
507
|
|
|
270
|
-
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
-
|
|
274
|
-
- `type` - Agent type
|
|
508
|
+
This `auth: false` flag is automatically added in:
|
|
509
|
+
- Session initialization payload (when guest)
|
|
510
|
+
- All message requests (when guest)
|
|
511
|
+
- Button postback requests (when guest)
|
|
275
512
|
|
|
276
|
-
**
|
|
513
|
+
**Note:** The `data` prop is for additional custom variables only. Required parameters (`userId`, `sourceId`, `webhookUrl`) and common optional parameters (`authUrl`, `username`) should be passed as direct props for better type safety and clarity.
|
|
277
514
|
|
|
278
515
|
#### Custom Styling
|
|
279
516
|
|
|
280
517
|
```jsx
|
|
281
518
|
<ChatWidget
|
|
282
|
-
userId="user123"
|
|
519
|
+
userId="user123" // Optional
|
|
283
520
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
521
|
+
webhookUrl="https://api.example.com/webhook"
|
|
284
522
|
width="400px"
|
|
285
523
|
height="600px"
|
|
286
524
|
right="20px"
|
|
@@ -295,8 +533,9 @@ Pass custom user data like username, phone number, etc. to the backend:
|
|
|
295
533
|
<div style={{ display: 'grid', gridTemplateColumns: '1fr 400px' }}>
|
|
296
534
|
<div>Main content</div>
|
|
297
535
|
<ChatWidget
|
|
298
|
-
userId="user123"
|
|
536
|
+
userId="user123" // Optional
|
|
299
537
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
538
|
+
webhookUrl="https://api.example.com/webhook"
|
|
300
539
|
position="relative"
|
|
301
540
|
width="100%"
|
|
302
541
|
height="100vh"
|
|
@@ -315,8 +554,9 @@ function App() {
|
|
|
315
554
|
|
|
316
555
|
return (
|
|
317
556
|
<ChatWidget
|
|
318
|
-
userId="user123"
|
|
557
|
+
userId="user123" // Optional
|
|
319
558
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
559
|
+
webhookUrl="https://api.example.com/webhook"
|
|
320
560
|
onToggle={handleToggle}
|
|
321
561
|
/>
|
|
322
562
|
);
|
|
@@ -327,8 +567,9 @@ function App() {
|
|
|
327
567
|
|
|
328
568
|
```jsx
|
|
329
569
|
<ChatWidget
|
|
330
|
-
userId="user123"
|
|
570
|
+
userId="user123" // Optional - supports guest users
|
|
331
571
|
sourceId="691e1b5952068ff7aaeccffc9"
|
|
572
|
+
webhookUrl="https://api.example.com/webhook"
|
|
332
573
|
width="100vw"
|
|
333
574
|
height="100vh"
|
|
334
575
|
right="0"
|
|
@@ -342,92 +583,153 @@ function App() {
|
|
|
342
583
|
|
|
343
584
|
---
|
|
344
585
|
|
|
345
|
-
The `data` prop allows you to pass
|
|
586
|
+
The `data` prop allows you to pass additional custom variables via a single string. This is especially useful when you need to dynamically pass user-specific data or pass it through URL parameters.
|
|
346
587
|
|
|
347
|
-
**Format:** `key
|
|
588
|
+
**Format:** `key=value` pairs separated by `~`
|
|
348
589
|
|
|
349
590
|
**Example data string:**
|
|
350
591
|
```
|
|
351
|
-
|
|
592
|
+
email=john@example.com~phone=+1234567890~department=Engineering
|
|
352
593
|
```
|
|
353
594
|
|
|
595
|
+
**Note:** `authUrl` and `username` are now **direct props** and should not be included in the `data` string.
|
|
596
|
+
|
|
354
597
|
#### Building Data String Programmatically
|
|
355
598
|
|
|
356
|
-
Instead of manually constructing the data string, you can create a helper function to build it dynamically:
|
|
599
|
+
Instead of manually constructing the data string, you can create a helper function to build it dynamically. This approach is recommended for production applications as it:
|
|
600
|
+
- Prevents syntax errors in the data string format
|
|
601
|
+
- Makes the code more maintainable and readable
|
|
602
|
+
- Allows for conditional inclusion of parameters
|
|
603
|
+
- Handles URL encoding automatically if needed
|
|
604
|
+
|
|
605
|
+
**Create a helper function** (`src/helpers/chatWidget.js` or similar):
|
|
606
|
+
|
|
607
|
+
```jsx
|
|
608
|
+
/**
|
|
609
|
+
* Builds the data string for ChatWidget component
|
|
610
|
+
* @param {Object} params - Object containing all parameters
|
|
611
|
+
* @param {string} params.email - Optional: User's email address
|
|
612
|
+
* @param {string} params.phone - Optional: User's phone number
|
|
613
|
+
* @param {Object} params.customFields - Optional: Any additional custom fields as key-value pairs
|
|
614
|
+
* @returns {string} Formatted data string for ChatWidget (always returns a string)
|
|
615
|
+
*
|
|
616
|
+
* @example
|
|
617
|
+
* // Returns: "email=john@example.com~phone=+1234567890~department=Engineering"
|
|
618
|
+
* buildChatWidgetData({
|
|
619
|
+
* email: "john@example.com",
|
|
620
|
+
* phone: "+1234567890",
|
|
621
|
+
* customFields: { department: "Engineering" }
|
|
622
|
+
* });
|
|
623
|
+
*/
|
|
624
|
+
export const buildChatWidgetData = ({
|
|
625
|
+
email,
|
|
626
|
+
phone,
|
|
627
|
+
customFields = {}
|
|
628
|
+
}) => {
|
|
629
|
+
const parts = [];
|
|
630
|
+
|
|
631
|
+
// Add standard fields
|
|
632
|
+
if (email) {
|
|
633
|
+
parts.push(`email=${encodeURIComponent(email)}`);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (phone) {
|
|
637
|
+
parts.push(`phone=${encodeURIComponent(phone)}`);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Add any custom fields dynamically
|
|
641
|
+
// Note: customFields is just a convenience parameter for the helper function
|
|
642
|
+
// Each field will be flattened into the string format: key=value~key2=value2
|
|
643
|
+
Object.entries(customFields).forEach(([key, value]) => {
|
|
644
|
+
if (value) {
|
|
645
|
+
parts.push(`${key}=${encodeURIComponent(String(value))}`);
|
|
646
|
+
}
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// Returns a string like: "email=john@example.com~phone=+1234567890~department=Engineering"
|
|
650
|
+
return parts.join("~");
|
|
651
|
+
};
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
**Important:** The `customFields` parameter is **NOT** passed as an object to the widget. It's just a convenient way to pass multiple additional fields to the helper function. The function flattens everything into a single string format.
|
|
655
|
+
|
|
656
|
+
**Usage in your application:**
|
|
357
657
|
|
|
358
|
-
**Usage:**
|
|
359
658
|
```jsx
|
|
360
659
|
import { ChatWidget } from "@data-netmonk/mona-chat-widget";
|
|
660
|
+
import "@data-netmonk/mona-chat-widget/dist/style.css";
|
|
361
661
|
import { buildChatWidgetData } from "./helpers/chatWidget";
|
|
362
662
|
|
|
363
663
|
function App() {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
username: "John Doe",
|
|
664
|
+
// Get user data from your auth system, state, or props
|
|
665
|
+
const user = {
|
|
666
|
+
id: "user123",
|
|
667
|
+
name: "John Doe",
|
|
369
668
|
email: "john@example.com",
|
|
370
669
|
phone: "+628123456789"
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
// Build the data string with custom variables only
|
|
673
|
+
const customData = buildChatWidgetData({
|
|
674
|
+
email: user.email,
|
|
675
|
+
phone: user.phone,
|
|
676
|
+
customFields: {
|
|
677
|
+
department: "Engineering",
|
|
678
|
+
role: "Developer",
|
|
679
|
+
company: "Acme Corp"
|
|
680
|
+
}
|
|
371
681
|
});
|
|
682
|
+
|
|
683
|
+
// customData is now a STRING like:
|
|
684
|
+
// "email=john@example.com~phone=%2B628123456789~department=Engineering~role=Developer~company=Acme%20Corp"
|
|
372
685
|
|
|
373
|
-
return
|
|
686
|
+
return (
|
|
687
|
+
<ChatWidget
|
|
688
|
+
userId={user.id}
|
|
689
|
+
sourceId="691e1b5952068ff7aaeccffc9"
|
|
690
|
+
webhookUrl="https://api.example.com/webhook"
|
|
691
|
+
authUrl="https://api.example.com/login/chatwidget" // Direct prop
|
|
692
|
+
username={user.name} // Direct prop
|
|
693
|
+
data={customData} // Only additional variables
|
|
694
|
+
/>
|
|
695
|
+
);
|
|
374
696
|
}
|
|
375
697
|
```
|
|
376
698
|
|
|
377
|
-
|
|
378
|
-
- Accept configuration parameters (userId, sourceId, botServerUrl, and any custom variables)
|
|
379
|
-
- Build the data string in format: `key=value` pairs separated by `~`
|
|
380
|
-
- Use `url:` prefix (not `url=`) for the backend URL
|
|
381
|
-
- Return the formatted string
|
|
382
|
-
|
|
383
|
-
#### Using with URL Parameters (Optional)
|
|
384
|
-
|
|
385
|
-
If you need to pass the data through URL parameters:
|
|
386
|
-
|
|
387
|
-
```jsx
|
|
388
|
-
// Parse from URL
|
|
389
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
390
|
-
const dataParam = urlParams.get('data');
|
|
391
|
-
|
|
392
|
-
<ChatWidget data={dataParam} />
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
**URL example:**
|
|
396
|
-
```
|
|
397
|
-
https://yourapp.com/chat?data=url:https://api.example.com~user_id=user123~source_id=abc~username=John~phone=%2B628123456789
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
#### Real-World Example from ui-mona-web
|
|
401
|
-
|
|
402
|
-
See the complete helper implementation in `ui-mona-web/src/helpers/chatWidget.js`:
|
|
699
|
+
**With conditional authentication:**
|
|
403
700
|
|
|
404
701
|
```jsx
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
const finalUserId = userId || getUserId();
|
|
410
|
-
|
|
411
|
-
// Get sourceId based on loginType
|
|
412
|
-
const finalSourceId = sourceId || getSourceIdByLoginType(loginType);
|
|
413
|
-
|
|
414
|
-
// Get bot server URL from env
|
|
415
|
-
const finalBotServerUrl = import.meta.env.VITE_CHAT_WIDGET_WEBHOOK_URL || botServerUrl;
|
|
416
|
-
|
|
417
|
-
const parts = [
|
|
418
|
-
`user_id=${String(finalUserId)}`,
|
|
419
|
-
`source_id=${finalSourceId}`,
|
|
420
|
-
];
|
|
421
|
-
|
|
422
|
-
if (finalBotServerUrl) {
|
|
423
|
-
parts.unshift(`url:${finalBotServerUrl}`);
|
|
424
|
-
}
|
|
702
|
+
function App() {
|
|
703
|
+
const authUrl = import.meta.env.VITE_CHAT_AUTH_ENABLED === "true"
|
|
704
|
+
? import.meta.env.VITE_CHAT_AUTH_URL
|
|
705
|
+
: null;
|
|
425
706
|
|
|
426
|
-
|
|
427
|
-
|
|
707
|
+
const customData = buildChatWidgetData({
|
|
708
|
+
email: getCurrentUser().email,
|
|
709
|
+
customFields: {
|
|
710
|
+
department: "Sales"
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
return (
|
|
715
|
+
<ChatWidget
|
|
716
|
+
userId={getCurrentUser().id}
|
|
717
|
+
sourceId="691e1b5952068ff7aaeccffc9"
|
|
718
|
+
webhookUrl={import.meta.env.VITE_WEBHOOK_URL}
|
|
719
|
+
authUrl={authUrl} // Direct prop (conditionally set)
|
|
720
|
+
username={getCurrentUser().name} // Direct prop
|
|
721
|
+
data={customData} // Only additional variables
|
|
722
|
+
/>
|
|
723
|
+
);
|
|
724
|
+
}
|
|
428
725
|
```
|
|
429
726
|
|
|
430
|
-
|
|
727
|
+
**The helper function handles:**
|
|
728
|
+
- ✅ Proper formatting with `~` separators
|
|
729
|
+
- ✅ URL encoding for special characters
|
|
730
|
+
- ✅ Conditional parameter inclusion (only adds if value exists)
|
|
731
|
+
- ✅ Support for dynamic custom fields
|
|
732
|
+
- ✅ Type safety and documentation via JSDoc comments
|
|
431
733
|
|
|
432
734
|
### Standalone app (for demonstration)
|
|
433
735
|
|