Harnix

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ínhBắt buộcMô tả
pkMột trong baPublishable key ẩn danh của tổ chức.
token-urlMột trong baURL trên backend của bạn trả về một token phiên chat.
tokenMột trong baToken phiên chat bạn tự lấy trước.
end-user-idKhôngĐịnh danh end-user của bạn, dùng cùng user-hash và expires-at để ký pk.
user-hashKhôngChữ ký HMAC của end-user-id + expires-at bằng identity secret.
expires-atKhôngUnix timestamp hết hạn cho chữ ký user-hash.
api-urlKhôngGhi đè URL API (mặc định là URL widget được tải từ).
agentKhôngChọn agent cụ thể nếu tổ chức có nhiều agent.
modeKhôngbubble (mặc định) hoặc inline.
positionKhôngright (mặc định) hoặc left — chỉ áp dụng ở chế độ bubble.
themeKhôngauto (mặc định), light, hoặc dark.
primary-colorKhôngMã màu #rgb/#rrggbb cho màu chủ đạo.
logoKhôngURL ảnh logo hiển thị trên widget.
titleKhôngTiêu đề hiển thị trên đầu widget.
greetingKhôngCâu chào mặc định khi mở widget.
stringsKhôngChuỗ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óaGiá trị mặc định
rateLimitedToo many messages, try again in {n} s
queueFullAssistant is busy, try again in {n} s
budgetExceededDaily limit reached, please try again later
approvalTitleConfirm this action
approvalPlaceholderConfirm the action above to continue
approveApprove
approveRememberApprove for this conversation
denyDecline
approvalExpiresInExpires in {time}
approvedLineApproved · {tool}
approvedRememberLineApproved for this conversation · {tool}
deniedLineDeclined · {tool}
expiredLineExpired · {tool}
questionPlaceholderPick above or type your answer…
questionOtherOther
questionOtherPlaceholderType your own answer…
questionMultiHintChoose one or more
questionSubmitSend
questionExpiresInExpires in {time}
questionExpiredLineQuestion 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.

Trên trang này