撤回消息
接口说明
撤回消息(发送者或应用服务器;时限 recallWindowMs,超时 1022)。
| 项目 | 值 |
|---|---|
| 操作 ID | message.recall |
| 起始版本 | 1.0.0 |
| 幂等 | 否 |
| 回调事件 | message.recalled |
| 所属模块 | 消息 |
请求头
| 名称 | 必填 | 说明 | 示例 |
|---|---|---|---|
App-Key | 是 | 应用 AppKey | demo |
Nonce | 是 | 随机串,8-64 字符,5 分钟内不可重复 | 9f2a7c1b |
Timestamp | 是 | epoch 毫秒,允许 ±300000ms | 1750000000000 |
Signature | 是 | hex(sha1(AppSecret + Nonce + Timestamp)) 小写 | 372e885320aabd997aafc5491f9d90fdca94432e |
X-Request-Id | 否 | 可选请求头;缺省或超过 128 字符时由服务端生成,响应原值回声 | req_7f3a9c |
请求体参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
fromUserId | string | 是 | 操作者(须为发送者,服务端代操作需应用级权限) |
messageId | string | 是 | — |
isAdmin | bool | 否 | true=应用侧强制撤回(忽略时限) |
返回结果
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
code | int | 是 | 0 表示成功;非 0 为错误码,见错误码表 |
msg | string | 否 | 错误信息;成功响应通常不返回 |
data | Message | 是 | 业务数据;成功时返回,结构见下方字段表 |
requestId | string | 是 | 服务端生成的请求 ID,便于排查;与请求头 X-Request-Id 对应 |
data 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
data.messageId | string | 是 | — |
data.clientMsgId | string | 否 | — |
data.conversationType | ConversationType | 是 | — |
data.targetId | string | 是 | — |
data.channelId | string | 否 | 超级群频道 ID(IDL rev23):conversationType=SUPER_GROUP 时可指定;仅该频道成员接收,历史按 channelId 过滤;为空表示群级消息。 |
data.senderId | string | 是 | — |
data.seq | uint64 | 是 | 会话内单调递增,服务端分配 |
data.timestamp | int64 | 是 | epoch ms |
data.content | Content | 是 | 消息内容联合体,按 type 取字段;服务端校验序列化后 <=5KB(1007)。 |
data.direction | Direction | 是 | — |
必填列取自 IDL 的 field.required;未标注的字段按非必填展示。
请求示例
APP_KEY="demo"
APP_SECRET="YOUR_APP_SECRET"
BASE_URL="https://im.example.com"
NONCE="$(openssl rand -hex 16)"
TIMESTAMP="$(date +%s%3N)"
SIGNATURE="$(printf '%s' "$APP_SECRET$NONCE$TIMESTAMP" | openssl sha1 | awk '{print $2}')"
curl -sS -X POST "$BASE_URL/im/v2/message/recall" \
-H "Content-Type: application/json" \
-H "App-Key: $APP_KEY" \
-H "Nonce: $NONCE" \
-H "Timestamp: $TIMESTAMP" \
-H "Signature: $SIGNATURE" \
-d '{"fromUserId":"user1","messageId":"msg_10001","isAdmin":false}'import { createHash, randomBytes } from 'node:crypto';
const APP_KEY = 'demo';
const APP_SECRET = 'YOUR_APP_SECRET';
const BASE_URL = 'https://im.example.com';
const PATH = '/im/v2/message/recall';
const nonce = randomBytes(16).toString('hex');
const timestamp = String(Date.now());
const signature = createHash('sha1')
.update(APP_SECRET + nonce + timestamp)
.digest('hex');
const res = await fetch(BASE_URL + PATH, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'App-Key': APP_KEY,
Nonce: nonce,
Timestamp: timestamp,
Signature: signature,
},
body: JSON.stringify({"fromUserId":"user1","messageId":"msg_10001","isAdmin":false}),
});
const result = await res.json();
if (result.code !== 0) throw new Error(result.code + ': ' + result.msg);
console.log(result.data);返回示例
JSON
{
"code": 0,
"data": {
"messageId": "msg_10001",
"clientMsgId": "client_9f2a7c",
"conversationType": 1,
"targetId": "user2",
"channelId": "channel1",
"senderId": "user1",
"seq": 1024,
"timestamp": 1750000000000,
"content": {
"type": "text",
"text": "你好,IM PaaS"
},
"direction": 1
},
"requestId": "req_7f3a9c"
}错误码
| 错误码 | 名称 | HTTP 状态 | 说明 | 可重试 | 起始版本 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 400 | 参数错误 | 否 | 1.0.0 |
1003 | FORBIDDEN | 403 | 无权限 | 否 | 1.0.0 |
1004 | USER_NOT_FOUND | 404 | 用户不存在 | 否 | 1.0.0 |
1022 | RECALL_EXPIRED | 400 | 超过撤回时限 | 否 | 1.0.0 |
1023 | MESSAGE_ALREADY_RECALLED | 400 | 消息已撤回 | 否 | 1.0.0 |