Giới thiệu các màn hình web của Zalo Sandbox
Back to zalo sandboxNgoài các HTTP API mô phỏng Zalo OA, plugin web của Zalo Sandbox còn cung cấp một số màn hình giúp quan sát và thao tác trực tiếp với dữ liệu thử nghiệm. Thay vì chỉ gọi API rồi kiểm tra kết quả trong trang quản trị, lập trình viên có thể đóng vai OA và vai người dùng Zalo cùng lúc trên hai tab trình duyệt, gửi tin qua lại và theo dõi webhook được phát về ứng dụng.
Tài liệu này giới thiệu các màn hình đó, cách chúng kết nối với nhau và những API đứng phía sau.
Tổng quan
Plugin web có ba màn hình chính:
| Đường dẫn | Màn hình | Vai trò |
|---|---|---|
/zalo-sandbox | Trang giới thiệu | Điểm vào, dẫn đến các màn hình còn lại |
/zalo-sandbox/oa/chat | Giao diện chat OA | Đóng vai quản trị viên OA, nhắn tin với người dùng OA |
/zalo-sandbox/user/chat | Giao diện chat người dùng | Đóng vai người dùng Zalo: đăng ký, đăng nhập, nhắn với OA và với người dùng khác |
Nếu website chưa có theme hoặc plugin nào xử lý đường dẫn gốc
/, plugin sẽ tự đăng ký một handler chuyển hướng / sang /zalo-sandbox. Việc kiểm tra diễn ra một lần sau khi ứng dụng khởi động xong, nên khi cài thêm theme có trang chủ riêng thì cần khởi động lại để trang chủ đó được ưu tiên.
flowchart LR
I[Trang giới thiệu] --> S[Swagger]
I --> O[Chat OA]
I --> U[Chat người dùng]
O <-->|Tin nhắn trong kênh OA| U
U <-->|Kênh chat trực tiếp| U2[Người dùng khác]
U -->|Webhook user_send_*| H[Webhook của ứng dụng]
Trang giới thiệu

Trang
/zalo-sandbox hiển thị ba nút ở giữa màn hình, mỗi nút mở một tab mới:- Tài liệu Zalo Sandbox API: trang Swagger mô tả các endpoint mô phỏng Zalo OA.
- Giao diện chat OA: mở
/zalo-sandbox/oa/chat. - Giao diện chat người dùng: mở
/zalo-sandbox/user/chat.
Giao diện chat OA

Màn hình này mô phỏng giao diện Official Account Manager. Quản trị viên OA thấy danh sách người dùng OA ở cột trái và nội dung hội thoại với từng người ở khung bên phải.
Danh sách người dùng OA

Danh sách gồm toàn bộ người dùng được gán vai trò
zalo-oa-sandbox-user, được tải qua nhiều trang cho đến hết. Mỗi mục hiển thị ảnh đại diện, tên, thời gian và nội dung tin nhắn cuối. Danh sách được sắp theo tin nhắn mới nhất, người chưa có tin nhắn nằm cuối.Tin nhắn cuối được hiển thị theo chiều gửi: tin do OA gửi có tiền tố
OA:, tin do người dùng gửi thì không. Với tin có đính kèm, nội dung được thay bằng nhãn như [Hình ảnh], [Video], [Tệp]; tin template hiển thị [Tin mẫu].Hai thao tác trên đầu danh sách:
- Tìm kiếm (biểu tượng kính lúp): lọc người dùng OA theo từ khóa. Hệ thống lần lượt thử khớp chính xác username, số điện thoại, email, UUID, sau đó tìm theo tiền tố từ khóa.
- Thêm người dùng OA (biểu tượng thêm người): mở hộp thoại tìm những người dùng chưa phải người dùng OA và gán vai trò cho họ. Người vừa thêm được đưa lên đầu danh sách và mở hội thoại ngay.
Hội thoại
Khi chọn một người dùng, khung chat tải 30 tin nhắn mới nhất; cuộn lên đầu để tải thêm tin cũ. Tin do OA gửi nằm bên phải, tin do người dùng gửi nằm bên trái, các ngày khác nhau được ngăn cách bằng dải ngày.
Thanh công cụ soạn tin hỗ trợ:
- nhập văn bản và nhấn Enter hoặc nút gửi;
- chèn biểu tượng cảm xúc từ bảng emoji;
- gửi ảnh, video hoặc tệp bất kỳ.
Tin do quản trị viên gửi từ màn hình này được lưu giống hệt tin gửi qua API
/v3.0/oa/message/cs. Tin văn bản có dạng {"text": ...}; tin đính kèm dùng cấu trúc attachment.payload.elements với media_type, url, attachment_id và file_name. Nhờ vậy ứng dụng và màn hình chat người dùng đọc được chúng theo cùng một định dạng.
Giao diện chat người dùng
Màn hình này mô phỏng Zalo Web ở phía người dùng. Đăng nhập và chat nằm trong cùng một trang: khi chưa đăng nhập, trang hiển thị màn hình đăng nhập; khi đã đăng nhập, trang chuyển sang màn hình chat mà không tải lại.
Đăng nhập
Khi mở trang, hệ thống gọi
PUT /ezylogin/api/v1/access-token/renew của plugin ezylogin để kiểm tra cookie đăng nhập. Nếu token còn tồn tại, trang vào thẳng màn hình chat và phiên đăng nhập được gia hạn; nếu không, màn hình đăng nhập được hiển thị. Vì vậy làm mới trang không buộc người dùng đăng nhập lại.Người dùng có thể nhập số điện thoại hoặc tên đăng nhập:
- Nếu giá trị chỉ gồm 9 đến 11 chữ số (sau khi bỏ khoảng trắng, dấu chấm, dấu gạch), hệ thống coi đó là số điện thoại. Số chưa có
0ở đầu sẽ được thêm0; hệ thống không tự thêm+84. - Các giá trị khác được gửi nguyên văn như tên đăng nhập.
Việc xác thực được thực hiện bằng
POST /ezylogin/api/v1/login. Sai thông tin hiển thị thông báo tài khoản hoặc mật khẩu không đúng.
Đăng ký
Liên kết Đăng ký dưới form đăng nhập mở form tạo tài khoản gồm số điện thoại, họ và tên, mật khẩu và nhập lại mật khẩu. API
POST /api/v1/zalo-sandbox/user/register kiểm tra:- số điện thoại hợp lệ và chưa được đăng ký;
- họ và tên không rỗng, tối đa 128 ký tự;
- mật khẩu dài từ 6 đến 128 ký tự và khớp với ô nhập lại.
Tài khoản được tạo ở trạng thái đã kích hoạt, email được sinh ngẫu nhiên dạng
zalo_sandbox_<uuid>@zalo-sandbox.local và tên đăng nhập do EzyPlatform tự sinh. Sau khi đăng ký thành công, trang tự đăng nhập bằng số điện thoại và mật khẩu vừa nhập rồi chuyển sang màn hình chat.
Danh sách hội thoại
Mục đầu tiên luôn là Zalo Sandbox - OA, được ghim cố định để việc thử gửi và nhận tin OA thuận tiện. Bên dưới là các kênh chat trực tiếp giữa người dùng hiện tại với người dùng khác, sắp theo thời gian trò chuyện gần nhất. Mỗi kênh hiển thị tên và ảnh đại diện của người còn lại, tin nhắn cuối và số tin chưa đọc.
Các tab Tất cả và Chưa đọc cùng ô Tìm kiếm lọc danh sách ngay trên trình duyệt.
Biểu tượng thêm người mở hộp thoại Tạo cuộc trò chuyện: người dùng tìm một tài khoản đang hoạt động khác rồi nhấn Nhắn tin. Mỗi cặp người dùng chỉ có một kênh trực tiếp, được đặt tên cố định
zalo_sandbox_direct_{idNhỏ}_{idLớn}; nếu kênh đã tồn tại thì hệ thống mở lại kênh cũ.Nhắn tin
Màn hình chat hỗ trợ:
- gửi văn bản bằng Enter hoặc nút gửi;
- gửi 👍 khi nhấn nút gửi lúc ô nhập đang trống;
- chèn biểu tượng cảm xúc từ bảng emoji;
- gửi ảnh hoặc video (biểu tượng hình ảnh) và tệp bất kỳ (biểu tượng kẹp giấy).
Ảnh hiển thị dạng hình thu nhỏ, video có nút phát, tệp hiển thị biểu tượng và tên tệp. Biểu tượng 👍 xuất hiện khi rê chuột lên một tin nhắn hiện chỉ là tương tác trên giao diện, chưa được lưu.
Tin nhắn trong kênh trực tiếp được tải qua API sẵn có của ezychat. API này cũng đánh dấu kênh là đã đọc. Tin gửi đi đi qua API của Zalo Sandbox và được xử lý tương tự luồng socket của ezychat: lưu tin và media, cập nhật thời gian trò chuyện, tăng số chưa đọc của người nhận và tạo trạng thái đã gửi.
Nhắn tin với OA
Tin người dùng gửi cho OA được lưu vào kênh chat OA với các loại riêng
USER_SEND_TEXT, USER_SEND_IMAGE, USER_SEND_VIDEO và USER_SEND_FILE, để phân biệt với tin do OA gửi. Trên màn hình chat OA, các tin này hiển thị ở phía người dùng.Sau khi lưu, sandbox phát webhook đến toàn bộ URL webhook đã cấu hình với tên sự kiện tương ứng:
| Nội dung gửi | Sự kiện | Trường chính trong `message` |
|---|---|---|
| Văn bản, emoji, 👍 | user_send_text | msg_id, text |
| Ảnh | user_send_image | msg_id, attachments |
| Video | user_send_video | msg_id, attachments |
| Tệp | user_send_file | msg_id, attachments |
Payload và chữ ký
X-ZEvent-Signature dùng cùng cơ chế với chức năng phát webhook thủ công trong trang quản trị. Webhook được gửi bất đồng bộ nên việc gửi tin không bị chậm khi URL đích phản hồi chậm; lỗi phát webhook chỉ được ghi log.Nếu người dùng chưa có vai trò
zalo-oa-sandbox-user, lần đầu nhắn cho OA hệ thống sẽ tự gán vai trò này để người dùng xuất hiện trong danh sách của màn hình chat OA.Cài đặt và đăng xuất
Biểu tượng bánh răng ở cuối thanh bên mở menu cài đặt, trong đó có mục Đăng xuất. Mục này gọi
POST /logout của ezylogin để xóa cookie đăng nhập, sau đó trang trở về màn hình đăng nhập.Cập nhật dữ liệu gần thời gian thực
Hai màn hình chat không dùng socket. Thay vào đó, sandbox duy trì trong bộ nhớ các mốc thời gian thay đổi:
- một mốc chung cho kênh OA, dùng bởi màn hình chat OA;
- một mốc riêng cho từng người dùng, dùng bởi màn hình chat người dùng.
Mỗi giây, trình duyệt gọi API state tương ứng. API này chỉ đọc bộ nhớ nên rất nhẹ. Khi mốc thời gian thay đổi, trình duyệt mới gọi các API tải tin nhắn của hội thoại đang mở và làm mới danh sách hội thoại.
sequenceDiagram
participant A as Người gửi
participant S as Zalo Sandbox
participant B as Trình duyệt người nhận
A->>S: Gửi tin nhắn
S->>S: Lưu tin, cập nhật mốc thời gian
loop Mỗi giây
B->>S: GET state
S-->>B: updatedAt
end
B->>S: Mốc thay đổi, tải tin nhắn mới
Các thao tác cập nhật mốc thời gian gồm: OA gửi tin (qua API hoặc màn hình chat OA), thêm người dùng OA, người dùng gửi tin cho OA, gửi tin trong kênh trực tiếp và tạo kênh trực tiếp.
Danh sách API phục vụ các màn hình
| Phương thức | Endpoint | Đăng nhập | Mục đích |
|---|---|---|---|
GET | /api/v1/zalo-sandbox/oa/state | Không | Mốc thay đổi của kênh OA |
GET | /api/v1/zalo-sandbox/oa/users | Không | Danh sách người dùng OA, hỗ trợ keyword |
POST | /api/v1/zalo-sandbox/oa/users | Không | Gán vai trò người dùng OA |
GET | /api/v1/zalo-sandbox/users | Không | Tìm người dùng chưa phải người dùng OA |
GET | /api/v1/zalo-sandbox/oa/users/{userId}/messages | Không | Tin nhắn giữa OA và một người dùng |
POST | /api/v1/zalo-sandbox/oa/users/{userId}/messages | Không | OA gửi tin văn bản |
POST | /api/v1/zalo-sandbox/oa/users/{userId}/media-messages | Không | OA gửi ảnh, video, tệp |
POST | /api/v1/zalo-sandbox/oa/users/{userId}/read | Không | OA đánh dấu đã đọc hội thoại với một người dùng |
POST | /api/v1/zalo-sandbox/user/register | Không | Đăng ký tài khoản |
GET | /api/v1/zalo-sandbox/user/me | Có | Thông tin người dùng hiện tại |
GET | /api/v1/zalo-sandbox/user/state | Có | Mốc thay đổi của người dùng hiện tại |
GET | /api/v1/zalo-sandbox/user/direct-channels | Có | Danh sách kênh chat trực tiếp |
POST | /api/v1/zalo-sandbox/user/direct-channels | Có | Tạo hoặc mở lại kênh trực tiếp |
GET | /api/v1/zalo-sandbox/user/users | Có | Tìm người dùng để bắt đầu trò chuyện |
POST | /api/v1/zalo-sandbox/user/direct-channels/{channelId}/messages | Có | Gửi tin văn bản trong kênh trực tiếp |
POST | /api/v1/zalo-sandbox/user/direct-channels/{channelId}/media-messages | Có | Gửi ảnh, video, tệp trong kênh trực tiếp |
GET | /api/v1/zalo-sandbox/user/oa/messages | Có | Tin nhắn giữa người dùng hiện tại và OA |
POST | /api/v1/zalo-sandbox/user/oa/messages | Có | Người dùng gửi tin văn bản cho OA |
POST | /api/v1/zalo-sandbox/user/oa/media-messages | Có | Người dùng gửi ảnh, video, tệp cho OA |
Các API danh sách dùng cơ chế phân trang của EzyPlatform với
nextPageToken, prevPageToken, lastPage và limit. Các API gửi media nhận multipart với trường file.Ngoài ra, màn hình chat người dùng sử dụng các API của plugin khác: đăng nhập, gia hạn token và đăng xuất của ezylogin, cùng API tải tin nhắn kênh
GET /ezychat/api/v1/channels/{id}/messages của ezychat.Một kịch bản thử nghiệm
- Mở
/zalo-sandbox, chọn Giao diện chat người dùng và đăng ký một tài khoản mới. - Trong mục Zalo Sandbox - OA, gửi một tin văn bản và một ảnh.
- Kiểm tra ứng dụng nhận được webhook
user_send_textvàuser_send_imagevới chữ ký hợp lệ. - Mở Giao diện chat OA ở tab khác; người dùng vừa đăng ký xuất hiện trong danh sách cùng các tin vừa gửi.
- Trả lời từ màn hình chat OA, hoặc từ ứng dụng thông qua
/v3.0/oa/message/cs; tin trả lời hiện ở màn hình chat người dùng sau khoảng một giây. - Đăng ký thêm một tài khoản thứ hai, dùng Tạo cuộc trò chuyện để nhắn tin trực tiếp giữa hai tài khoản.
Giới hạn cần lưu ý
- Các màn hình chat OA và phần lớn API phía OA không yêu cầu đăng nhập; chỉ nên dùng trong môi trường thử nghiệm.
- Mốc thời gian thay đổi được lưu trong bộ nhớ của một tiến trình. Khi chạy nhiều instance, trình duyệt có thể không nhận được thay đổi xảy ra ở instance khác. Khi khởi động lại, mỗi trang đang mở sẽ làm mới dữ liệu một lần.
- Tin nhắn gửi qua socket của ezychat hoặc qua plugin khác không cập nhật mốc thời gian, nên chỉ hiển thị khi có thay đổi khác hoặc khi tải lại trang.
- Tương tác 👍 trên từng tin nhắn và các biểu tượng trang trí (sticker, danh thiếp, định dạng văn bản...) chưa có chức năng.
- Đăng nhập qua mã QR chỉ là hình minh họa.
- Người dùng mới đăng ký chỉ được gán vai trò người dùng OA khi lần đầu nhắn cho OA.