修改对话状态
通过 toggle_status 接口变更指定会话的状态,服务端会按 STATUS_TRANSITIONS 状态迁移矩阵 校验目标状态是否合法。
请求方式
POST
调用地址
https://livedesk-api.engagelab.com/api/v2/accounts/conversations/{conversation_id}/toggle_status
调用验证
详情参见 API 概述的鉴权方式说明。
请求
请求示例
curl -X POST 'https://livedesk-api.engagelab.com/api/v2/accounts/conversations/{conversation_id}/toggle_status' \
-H 'Content-Type: application/json' \
-H 'Authorization: Basic base64(api_key:api_secret)' \
-d '{
"status": "resolved",
"snoozed_until": 1715000000
}'
curl -X POST 'https://livedesk-api.engagelab.com/api/v2/accounts/conversations/{conversation_id}/toggle_status' \
-H 'Content-Type: application/json' \
-H 'Authorization: Basic base64(api_key:api_secret)' \
-d '{
"status": "resolved",
"snoozed_until": 1715000000
}'
此代码块在浮窗中显示
请求头
| 字段 | 类型 | 描述 |
|---|---|---|
| Authorization | string | 使用 Authorization: Basic base64(API Key:API Secret) 进行身份验证。请前往 API 密钥页面 获取 API Key 和 API Secret,并将两者以冒号连接后进行 Base64 编码。 |
| Content-Type | application/json | 数据类型,普通文字消息使用 application/json。 |
路径参数
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
| conversation_id | string | 是 | 对话ID。 |
请求体参数
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
| status | string | 是 | 目标状态,枚举值见下方 |
| snoozed_until | integer | 否 | 仅在 status=snoozed 时生效,UNIX 时间戳(秒)。不传表示无限期暂存 |
| sender_type | string | 否 | 仅服务端内部识别用途。当调用方为 AgentBot 且当前状态为 pending、目标状态为 open 时,会触发 bot_handoff! 流程并派发 CONVERSATION_BOT_HANDOFF 事件 |
status 枚举值
| 值 | 含义 |
|---|---|
| open | 进行中 |
| resolved | 已解决 |
| pending | 待 Bot/客服处理 |
| snoozed | 暂存 |
| closed | 已关闭(归档) |
状态迁移矩阵(STATUS_TRANSITIONS)
| 当前状态 | 允许变更到 |
|---|---|
| open | open, resolved, pending, snoozed |
| resolved | resolved, open, pending, snoozed, closed |
| pending | pending, open, resolved, snoozed |
| snoozed | snoozed, open, resolved, pending |
| closed | closed, open |
关键约束
resolved是进入closed的唯一前置状态:open/pending/snoozed都不能直接置为closed,必须先流转到resolved再归档。closed只能回到open:归档后的会话不允许直接进入resolved/pending/snoozed等其它工作中状态。- 同状态写入是幂等的:目标状态等于当前状态时跳过校验直接返回成功,不会触发回调。
- 校验在 ActiveRecord 模型层通过
validate :status_transition_allowed, if: :will_save_change_to_status?实现,对所有save!/update!/status=+save路径均生效。
响应
成功响应
HTTP 200:
{
"meta": {},
"payload": {
"success": true,
"conversation_id": 45,
"current_status": "resolved",
"snoozed_until": null
}
}
{
"meta": {},
"payload": {
"success": true,
"conversation_id": 45,
"current_status": "resolved",
"snoozed_until": null
}
}
此代码块在浮窗中显示
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
| success | boolean | save 返回值;状态变更成功为 true |
| conversation_id | integer | 会话的 display_id(账户内可见 ID) |
| current_status | string | 变更后的会话状态 |
| snoozed_until | integer / null | 当前生效的 snooze 到期时间戳;非 snoozed 状态固定为 null |
错误响应
| HTTP 状态码 | 触发条件 |
|---|---|
| 401 | 未认证 / 认证失败 |
| 403 | 当前用户对该会话所属 Inbox 没有访问权限 |
| 404 | 在当前账户下找不到对应 display_id 的会话 |
| 422 | status 不是合法枚举值、snoozed_until 解析失败,或目标状态违反 STATUS_TRANSITIONS 矩阵 |
422 响应结构
违反状态迁移矩阵(来自模型层校验,由 RequestExceptionHandler 渲染为 full_messages):
{
"message": "Status can't transition from open to closed",
"attributes": ["status"]
}
{
"message": "Status can't transition from open to closed",
"attributes": ["status"]
}
此代码块在浮窗中显示
未知 status 枚举值(来自 CustomExceptions::Conversation::InvalidStatus):
{
"message": "Invalid conversation status: \"foo\" ('foo' is not a valid status)"
}
{
"message": "Invalid conversation status: \"foo\" ('foo' is not a valid status)"
}
此代码块在浮窗中显示
非法 snoozed_until(来自 CustomExceptions::Conversation::InvalidSnoozedUntil):
{
"message": "Invalid snoozed_until: \"not-a-timestamp\" (invalid date)"
}
{
"message": "Invalid snoozed_until: \"not-a-timestamp\" (invalid date)"
}
此代码块在浮窗中显示










