ai-chatbot-widget 0.0.37 → 0.1.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 +259 -0
- package/dist/chatbot-widget.es.js +4336 -4151
- package/dist/chatbot-widget.iife.js +75 -75
- package/dist/index.css +1 -1
- package/package.json +7 -7
package/README.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# AI Chatbot Widget
|
|
2
|
+
|
|
3
|
+
This chatbot widget was developed for [Agile Alpaca](https://agile-alpaca.com) clients who have used our AI-agent integration services in their online stores. It’s designed for commercial websites to help visitors quickly get answers to their questions and place orders.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
- [x] Theme customization – the theme parameter applies predefined styles that change the background, button, and message-bubble colors.
|
|
9
|
+
- [x] Animated popup window – the chat window is anchored to the bottom-right corner and opens/collapses with smooth animation.
|
|
10
|
+
- [x] Open button + message badge
|
|
11
|
+
- [x] Welcome message
|
|
12
|
+
- [x] Previous dialogue restoration
|
|
13
|
+
- [x] Quick-reply prompts (chat prompts)
|
|
14
|
+
- [x] Page context (pageContext) – lets you run arbitrary scripts (e.g., auto-show the chat or display a personalized message) once a visitor has spent timer ms on a specific pathname.
|
|
15
|
+
- [x] Full control via context object – the execPageContext function provides external code with a complete set of setters (open, messageOptions, input, promptsOptions) plus a scrollToBottom method, simplifying integration with analytics or business logic.
|
|
16
|
+
- [x] Input with Shift+Enter support – pressing Enter sends a message; Shift+Enter inserts a newline.
|
|
17
|
+
- [x] Automatic scroll to the latest message
|
|
18
|
+
- [x] Responsive design
|
|
19
|
+
- [ ] Full-page context handling – ability to send the entire page context to the server along with the user’s message.
|
|
20
|
+
|
|
21
|
+
## Required API routes (for widget)
|
|
22
|
+
|
|
23
|
+
`apiBaseUrl` must point to a specific public chat endpoint.
|
|
24
|
+
|
|
25
|
+
The widget uses the same URL for both read/send operations and sends requests with `withCredentials: true`.
|
|
26
|
+
|
|
27
|
+
### 1) Get dialog/session
|
|
28
|
+
|
|
29
|
+
- Method: `GET`
|
|
30
|
+
- Purpose: load existing dialog and create session (if cookie does not exist yet)
|
|
31
|
+
- Response shape:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"data": {
|
|
36
|
+
"sessionUuid": "uuid", // not used now
|
|
37
|
+
"createdAt": "ISO date",
|
|
38
|
+
"messages": [
|
|
39
|
+
{
|
|
40
|
+
"id": 1,
|
|
41
|
+
"text": "Hello",
|
|
42
|
+
"type": "INPUT",
|
|
43
|
+
"sentAt": "ISO date",
|
|
44
|
+
"usage": 10
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2) Send message
|
|
52
|
+
|
|
53
|
+
- Method: `POST`
|
|
54
|
+
- Body:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"text": "User message"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- Response shape:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"data": {
|
|
67
|
+
"sessionUuid": "uuid", // not used now
|
|
68
|
+
"input": {},
|
|
69
|
+
"output": {
|
|
70
|
+
"text": "Bot reply"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3) Preflight (CORS)
|
|
77
|
+
|
|
78
|
+
- Method: `OPTIONS`
|
|
79
|
+
- Purpose: browser preflight for cross-origin `POST` with credentials
|
|
80
|
+
|
|
81
|
+
Minimal required CORS headers in API response:
|
|
82
|
+
- `Access-Control-Allow-Origin: <exact widget origin>`
|
|
83
|
+
- `Access-Control-Allow-Credentials: true`
|
|
84
|
+
- `Access-Control-Allow-Methods: GET,POST,OPTIONS`
|
|
85
|
+
- `Access-Control-Allow-Headers: Content-Type` (or requested headers)
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
```html
|
|
89
|
+
<head>
|
|
90
|
+
<!-- ... -->
|
|
91
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ai-chatbot-widget@latest/dist/index.css" />
|
|
92
|
+
</head>
|
|
93
|
+
|
|
94
|
+
<body>
|
|
95
|
+
<!-- ... -->
|
|
96
|
+
|
|
97
|
+
<div id="chatbot"></div>
|
|
98
|
+
|
|
99
|
+
<script src="https://cdn.jsdelivr.net/npm/ai-chatbot-widget@latest/dist/chatbot-widget.iife.js"></script>
|
|
100
|
+
|
|
101
|
+
<script>
|
|
102
|
+
const greeting = 'Hello! 👋 I’m the AI assistant.'
|
|
103
|
+
const contactUsMessage = `To get in touch with our manager, please leave your email address 📧, WhatsApp, or phone number 📱.
|
|
104
|
+
|
|
105
|
+
We'll get back to you during our business hours 🕖 7:00 a.m. – 4:00 p.m. CST.
|
|
106
|
+
|
|
107
|
+
Thank you for reaching out! 💬`
|
|
108
|
+
|
|
109
|
+
const chatPrompts = [
|
|
110
|
+
'I want a custom sign',
|
|
111
|
+
'I want to track my order',
|
|
112
|
+
'What are production and delivery times?',
|
|
113
|
+
'What are your shipping and refund policies?',
|
|
114
|
+
'I have problem with my order'
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
ChatbotWidget.mountChatbotWidget("#chatbot", {
|
|
118
|
+
apiBaseUrl: 'https://api.example.com',
|
|
119
|
+
greeting,
|
|
120
|
+
chatPrompts,
|
|
121
|
+
|
|
122
|
+
title: 'Bsign Assistant',
|
|
123
|
+
imageUrl: 'https://cdn.shopify.com/s/files/1/0248/8198/7665/files/chatbot-logo.png?v=1750682293',
|
|
124
|
+
imageWidth: '120px',
|
|
125
|
+
|
|
126
|
+
// Modify the chat states depending on the user's URL
|
|
127
|
+
pageContext: {
|
|
128
|
+
'/pages/contact-us': {
|
|
129
|
+
timer: 1000,
|
|
130
|
+
exec: ({ open, messageOptions }) => {
|
|
131
|
+
messageOptions.setMessages(prev => [
|
|
132
|
+
...prev,
|
|
133
|
+
{content: contactUsMessage, sender: 'bot'}
|
|
134
|
+
])
|
|
135
|
+
open.setIsOpen(true);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
</script>
|
|
141
|
+
</body>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Themes
|
|
145
|
+
|
|
146
|
+
Avaible themes: `futuristic`, `lighty`, `boring`, `o Canada`.
|
|
147
|
+
|
|
148
|
+
The themes are stylized using tailwind, you can see them here: `/widget-vite/src/utils/styles.ts`.
|
|
149
|
+
|
|
150
|
+
There is currently no solution for creating custom themes by passing props. If needed, you can use plain CSS with the !important directive.
|
|
151
|
+
|
|
152
|
+
#### lighty
|
|
153
|
+
|
|
154
|
+

|
|
155
|
+
|
|
156
|
+
The “lighty” theme combines minimalism with vibrant accents:
|
|
157
|
+
- A clean white background makes the interface feel light and airy.
|
|
158
|
+
- A contrasting dark header adds structure and focuses attention on navigation.
|
|
159
|
+
- Gradiented bot messages in purple-pink hues enliven the space without overwhelming it.
|
|
160
|
+
- Black-and-white user messages (with subtle transparency) maintain a sleek look.
|
|
161
|
+
- Buttons and input fields feature delicate purple outlines for a modern yet refined style.
|
|
162
|
+
|
|
163
|
+
#### boring
|
|
164
|
+
|
|
165
|
+

|
|
166
|
+
|
|
167
|
+
The “boring” theme offers a maximally neutral and formal interface:
|
|
168
|
+
- A pure white background and a solid dark header (no gradients) create a very simple backdrop.
|
|
169
|
+
- Bot messages in dark gray blocks with white text look like a classic terminal chat.
|
|
170
|
+
- User messages and icons are in black without any color accents—utterly restrained.
|
|
171
|
+
- Inputs and buttons have thin gray borders that barely draw attention.
|
|
172
|
+
- This style suits corporate or internal tools where functionality matters more than aesthetics.
|
|
173
|
+
|
|
174
|
+
#### futuristic
|
|
175
|
+
|
|
176
|
+

|
|
177
|
+
|
|
178
|
+
The “futuristic” theme plunges you into a cyberpunk, sci-fi world:
|
|
179
|
+
- A deep gradient from dark slate through purple to near-black evokes the infinity of space.
|
|
180
|
+
- Bright purple-to-blue accents in the header and open button emit neon energy.
|
|
181
|
+
- Bot messages in warm purple-pink gradients with white text resemble holograms.
|
|
182
|
+
- Semi-transparent, heavily blurred user message backgrounds create a digital cocoon.
|
|
183
|
+
- Glow effects on the open button and notification badge complete the high-tech vibe.
|
|
184
|
+
|
|
185
|
+
#### o Canada
|
|
186
|
+
|
|
187
|
+

|
|
188
|
+
|
|
189
|
+
The “o Canada” theme embodies nature and stability:
|
|
190
|
+
- A white background recalls Canadian forests, snowy landscapes, and purity.
|
|
191
|
+
- The header and bot elements use a deep green (#016553), reminiscent of evergreen woods.
|
|
192
|
+
- The gold notification badge (#D1A205) symbolizes the warm hues of sunlight over the plains.
|
|
193
|
+
- User messages and input fields remain understated so nothing distracts from the core content.
|
|
194
|
+
- This style works well for eco-friendly, educational, or official projects that value trust and reliability.
|
|
195
|
+
|
|
196
|
+
### Widget context
|
|
197
|
+
|
|
198
|
+
One of the chatbot’s most important features is its ability to manipulate widget states based on the page context (and this functionality will only expand over time).
|
|
199
|
+
|
|
200
|
+
At the moment, you can only modify states based on the URL the user is visiting.
|
|
201
|
+
|
|
202
|
+
Example usage:
|
|
203
|
+
```typescript
|
|
204
|
+
pageContext: {
|
|
205
|
+
'/pages/contact-us': {
|
|
206
|
+
timer: 1000, // after how many ms executed
|
|
207
|
+
exec: ({ open, messageOptions }) => {
|
|
208
|
+
|
|
209
|
+
// Adds messages to existing
|
|
210
|
+
messageOptions.setMessages(prev => [
|
|
211
|
+
...prev,
|
|
212
|
+
{ content: "Hello! Do you want to contact us?", sender: 'bot' }
|
|
213
|
+
]);
|
|
214
|
+
|
|
215
|
+
// Automatically expands the widget
|
|
216
|
+
open.setIsOpen(true);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
All modifiable states are:
|
|
223
|
+
```typescript
|
|
224
|
+
{
|
|
225
|
+
open: {
|
|
226
|
+
isOpen: boolean, // whether the widget is open
|
|
227
|
+
setIsOpen: (v: boolean) => void // open / close the widget
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
messageOptions: {
|
|
231
|
+
// All existing messages
|
|
232
|
+
messages: {
|
|
233
|
+
content: string,
|
|
234
|
+
sender: "user" | "bot"
|
|
235
|
+
}[],
|
|
236
|
+
|
|
237
|
+
// Function for setting messages
|
|
238
|
+
setMessages: (messages: {
|
|
239
|
+
content: string,
|
|
240
|
+
sender: "user" | "bot"
|
|
241
|
+
}[]) => void,
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
// Input field
|
|
245
|
+
input: {
|
|
246
|
+
inputValue: string,
|
|
247
|
+
setInputValue: (value: string) => void,
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
// Tips for the user
|
|
251
|
+
promptsOptions: {
|
|
252
|
+
prompts: string[],
|
|
253
|
+
setPrompts: (prompts: string[]) => void
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
// Thing that unfortunately doesn't work
|
|
257
|
+
scrollToBottom: () => void
|
|
258
|
+
}
|
|
259
|
+
```
|