tchao 0.1.2 → 1.0.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 +143 -100
- package/dist/npm.d.mts +106 -69
- package/dist/npm.d.ts +106 -69
- package/dist/npm.js +1 -1440
- package/dist/npm.js.map +1 -1
- package/dist/npm.mjs +1 -1440
- package/dist/npm.mjs.map +1 -1
- package/dist/react.d.mts +68 -0
- package/dist/react.d.ts +68 -0
- package/dist/react.js +2 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +2 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +17 -13
package/README.md
CHANGED
|
@@ -4,8 +4,6 @@ JavaScript SDK for integrating the Tchao chat widget into your application.
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
### Option 1: npm package
|
|
8
|
-
|
|
9
7
|
```bash
|
|
10
8
|
npm install tchao
|
|
11
9
|
# or
|
|
@@ -14,146 +12,191 @@ pnpm add tchao
|
|
|
14
12
|
yarn add tchao
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
## Quick Start
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
### React (Recommended)
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { useTchao } from "tchao/react";
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
const { isReady, open, identify } = useTchao({
|
|
24
|
+
websiteId: "your-website-id",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Identify user when ready
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (isReady && user) {
|
|
30
|
+
identify({ email: user.email, name: user.name });
|
|
31
|
+
}
|
|
32
|
+
}, [isReady, user, identify]);
|
|
33
|
+
|
|
34
|
+
return <button onClick={() => open()}>Chat with us</button>;
|
|
35
|
+
}
|
|
21
36
|
```
|
|
22
37
|
|
|
23
|
-
|
|
38
|
+
### React Provider (Simpler)
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { TchaoProvider } from "tchao/react";
|
|
42
|
+
|
|
43
|
+
function Layout({ children }) {
|
|
44
|
+
return (
|
|
45
|
+
<>
|
|
46
|
+
<TchaoProvider
|
|
47
|
+
websiteId="your-website-id"
|
|
48
|
+
visitor={{ email: user?.email, name: user?.name }}
|
|
49
|
+
/>
|
|
50
|
+
{children}
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
24
55
|
|
|
25
|
-
###
|
|
56
|
+
### Vanilla JavaScript
|
|
26
57
|
|
|
27
58
|
```typescript
|
|
28
|
-
import {
|
|
59
|
+
import { tchao } from "tchao";
|
|
29
60
|
|
|
30
|
-
// Initialize
|
|
31
|
-
|
|
32
|
-
websiteId: 'your-website-id'
|
|
33
|
-
});
|
|
61
|
+
// Initialize (call once)
|
|
62
|
+
await tchao.init({ websiteId: "your-website-id" });
|
|
34
63
|
|
|
35
|
-
//
|
|
36
|
-
|
|
64
|
+
// All methods are safe - no try/catch needed
|
|
65
|
+
tchao.identify({ email: "user@example.com" });
|
|
66
|
+
tchao.open();
|
|
37
67
|
```
|
|
38
68
|
|
|
39
|
-
### Script
|
|
69
|
+
### Script Tag
|
|
40
70
|
|
|
41
71
|
```html
|
|
42
|
-
<script
|
|
72
|
+
<script
|
|
73
|
+
src="https://tchao.app/widget.js"
|
|
74
|
+
data-website-id="your-website-id"
|
|
75
|
+
></script>
|
|
43
76
|
<script>
|
|
44
|
-
// Widget auto-initializes
|
|
45
|
-
window.Tchao.
|
|
46
|
-
|
|
47
|
-
// Listen for events
|
|
48
|
-
window.Tchao.on('ready', () => {
|
|
49
|
-
console.log('Widget ready!');
|
|
50
|
-
});
|
|
77
|
+
// Widget auto-initializes
|
|
78
|
+
window.Tchao.identify({ email: "user@example.com" });
|
|
51
79
|
</script>
|
|
52
80
|
```
|
|
53
81
|
|
|
54
82
|
## API Reference
|
|
55
83
|
|
|
56
|
-
### `
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
### React Hook: `useTchao(config)`
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { useTchao } from "tchao/react";
|
|
88
|
+
|
|
89
|
+
const {
|
|
90
|
+
isReady, // boolean - widget is initialized
|
|
91
|
+
isLoading, // boolean - widget is loading
|
|
92
|
+
error, // Error | null - initialization error
|
|
93
|
+
show, // () => void
|
|
94
|
+
hide, // () => void
|
|
95
|
+
toggle, // () => void
|
|
96
|
+
open, // (message?: string) => void
|
|
97
|
+
identify, // (info: VisitorInfo) => void
|
|
98
|
+
config, // () => Partial<WidgetConfig>
|
|
99
|
+
on, // (event, callback) => void
|
|
100
|
+
off, // (event, callback) => void
|
|
101
|
+
} = useTchao({ websiteId: "..." });
|
|
65
102
|
```
|
|
66
103
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
### Instance Methods
|
|
104
|
+
### Safe API: `tchao`
|
|
70
105
|
|
|
71
|
-
|
|
72
|
-
Show the widget launcher button.
|
|
73
|
-
|
|
74
|
-
#### `widget.hide()`
|
|
75
|
-
Hide the widget launcher button.
|
|
76
|
-
|
|
77
|
-
#### `widget.toggle()`
|
|
78
|
-
Toggle the chat window open/closed.
|
|
79
|
-
|
|
80
|
-
#### `widget.open()`
|
|
81
|
-
Open the chat window.
|
|
82
|
-
|
|
83
|
-
#### `widget.identify(info)`
|
|
84
|
-
Identify the visitor with their information.
|
|
106
|
+
All methods are safe to call at any time - they will queue and execute when ready.
|
|
85
107
|
|
|
86
108
|
```typescript
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
109
|
+
import { tchao } from "tchao";
|
|
110
|
+
|
|
111
|
+
// Initialize
|
|
112
|
+
await tchao.init({ websiteId: "your-website-id" });
|
|
113
|
+
|
|
114
|
+
// Control methods (safe before/after init)
|
|
115
|
+
tchao.show();
|
|
116
|
+
tchao.hide();
|
|
117
|
+
tchao.toggle();
|
|
118
|
+
tchao.open();
|
|
119
|
+
tchao.open("I need help with...");
|
|
120
|
+
|
|
121
|
+
// Identify visitor
|
|
122
|
+
tchao.identify({
|
|
123
|
+
email: "user@example.com",
|
|
124
|
+
name: "John Doe",
|
|
125
|
+
avatar: "https://example.com/avatar.jpg",
|
|
126
|
+
metadata: { plan: "pro", userId: "123" },
|
|
95
127
|
});
|
|
96
|
-
```
|
|
97
128
|
|
|
98
|
-
|
|
99
|
-
|
|
129
|
+
// Events
|
|
130
|
+
tchao.on("message", (msg) => console.log(msg));
|
|
131
|
+
tchao.on("open", () => console.log("Opened"));
|
|
132
|
+
tchao.on("close", () => console.log("Closed"));
|
|
133
|
+
tchao.on("ready", () => console.log("Ready"));
|
|
100
134
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
135
|
+
// Cleanup
|
|
136
|
+
tchao.destroy();
|
|
137
|
+
|
|
138
|
+
// Status
|
|
139
|
+
tchao.isReady(); // boolean
|
|
107
140
|
```
|
|
108
141
|
|
|
109
|
-
|
|
110
|
-
Subscribe to widget events.
|
|
142
|
+
### Init Config
|
|
111
143
|
|
|
112
144
|
```typescript
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
widget.on('ready', () => {
|
|
126
|
-
console.log('Widget ready');
|
|
145
|
+
tchao.init({
|
|
146
|
+
websiteId: "required",
|
|
147
|
+
host: "https://tchao.app", // optional, for self-hosted
|
|
148
|
+
position: "bottom-right", // "bottom-right" | "bottom-left"
|
|
149
|
+
primaryColor: "#6366f1",
|
|
150
|
+
themeMode: "system", // "light" | "dark" | "system"
|
|
151
|
+
widgetStyle: "bubble", // "bubble" | "name_line" | "question_cta"
|
|
152
|
+
agentName: "Support",
|
|
153
|
+
agentRole: "Customer Support",
|
|
154
|
+
agentImage: "https://...",
|
|
155
|
+
agentWelcomeMessage: "Hi! How can I help?",
|
|
156
|
+
hidePoweredBy: false,
|
|
127
157
|
});
|
|
128
158
|
```
|
|
129
159
|
|
|
130
|
-
|
|
131
|
-
Unsubscribe from widget events.
|
|
160
|
+
### Events
|
|
132
161
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
162
|
+
| Event | Callback | Description |
|
|
163
|
+
|-------|----------|-------------|
|
|
164
|
+
| `message` | `(message: Message) => void` | New message received |
|
|
165
|
+
| `open` | `() => void` | Chat window opened |
|
|
166
|
+
| `close` | `() => void` | Chat window closed |
|
|
167
|
+
| `ready` | `() => void` | Widget initialized |
|
|
138
168
|
|
|
139
|
-
|
|
140
|
-
Clean up and remove the widget from the page.
|
|
169
|
+
### TypeScript
|
|
141
170
|
|
|
142
171
|
```typescript
|
|
143
|
-
|
|
172
|
+
import type {
|
|
173
|
+
TchaoConfig,
|
|
174
|
+
TchaoInstance,
|
|
175
|
+
VisitorInfo,
|
|
176
|
+
Message,
|
|
177
|
+
WidgetConfig,
|
|
178
|
+
TchaoEvent,
|
|
179
|
+
TchaoEventMap,
|
|
180
|
+
} from "tchao";
|
|
181
|
+
|
|
182
|
+
// React types
|
|
183
|
+
import type { UseTchaoOptions, UseTchaoReturn } from "tchao/react";
|
|
144
184
|
```
|
|
145
185
|
|
|
146
|
-
##
|
|
186
|
+
## Migration from v0.1.3
|
|
147
187
|
|
|
148
|
-
|
|
188
|
+
The API is backward compatible. New additions:
|
|
149
189
|
|
|
150
190
|
```typescript
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
} from
|
|
191
|
+
// New: Safe API (no try/catch needed)
|
|
192
|
+
import { tchao } from "tchao";
|
|
193
|
+
tchao.identify({ email: "..." }); // Works before init!
|
|
194
|
+
|
|
195
|
+
// New: React hook
|
|
196
|
+
import { useTchao } from "tchao/react";
|
|
197
|
+
|
|
198
|
+
// New: React provider
|
|
199
|
+
import { TchaoProvider } from "tchao/react";
|
|
157
200
|
```
|
|
158
201
|
|
|
159
202
|
## License
|
package/dist/npm.d.mts
CHANGED
|
@@ -1,97 +1,134 @@
|
|
|
1
|
-
type SenderType = "VISITOR" | "AGENT" | "AI" | "SYSTEM";
|
|
2
|
-
type ConversationStatus = "OPEN" | "IN_PROGRESS" | "CLOSED";
|
|
3
|
-
type MessageStatus = "sending" | "sent" | "failed";
|
|
4
|
-
type WidgetPosition = "bottom-right" | "bottom-left";
|
|
5
|
-
type WidgetStyle = "bubble" | "name_line" | "question_cta";
|
|
6
|
-
type ThemeMode = "light" | "dark" | "system";
|
|
7
1
|
type VisitorInfo = {
|
|
8
2
|
name?: string;
|
|
9
3
|
email?: string;
|
|
10
4
|
avatar?: string;
|
|
11
5
|
metadata?: Record<string, unknown>;
|
|
12
6
|
};
|
|
13
|
-
type MessageReaction = {
|
|
14
|
-
emoji: string;
|
|
15
|
-
userIds: string[];
|
|
16
|
-
};
|
|
17
|
-
type Message = {
|
|
18
|
-
id: string;
|
|
19
|
-
content: string;
|
|
20
|
-
senderType: SenderType;
|
|
21
|
-
senderId: string;
|
|
22
|
-
screenshot?: string | null;
|
|
23
|
-
image?: string | null;
|
|
24
|
-
timestamp: number;
|
|
25
|
-
status?: MessageStatus;
|
|
26
|
-
reactions?: MessageReaction[] | null;
|
|
27
|
-
};
|
|
28
7
|
type WidgetConfig = {
|
|
29
8
|
websiteId: string;
|
|
30
|
-
|
|
9
|
+
position?: "bottom-right" | "bottom-left";
|
|
10
|
+
primaryColor?: string;
|
|
11
|
+
widgetStyle?: "bubble" | "name_line" | "question_cta";
|
|
12
|
+
themeMode?: "light" | "dark" | "system";
|
|
13
|
+
agentName?: string;
|
|
14
|
+
agentRole?: string;
|
|
15
|
+
agentImage?: string;
|
|
16
|
+
agentWelcomeMessage?: string;
|
|
17
|
+
hidePoweredBy?: boolean;
|
|
18
|
+
bubbleIcon?: string;
|
|
19
|
+
};
|
|
20
|
+
type TchaoConfig = {
|
|
21
|
+
websiteId: string;
|
|
22
|
+
host?: string;
|
|
31
23
|
convexUrl?: string;
|
|
32
|
-
position?:
|
|
24
|
+
position?: "bottom-right" | "bottom-left";
|
|
33
25
|
primaryColor?: string;
|
|
34
|
-
widgetStyle?:
|
|
35
|
-
themeMode?:
|
|
26
|
+
widgetStyle?: "bubble" | "name_line" | "question_cta";
|
|
27
|
+
themeMode?: "light" | "dark" | "system";
|
|
28
|
+
agentName?: string;
|
|
29
|
+
agentRole?: string;
|
|
30
|
+
agentImage?: string;
|
|
31
|
+
agentWelcomeMessage?: string;
|
|
32
|
+
hidePoweredBy?: boolean;
|
|
33
|
+
bubbleIcon?: string;
|
|
36
34
|
};
|
|
37
|
-
type
|
|
35
|
+
type Message = {
|
|
36
|
+
content: string;
|
|
37
|
+
sender: string;
|
|
38
|
+
timestamp: number;
|
|
39
|
+
};
|
|
40
|
+
type TchaoEventMap = {
|
|
38
41
|
message: (message: Message) => void;
|
|
39
42
|
open: () => void;
|
|
40
43
|
close: () => void;
|
|
41
44
|
ready: () => void;
|
|
42
45
|
};
|
|
43
|
-
type
|
|
46
|
+
type TchaoEvent = keyof TchaoEventMap;
|
|
47
|
+
type TchaoInstance = {
|
|
44
48
|
show: () => void;
|
|
45
49
|
hide: () => void;
|
|
46
50
|
toggle: () => void;
|
|
47
|
-
open: () => void;
|
|
51
|
+
open: (message?: string) => void;
|
|
48
52
|
identify: (info: VisitorInfo) => void;
|
|
49
|
-
config: (
|
|
50
|
-
on: <
|
|
51
|
-
off: <
|
|
53
|
+
config: () => Partial<WidgetConfig>;
|
|
54
|
+
on: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
|
|
55
|
+
off: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
|
|
56
|
+
destroy: () => void;
|
|
57
|
+
isReady: () => boolean;
|
|
52
58
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
setCallbacks(callbacks: {
|
|
63
|
-
show: () => void;
|
|
64
|
-
hide: () => void;
|
|
65
|
-
toggle: () => void;
|
|
66
|
-
open: () => void;
|
|
67
|
-
identify: (info: VisitorInfo) => void;
|
|
68
|
-
config: (opts: Partial<WidgetConfig>) => void;
|
|
69
|
-
}): void;
|
|
70
|
-
show(): void;
|
|
71
|
-
hide(): void;
|
|
72
|
-
toggle(): void;
|
|
73
|
-
open(): void;
|
|
74
|
-
identify(info: VisitorInfo): void;
|
|
75
|
-
config(opts: Partial<WidgetConfig>): void;
|
|
76
|
-
on<K extends keyof SDKEventMap>(event: K, callback: SDKEventMap[K]): void;
|
|
77
|
-
off<K extends keyof SDKEventMap>(event: K, callback: SDKEventMap[K]): void;
|
|
78
|
-
emit<K extends keyof SDKEventMap>(event: K, ...args: Parameters<SDKEventMap[K]>): void;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
type TchaoInitConfig = {
|
|
82
|
-
websiteId: string;
|
|
83
|
-
host?: string;
|
|
59
|
+
type InternalTchaoInstance = {
|
|
60
|
+
show: () => void;
|
|
61
|
+
hide: () => void;
|
|
62
|
+
toggle: () => void;
|
|
63
|
+
open: (message?: string) => void;
|
|
64
|
+
identify: (info: VisitorInfo) => void;
|
|
65
|
+
config: () => Partial<WidgetConfig>;
|
|
66
|
+
on: (event: string, callback: (...args: unknown[]) => void) => void;
|
|
67
|
+
off: (event: string, callback: (...args: unknown[]) => void) => void;
|
|
84
68
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
69
|
+
declare global {
|
|
70
|
+
interface Window {
|
|
71
|
+
Tchao?: InternalTchaoInstance;
|
|
72
|
+
__TCHAO_CONFIG__?: TchaoConfig;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
declare function init(config: TchaoConfig): Promise<TchaoInstance>;
|
|
76
|
+
/**
|
|
77
|
+
* Safe API that works before initialization.
|
|
78
|
+
* Calls are queued and executed once the widget is ready.
|
|
79
|
+
*/
|
|
80
|
+
declare const tchao: {
|
|
81
|
+
/**
|
|
82
|
+
* Initialize the widget. Returns a promise that resolves with the instance.
|
|
83
|
+
*/
|
|
84
|
+
init: typeof init;
|
|
85
|
+
/**
|
|
86
|
+
* Show the widget launcher. Safe to call before init.
|
|
87
|
+
*/
|
|
88
|
+
show: () => void;
|
|
89
|
+
/**
|
|
90
|
+
* Hide the widget launcher. Safe to call before init.
|
|
91
|
+
*/
|
|
92
|
+
hide: () => void;
|
|
93
|
+
/**
|
|
94
|
+
* Toggle the chat window. Safe to call before init.
|
|
95
|
+
*/
|
|
96
|
+
toggle: () => void;
|
|
97
|
+
/**
|
|
98
|
+
* Open the chat window. Safe to call before init.
|
|
99
|
+
*/
|
|
100
|
+
open: (message?: string) => void;
|
|
101
|
+
/**
|
|
102
|
+
* Identify the visitor. Safe to call before init.
|
|
103
|
+
*/
|
|
104
|
+
identify: (info: VisitorInfo) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Get the current widget configuration.
|
|
107
|
+
*/
|
|
108
|
+
config: () => Partial<WidgetConfig>;
|
|
109
|
+
/**
|
|
110
|
+
* Subscribe to widget events. Safe to call before init.
|
|
111
|
+
*/
|
|
112
|
+
on: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
|
|
113
|
+
/**
|
|
114
|
+
* Unsubscribe from widget events.
|
|
115
|
+
*/
|
|
116
|
+
off: <E extends TchaoEvent>(event: E, callback: TchaoEventMap[E]) => void;
|
|
117
|
+
/**
|
|
118
|
+
* Destroy the widget and clean up resources.
|
|
119
|
+
*/
|
|
88
120
|
destroy: () => void;
|
|
121
|
+
/**
|
|
122
|
+
* Check if the widget is ready.
|
|
123
|
+
*/
|
|
124
|
+
isReady: () => boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Get the current instance (null if not initialized).
|
|
127
|
+
*/
|
|
128
|
+
getInstance: () => TchaoInstance | null;
|
|
89
129
|
};
|
|
90
|
-
type TchaoEvents = SDKEventMap;
|
|
91
|
-
|
|
92
|
-
declare function init(config: TchaoConfig): Promise<TchaoInstance>;
|
|
93
130
|
declare const Tchao: {
|
|
94
131
|
init: typeof init;
|
|
95
132
|
};
|
|
96
133
|
|
|
97
|
-
export { type
|
|
134
|
+
export { type Message, Tchao, type TchaoConfig, type TchaoEvent, type TchaoEventMap, type TchaoInstance, type VisitorInfo, type WidgetConfig, Tchao as default, init, tchao };
|