Widget
Snippet cài đặt, bảng thuộc tính, bubble vs inline, theming, CSP.
Nhúng <harnix-chat> vào trang bằng một dòng script và một thẻ tuỳ biến:
<script src="https://api.harnix.vn/v2/widget/v1/widget.js" defer></script>
<harnix-chat pk="pk_live_..." title="Hỏi chúng tôi"></harnix-chat>Widget không có runtime dependency và không đọc gì từ trang chủ nhà ngoài
những thuộc tính bạn đặt trên thẻ <harnix-chat>.
Bảng thuộc tính
Cần đúng một trong ba: pk, token-url, hoặc token.
| Thuộc tính | Bắt buộc | Mô tả |
|---|---|---|
pk | Một trong ba | Publishable key ẩn danh của tổ chức. |
token-url | Một trong ba | URL trên backend của bạn trả về một token phiên chat. |
token | Một trong ba | Token phiên chat bạn tự lấy trước. |
end-user-id | Không | Định danh end-user của bạn, dùng cùng user-hash và expires-at để ký pk. |
user-hash | Không | Chữ ký HMAC của end-user-id + expires-at bằng identity secret. |
expires-at | Không | Unix timestamp hết hạn cho chữ ký user-hash. |
api-url | Không | Ghi đè URL API (mặc định là URL widget được tải từ). |
agent | Không | Chọn agent cụ thể nếu tổ chức có nhiều agent. |
mode | Không | bubble (mặc định) hoặc inline. |
position | Không | right (mặc định) hoặc left — chỉ áp dụng ở chế độ bubble. |
theme | Không | auto (mặc định), light, hoặc dark. |
primary-color | Không | Mã màu #rgb/#rrggbb cho màu chủ đạo. |
logo | Không | URL ảnh logo hiển thị trên widget. |
title | Không | Tiêu đề hiển thị trên đầu widget. |
greeting | Không | Câu chào mặc định khi mở widget. |
strings | Không | Chuỗi JSON ghi đè nhãn hiển thị, ví dụ để dịch sang tiếng Việt. |
Ghi đè nhãn
Bạn có thể ghi đè các nhãn mặc định của widget qua thuộc tính strings. Dưới đây là các khóa có sẵn:
| Khóa | Giá trị mặc định |
|---|---|
| rateLimited | Too many messages, try again in {n} s |
| queueFull | Assistant is busy, try again in {n} s |
| budgetExceeded | Daily limit reached, please try again later |
| approvalTitle | Confirm this action |
| approvalPlaceholder | Confirm the action above to continue |
| approve | Approve |
| approveRemember | Approve for this conversation |
| deny | Decline |
| approvalExpiresIn | Expires in {time} |
| approvedLine | Approved · {tool} |
| approvedRememberLine | Approved for this conversation · {tool} |
| deniedLine | Declined · {tool} |
| expiredLine | Expired · {tool} |
| questionPlaceholder | Pick above or type your answer… |
| questionOther | Other |
| questionOtherPlaceholder | Type your own answer… |
| questionMultiHint | Choose one or more |
| questionSubmit | Send |
| questionExpiresIn | Expires in {time} |
| questionExpiredLine | Question expired |
Chuỗi {n} ở rateLimited/queueFull là số giây còn lại; {time} ở approvalExpiresIn và questionExpiresIn là thời gian còn lại định dạng "M:SS"; {tool} là tên của tool được xác nhận.
Một thuộc tính enum không hợp lệ (ví dụ position="up") sẽ rơi về giá trị
mặc định của thiết kế thay vì làm lỗi cả widget.
Xác nhận hành động
Một công cụ của connector có thể thay đổi dữ liệu — tạo đơn hàng, gửi email, cập nhật ticket. Những công cụ như vậy không chạy âm thầm. Khi agent chọn gọi một công cụ như thế, widget hiển thị một thẻ xác nhận ghi tên connector, tên công cụ, và tham số thật mà agent sắp gửi:
- Đồng ý gọi công cụ ngay với những tham số đó.
- Đồng ý cho cuộc trò chuyện này gọi công cụ và ghi nhớ quyết định này cho toàn bộ cuộc hội thoại — cùng công cụ đó sẽ không hỏi lại trong cuộc trò chuyện này.
- Từ chối không gọi công cụ; trợ lý sẽ nói lại người dùng và cuộc hội thoại tiếp tục bình thường.
Nút đếm ngược ghi "Hết hạn trong 4:32" rồi 0:00; nếu bạn không trả lời trong 5 phút, hành động coi như bị từ chối. Ô nhập tin nhắn bị khoá khi đang chờ xác nhận — bạn không thể gửi tin nhắn khác cho tới khi thẻ xác nhận được giải quyết. Nếu bạn tải lại trang, widget sẽ khôi phục thẻ từ máy chủ và kết nối lại stream để tiếp tục nhận câu trả lời.
Trả lời câu hỏi
Khi agent gọi công cụ ask_user để hỏi lại ý kiến người dùng, widget hiển thị một thẻ câu hỏi trực tiếp trong dòng tin nhắn:
- 1–4 câu hỏi: Mỗi câu có tiêu đề ngắn gọn (chip), nội dung câu hỏi, và các lựa chọn (chọn một kiểu radio hoặc chọn nhiều kiểu checkbox kèm gợi ý "Choose one or more").
- Tự gõ câu trả lời (Khác): Mỗi câu hỏi có thêm lựa chọn Khác kèm ô nhập để người dùng tự gõ câu trả lời nếu không muốn chọn các phương án có sẵn.
- Bấm gửi ngay (tap-to-send): Nếu chỉ có một câu hỏi chọn một và ô "Khác" trống, bấm vào một lựa chọn sẽ gửi câu trả lời ngay lập tức mà không cần bấm thêm nút gửi.
- Nút gửi: Với câu hỏi chọn nhiều hoặc thẻ có nhiều câu hỏi, nút Gửi chỉ bật khi mọi câu hỏi đều đã được trả lời (đã chọn phương án hoặc đã nhập câu trả lời khác).
- Gõ trực tiếp vào ô chat: Trong lúc thẻ câu hỏi đang mở, ô nhập tin nhắn ở dưới chân widget không bị khoá (placeholder chuyển thành "Pick above or type your answer…"). Bạn có thể gõ câu trả lời vào ô chat và gửi như tin nhắn bình thường; server sẽ ghi nhận tin nhắn đó là câu trả lời cho câu hỏi đang chờ, thẻ câu hỏi biến mất và câu trả lời tiếp tục stream trong cùng lượt chạy.
- Đếm ngược và hết hạn: Phía dưới thẻ có bộ đếm ngược "Expires in M:SS" (mặc định 10 phút). Nếu hết thời gian mà chưa trả lời, thẻ câu hỏi thu gọn lại thành một dòng "Question expired" và model tiếp tục xử lý với các thông tin hiện có.
- Khôi phục khi tải lại trang: Nếu người dùng tải lại trang trong khi câu hỏi đang chờ, widget sẽ khôi phục lại thẻ câu hỏi từ máy chủ và mở lại kết nối stream để tiếp tục nhận câu trả lời.