Chat from Share
Hướng dẫn tích hợp luồng chia sẻ phiên chat và tiếp tục chat từ link share cho app mobile/web.
Tổng quan
┌──────────────────┐ ┌──────────────────────────┐ ┌─────────────────────────┐
│ Bấm nút Share │────▶│ Share Link (read-only) │────▶│ Continue Chat (new) │
│ POST /share │ │ GET /share/{id} │ │ WS: chat + share_id │
└──────────────────┘ └──────────────────────────┘ └─────────────────────────┘
Luồng chính:
- Tạo share - User bấm share, backend lưu snapshot tại thời điểm hiện tại
- Xem share - Bất kỳ ai có link đều xem được (public, không cần auth)
- Continue chat - User đăng nhập, gửi tin nhắn qua WebSocket với
share_id→ nhậnsession_created→ chuyển sang chat bình thường
Phase 1: Tạo Share Link
POST /v2/sessions/{session_id}/share?title=Phân+tích+HPG
Response:
{
"share_id": "2uRJLYz57j-jxwmcHpjiZQ",
"share_url": "/share/2uRJLYz57j-jxwmcHpjiZQ",
"title": "Phân tích HPG",
"expires_at": null,
"is_existing": false
}
| Field | Mô tả |
|---|---|
share_id | ID duy nhất của share link |
share_url | Path tương đối, frontend ghép với domain |
title | Tên share, mặc định lấy từ session name |
is_existing | true nếu session đã share trước đó (tự update snapshot mới) |
- Nếu session đã share, API không tạo mới mà update snapshot. Bấm share nhiều lần = cùng link, cập nhật nội dung.
- Nếu không truyền
title, tự lấysession_name. - Người xem share chỉ thấy messages đến thời điểm bấm share, chat thêm sau đó không ảnh hưởng.
Phase 2: Xem Share (Read-only)
GET /v2/share/{share_id}
Endpoint public - không cần auth token.
Response:
{
"share_info": {
"share_id": "2uRJLYz57j-jxwmcHpjiZQ",
"session_id": "f6281ea8-...",
"title": "Phân tích HPG",
"last_message_uuid": "4d09a45d-...",
"view_count": 5,
"created_at": "2026-04-01T01:36:40.787329+00:00",
"expires_at": null
},
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "phân tích hpg"
}
],
"uuid": "38ff5e7c-..."
},
{
"role": "assistant",
"message_type": "chat",
"content": [
{
"type": "text",
"text": "..."
}
],
"uuid": "a9336b5d-...",
"parent_uuid": "38ff5e7c-..."
}
],
"message_count": 12
}
Render: Messages format giống /v2/sessions/{id}/history. Dùng chung component render chat history.
Phase 3: Continue Chat từ Share
Khi user đăng nhập và gửi tin nhắn từ share view, gửi qua WebSocket với share_id.
3.1 Gửi message
{
"type": "chat",
"message": "Phân tích thêm về doanh thu Q4",
"share_id": "2uRJLYz57j-jxwmcHpjiZQ"
}
Gửi share_id thay vì session_id. Không gửi đồng thời cả hai.
3.2 Nhận session_created
Backend clone session gốc → tạo session mới → gửi event:
{
"type": "session_created",
"session_id": "dfb5e5b0-d3ce-4546-...",
"from_share": true,
"title": "Phân tích HPG"
}
Frontend xử lý khi nhận event này:
- Thêm session mới vào danh sách sidebar
- Chuyển
activeSessionIdsang session mới - Tắt share view mode
- Navigate sang
/chat/{newSessionId}
3.3 Nhận stream response
Sau session_created, tiếp tục nhận stream events giống chat bình thường:
← session_created (session mới đã tạo)
← subscribed (đã subscribe session mới)
← message_start (agent bắt đầu xử lý)
← content_block_delta (streaming nội dung)
← ...
← message_stop (hoàn thành)
Sequence Diagram
Client (WS) Server (WS)
│ │
│─── chat + share_id ─────────▶│
│ │── clone messages → new session
│◀── session_created ──────────│
│◀── subscribed ───────────────│
│ │── run agent
│◀── message_start ────────────│
│◀── content_block_delta ──────│
│◀── ... (stream events) ──────│
│◀── message_stop ─────────────│
│ │
Luồng Login từ Share
Khi user chưa đăng nhập xem share và muốn chat tiếp:
Share View → Gửi tin nhắn → Redirect /login?returnUrl=/share/xxx → Login → Redirect về /share/xxx → Gửi tin nhắn → Continue chat
Quan trọng: Khi redirect sang login, truyền returnUrl để sau login quay về đúng share page:
/login?returnUrl=%2Fshare%2F2uRJLYz57j-jxwmcHpjiZQ
Login xong, đọc returnUrl từ query params và redirect về.
Quản lý Share
Danh sách share của user
GET /v2/users/shares?page=1&page_size=12
Response:
{
"shares": [
{
"share_id": "2uRJLYz57j-...",
"session_id": "f6281ea8-...",
"title": "Phân tích HPG",
"share_type": "session",
"is_active": true,
"view_count": 5,
"created_at": "2026-04-01T01:36:40",
"expires_at": null,
"share_url": "/share/2uRJLYz57j-..."
}
],
"page": 1,
"total": 3,
"total_pages": 1
}
Xóa share
DELETE /v2/shares/{share_id}
WebSocket Reference
Chat payload
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | "chat" |
message | string | Yes | Nội dung tin nhắn |
share_id | string | Conditional | Gửi khi chat từ share (thay session_id) |
session_id | string | Conditional | Gửi khi chat bình thường |
model | string | No | Model override |
content_urls | array | No | URLs đính kèm |
Event: session_created
| Field | Type | Description |
|---|---|---|
type | string | "session_created" |
session_id | string | ID session mới được tạo |
from_share | boolean | Luôn true |
title | string | Tên session (từ share title) |
Lưu ý tích hợp
-
Share là snapshot - Bấm share = chốt nội dung tại thời điểm đó. Chat thêm sau không ảnh hưởng link share. Bấm share lại = update snapshot.
-
Session clone độc lập - Session mới từ share hoàn toàn tách biệt session gốc. Hai bên chat song song không ảnh hưởng nhau.
-
WebSocket connect khi đã login - Dù đang ở share view, nếu user đã đăng nhập thì WS phải connect sẵn để gửi tin nhắn ngay.
-
Render share giống history - API trả messages cùng format với session history. Dùng chung component render.
-
Nút share disable ở share view - Không cho share lại khi đang xem share của người khác.