# chat-message:消息、文件、搜索与卡片 > 返回入口:[chat.md](../chat.md) ## 适用场景 用于当前用户发消息、拉消息、搜索消息、撤回、已读状态、文件/图片/音频/视频/位置/名片发送、话题回复、转发、Pin/Top、表情回应、文本翻译和流式卡片。 ## 默认入口 | 用户终点 | 默认入口 | |---|---| | 按姓名发送简单文本/Markdown | `dws chat +dm` | | 按群名发送简单文本/Markdown | `dws chat +send-to-group` | | 文件、Bot、Webhook、复杂 @、已知 ID 或幂等发送 | `dws chat +messages-send` | | 读取一个指定群聊或单聊 | `dws chat +chat-messages` | | 跨会话、多条件或全量翻页搜索 | `dws chat +search-msg` | | 引用回复已有消息 | `dws chat +messages-reply` | | 查看指定群内 @我的消息 | `dws chat +at-me --chat-query <群名>` | | 撤回当前用户消息 | `dws chat +messages-recall --msg-id ` | 以下原子命令只用于 Shortcut 未暴露的底层字段、原始响应或精确分页控制。不得把它们重新写成 上述高频任务的默认路径;写入原子命令若与 Golden Shortcut 的 confirmation 不一致,停止并 报告交付漂移,不以文档确认代替 Runtime gate。 ## 必读约束 - 发消息前必须核对接收对象、消息内容、@ 对象、附件路径和消息类型;不明确时先问用户。 - `--group`、`--user`、`--open-dingtalk-id` 通常互斥,群聊用 `--group`,单聊用 `--user` 或 `--open-dingtalk-id`。 - 发送本地文件、音频、视频默认用 `dws chat +messages-send --as user --file <相对路径>`; `audio` / `video` 的具体类型以 leaf Schema 为准。只有 Shortcut 未暴露的位置、名片等底层 类型才进入本文件的原子 fallback。 - 发送位置消息前必须确认纬度、经度、地址名称;地图缩略图需先通过旧媒体上传链路拿到 mediaId。 - 分享联系人名片前必须确认联系人 `openDingTalkId`,不要把 userId 直接当 `--contact-id`。 - 消息内容按 Markdown 渲染,换行必须是真实换行符;需要换行效果时用空行、行尾两个空格或 `
`。 - 建议发送时带 `--uuid`,失败重试复用同一个值。 - Bot/Webhook 只支持文本/Markdown;Bot 多群使用 `+messages-send --groups/--groups-file` 的逐项 ledger。不要把 user 文件/图片能力外推到 Bot。 ## 原子 fallback 命令明细 ### 发送消息的底层 fallback #### `dws chat message send`(非默认入口) 以当前用户身份发送群聊或单聊消息。 ```bash # 文本/Markdown dws chat message send --group --text "hello" dws chat message send --user --text "请查收" dws chat message send --open-dingtalk-id --text "请查收" dws chat message send --group --title "周报提醒" --text "请大家本周五前提交周报" --uuid # @ 群成员 dws chat message send --group --at-all "<@all> 请大家注意" dws chat message send --group --at-open-dingtalk-ids odt1,odt2 "<@odt1> <@odt2> 请查收" # 图片/文件/音频/视频,一条命令直发 dws chat message send --group --msg-type file --file-path ./screenshot.png dws chat message send --open-dingtalk-id --msg-type file --file-path ./report.pdf dws chat message send --group --msg-type audio --file-path ./voice.mp3 dws chat message send --group --msg-type video --file-path ./demo.mp4 # 位置/联系人名片 dws chat message send --group --msg-type location --latitude <纬度> --longitude <经度> --location-name <地址名称> --map-thumbnail-url "@mediaId" dws chat message send --group --msg-type profile --contact-id ``` 关键 flags: | Flag | 说明 | |------|------| | `--group` | 群聊 openConversationId;别名 `--id` / `--chat` / `--conversation-id` | | `--user` | 单聊接收人 userId | | `--open-dingtalk-id` | 单聊接收人 openDingTalkId | | `--text` | 消息内容,推荐使用;也支持位置参数 | | `--title` | 消息标题,未传时使用安全标题 | | `--at-all` | 群聊 @所有人,正文需含 `<@all>` | | `--at-open-dingtalk-ids` | 群聊 @指定 openDingTalkId,正文需含 `<@id>` | | `--msg-type` | `file` / `audio` / `video` / `image` / `location` / `profile`;本地音视频用 `audio` / `video`,底层按 `file` 发送 | | `--file-path` | 本地文件路径,`msg-type=file/audio/video` 时自动上传并发送 | | `--media-id` | 旧图片链路 mediaId | | `--latitude` / `--longitude` / `--location-name` | 位置消息参数 | | `--map-thumbnail-url` | 位置消息缩略图 mediaId,形如 `@mediaId` | | `--contact-id` | 联系人名片 openDingTalkId | | `--uuid` | 幂等 UUID,24h 内相同值不重复投递 | 当前没有经过验证的 Thread writer。`openConvThreadId` 只用于 `+thread-replies` 读取或 `+messages-forward-topic` 转发;不要把它作为普通 `--group` 猜测写入。引用回复使用 `+messages-reply`,但这不等于 Thread 内新增回复。 ### 拉取消息的底层 fallback 默认使用 `dws chat +chat-messages`。群聊的 `--group` 可传群名或 openConversationId; 也可用 `--chat-query` 显式按群名解析、用 `--conversation-id` 显式传稳定 ID。全量读取加 `--page-all`,必要时用 `--page-limit`、 `--max-results` 控制边界,用 `--output <相对.json>` 原子导出。只有需要原始响应或显式手工 continuation 时才使用下表;原子 `message list` 不代表自动全量分页。 | 命令 | 用途 | 示例与要点 | |------|------|------------| | `message list` | 拉取指定群聊或单聊消息 | `dws chat message list --group --time "2025-03-01 00:00:00" --direction older`;目标三选一,`--direction newer/older` 优先于旧 `--forward` | | `message list-all` | 时间范围内全部会话消息 | `dws chat message list-all --start --end --limit 100 --cursor 0`;四个参数每次请求都传,翻页用 `nextCursor` | | `message list-by-sender` | 查指定发送者消息 | `--sender-user-id` 与 `--sender-open-dingtalk-id` 二选一,跨单聊+群聊 | | `message list-mentions` | 查 @ 我的消息 | 可传 `--group` 限定群,不传查全部 | | `message list-focused` | 查特别关注人消息 | 零参数可用,可加 `--limit` / `--cursor` | | `message list-unread-conversations` | 未读会话列表 | 可选 `--count` | | `message list-topic-replies` | 拉取话题回复 | `--group --topic-id ` | | `message list-by-ids` | 按消息 ID 批量查询 | `--msg-ids msgId1,msgId2`,最多 50 条 | `message list` 注意事项: - `--group`、`--user`、`--open-dingtalk-id` 互斥且必须指定一个。 - `--time` 格式为 `yyyy-MM-dd HH:mm:ss`。 - `hasMore=true` 时,用结果中的边界 `createTime` 作为下次 `--time`。 - 返回 `openConvThreadId` 表示话题消息,完整内容需再拉 `list-topic-replies`。 ### 搜索消息的底层 fallback 默认使用 `dws chat +search-msg`;搜索内容使用 canonical `--query`,群名和发送者姓名分别使用 `--chat-query` / `--sender-query`。需要 Shortcut 未暴露的原始过滤字段或响应时,才评估 `message search-advanced`。它是原子 `message search` 的严格超集,但不是 Agent 高频默认入口。 ```bash dws chat message search-advanced --query "周报" --start "2026-04-01T00:00:00+08:00" --end "2026-04-15T00:00:00+08:00" dws chat message search-advanced --user --start --end dws chat message search-advanced --at-me --start --end dws chat message search-advanced --conversation-ids , --query "合同" --limit 50 --cursor 0 dws chat message search-advanced --message-type file --search-conv-type group_chat --query "附件" dws chat message search-advanced --only-robot-messages --query "通知" ``` | 参数 | 说明 | |------|------| | `--query` | 搜索关键词,可选 | | `--user` / `--users` | 发送者 userId | | `--sender-ids` | 发送者 openDingTalkId | | `--at-me` / `--at-ids` | @ 我 / @ 指定 openDingTalkId | | `--conversation-ids` | 多个群聊或单聊 openConversationId;别名 `--groups` | | `--message-type` | 按消息类型过滤,例如 `file` | | `--search-conv-type` | 按会话类型过滤,例如 `group_chat` | | `--only-robot-messages` | 只搜索机器人消息 | | `--start` / `--end` | ISO-8601 时间范围 | | `--cursor` / `--limit` | 分页,翻页用 `nextCursor` | 仅简单关键词搜索时可用: ```bash dws chat message search --query "changefree" --start --end --limit 50 --cursor 0 dws chat message search --query "codereview" --group --start --end ``` ### 消息状态与撤回 | 命令 | 用途 | 必填参数 | |------|------|----------| | `message query-send-status` | 查询当前用户发消息任务状态 | `--open-task-id`,来自 `message send` 返回 | | `+messages-recall` | 撤回当前用户消息 | `--msg-id`;可选 `--conversation-id`,省略时 CLI 从消息详情补齐;兼容单值 `--message-ids` | | `message edit` | 编辑已发送消息内容 | `--conversation-id` `--msg-id`,并在 `--text` / `--content` 中二选一;可选 `--title` `--at-all` `--at-open-dingtalk-ids` | | `message read-status` | 查消息已读/未读状态 | `--group` `--message-id`;可选目标用户 | `+messages-recall` 与 `recall-by-bot` 不同:前者使用 `openMessageId`,缺少会话 ID 时先只读查询消息详情;后者撤回机器人消息,需要 `robot-code + processQueryKey`。不要把 `processQueryKey` 当 `openMessageId`。 编辑消息使用 `message edit`。推荐传 `--text`,CLI 会生成 markdown content JSON:`{"title":"标题","text":"正文"}`;可选 `--title`,不传时会从正文自动生成标题。高级场景可直接传 `--content`,此时必须是完整 markdown content JSON,且不能同时传 `--text`。 @ 规则:`--at-all` 会传 `atAll=true`,正文应包含 `<@all>`,未包含时 CLI 会自动补到开头;`--at-open-dingtalk-ids` 会传 `atOpenDingTalkIds`,正文需包含对应 `<@openDingTalkId>` 占位符,裸 `@openDingTalkId` 会自动补成尖括号格式。 ```bash dws chat message edit --conversation-id --msg-id --text "更新后的内容" dws chat message edit --group --msg-id --title "标题" --text "更新后的内容" dws chat message edit --group --msg-id --text "<@all> 请查看" --at-all dws chat message edit --group --msg-id --text "<@openDingTalkId1> 请查看" --at-open-dingtalk-ids dws chat message edit --group --msg-id --content '{"title":"标题","text":"更新后的内容"}' ``` ### 回复与转发的底层 fallback 引用回复默认使用 `dws chat +messages-reply`。以下原子 reply 只保留底层字段 fallback;转发 仍按各自精确 Shortcut/leaf Schema 选择。 | 命令 | 用途 | 必填参数 | |------|------|----------| | `message reply` | 引用回复,单聊/群聊均可 | `--conversation-id` `--ref-msg-id` `--ref-sender` `--text` | | `message forward` | 转发单条消息,源/目标均支持单聊/群聊 | `--src-conversation-id` `--msg-id` `--dest-conversation-id` | | `message combine-forward` | 多条消息合并为一条转发 | `--src-conversation-id` `--msg-ids` `--dest-conversation-id`,可选 `--uuid` | | `message forward-topic` | 转发话题消息 | `--src-msg-id` `--src-conversation-id` `--src-thread-id` `--dest-conversation-id` | ### 话题与卡片 话题完整读取流程: 1. `dws chat message list --group --time ...` 获取话题主消息。 2. 如果返回 `openConvThreadId`,执行 `dws chat message list-topic-replies --group --topic-id `。 流式卡片优先使用公开 Shortcut;创建可选在同一次调用中写入内容: ```bash dws chat +messages-send-card --group --content "开始处理" --flow-status 1 dws chat +messages-update-card --biz-id --content "更新的卡片内容" --flow-status 2 dws chat +messages-update-card --biz-id --content "最终内容" --flow-status 3 ``` `flow-status`:1=处理中,2=输入中,3=完成,4=执行中,5=错误,Runtime 拒绝范围外值。 当前只支持 streaming text;不支持 Card JSON 组件或 action callback。精确边界见 [card references](../card/schema.md)。 ### Pin / Top / Favorite | 命令 | 用途 | 必填参数 | |------|------|----------| | `message set-pin-msg` / `unset-pin-msg` | 钉住/取消钉住消息 | `--open-conversation-id` `--msg-id` | | `message list-pin-msg` | 拉取钉住消息列表 | `--open-conversation-id`,可选 `--cursor` `--size` | | `message set-top-msg` / `unset-top-msg` | 置顶/取消置顶会话内某条消息 | `--open-conversation-id` `--msg-id` | | `message add-favorite` | 收藏消息 | `--open-message-id` `--open-conversation-id` | | `message remove-favorite` | 取消收藏消息 | `--open-message-id` `--open-conversation-id` | | `message list-favorites` | 查询收藏消息列表 | 可选 `--cursor` `--size` | 消息置顶 `set-top-msg` 与会话置顶 `chat set-top` 不同:前者置顶会话内消息,后者置顶整个会话。 ### 表情回应 优先查 [chat-emoji-list.md](../chat-emoji-list.md) 中的默认表情名称。 | 命令 | 场景 | 必填参数 | |------|------|----------| | `message add-emoji` / `remove-emoji` | 默认表情命中时使用 | `--conversation-id` `--msg-id` `--emoji` | | `message create-text-emotion` | 默认表情没有合适项时先创建 | `--emotion-name` `--text`,可选 `--background-id` | | `message add-text-emotion` / `remove-text-emotion` | 添加/移除文字表情 | `--conversation-id` `--msg-id` `--emotion-id` `--emotion-name` `--text` `--background-id` | | `message update-text-emotion` | 用新的文字表情替换消息上的原回应 | `--conversation-id` `--msg-id` `--old-emotion-id` `--emotion-id` `--emotion-name` `--text` `--background-id` | | `message list-emotion-replies` | 批量查询消息的表情回复和文字回复 | `--msg-ids` | ```bash dws chat message list-emotion-replies --msg-ids msgId1,msgId2,msgId3 ``` 消息 ID 可通过 `dws chat message list` 获取;该命令用于一次性查看多条消息上的 emoji 回应和文字表情回应。 ### 文本工具 #### `dws chat text translate` 将指定文本翻译成目标语言。用户只说“翻译这段文字”时使用;不要误走 `message send`。 ```bash dws chat text translate --query "你好世界" --to en_US dws chat text translate --query "Hello World" --to zh_CN dws chat text translate --query "Bonjour" --to ja_JP ``` 关键 flags: | Flag | 说明 | |------|------| | `--query` | 待翻译文本,必填 | | `--to` | 目标语言代码,必填,默认 `en_US` | ### 文件与媒体 #### `dws chat message download-media` ```bash dws chat message download-media --type mediaId --resource-id --message-id --open-conversation-id --output ./downloads/ ``` `resource-id` 来自消息内容中的 mediaId,`message-id` 来自 `openMessageId`,会话 ID 来自 `chat search` 或 `conversation-info`。 公开 `+messages-resource-download` 使用工作目录内安全相对路径、默认不覆盖、整文件临时落盘后 原子发布。当前没有 Range/断点续传;失败时保留 ledger 或错误,显式重试整个文件,不拼接残片。 ## 常见工作流 ### 群聊发文字与文件 ```bash dws chat +send-to-group --group "项目冲刺" --text "请大家本周五前提交周报" --format json dws chat +messages-send --as user --chat-query "项目冲刺" --file ./report.pdf --uuid --format json dws chat +messages-send --as user --chat-query "项目冲刺" --msg-type audio --file ./voice.mp3 --uuid --format json dws chat +messages-send --as user --chat-query "项目冲刺" --msg-type video --file ./demo.mp4 --uuid --format json # 仅 Shortcut 尚未覆盖的位置/名片底层类型才使用原子 fallback dws chat message send --group --msg-type location --latitude <纬度> --longitude <经度> --location-name <地址名称> --map-thumbnail-url "@mediaId" --format json dws chat message send --group --msg-type profile --contact-id --format json ``` ### 查消息并撤回 ```bash dws chat +chat-messages --group --direction older --format json dws chat +messages-recall --msg-id --format json ``` ### 多维度搜索 ```bash dws chat message search-advanced --query "合同" --conversation-ids , --start "2026-04-01T00:00:00+08:00" --end "2026-04-15T00:00:00+08:00" --limit 50 --cursor 0 --format json dws chat message search-advanced --message-type file --search-conv-type group_chat --query "附件" --format json ``` ## 常见错误与回退 - 发送目标不唯一:保留 resolver 返回的候选并让用户消歧;不要退回手工搜索后选择第一项。 - `unknown flag`:立即执行对应命令 `--help`,不要猜参数。 - 文件/音视频发送失败:确认本地路径可读;新链路使用 `--msg-type file|audio|video --file-path`。 - 位置消息参数不完整:先确认经纬度、地址名称和缩略图 mediaId。 - 名片发送失败:确认 `--contact-id` 是 openDingTalkId,不是 userId。 - 话题回复缺失:检查是否只拉了主消息,需继续用 `list-topic-replies`。 - `search-advanced` 无条件:至少提供 query、sender、@、conversation、时间等任一有效过滤条件。