钉钉个人 IM 事件长连接监听、订阅与消费,覆盖消息接收、全部单聊/群消息、指定发送人、已读、撤回、表情回应和群生命周期,输出 NDJSON 到 stdout。Use when 用户提到 监听个人消息事件、监听所有单聊或群消息、被@消息、监听单聊或群消息、监听某人发送的消息、监听消息已读、监听消息撤回、监听消息贴表情或表情回应、监听群成员加入、监听群成员退出、监听群改名或群解散、实时接收钉钉事件、用事件驱动 Agent。命令前缀:dws event。
72
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
只使用 dws event consume 建立个人消息事件长连接。用户要求实时监听、订阅、自动回复或驱动 Agent 时,不要写轮询脚本,不要用消息历史查询模拟事件。
dws chat message send)。--profile <corpId 或 profile 名>;漏传会退回默认 profile 而失败。| Command | Purpose |
|---|---|
dws event list | 查看当前个人事件目录;不要把它当能力菜单主动展示 |
dws event schema <event_key> --flatten | 查看 Agent 使用的顶层业务字段 schema,默认 JSON |
dws event consume <event_key> [event_key...] --flatten [flags] | 阻塞消费一个或多个兼容事件;事件写到 stdout,推荐 -f ndjson |
dws event status --event <event_key> | 查看个人订阅、personal bus 和本地 consume |
dws event stop <subscribe_id> --dry-run / --yes | 先预览,再确认取消个人订阅并停止对应本地消费 |
dws event stop --all --dry-run / --yes | 先预览,再确认清理当前身份下本地记录的全部个人订阅 |
区分两个 schema:dws event schema <event_key> 查事件输出字段;dws schema "event consume" 查 consume 命令入参(统一内嵌 ToolSpec,含 parameters + 位置参数)。source 是 reviewed command identity 的 provenance;event list/schema 是 interface_mode=local,event consume/status/stop 因同时编排远端订阅控制面与本地 bus 而是 interface_mode=composite,不要把 identity 与实现机制混为一谈。
| 事件码 | 场景 | 必填参数 |
|---|---|---|
user_im_message_receive_at | 当前用户被 @ 的消息 | 无 |
user_im_message_receive_o2o | 当前用户与指定用户的单聊消息 | --user 或 --open-dingtalk-id |
user_im_message_receive_group | 当前用户所在指定群聊/会话的消息 | --group |
user_im_message_receive_user | 当前用户收到的指定用户发送的消息(单聊和群聊) | --user 或 --open-dingtalk-id |
user_im_message_receive_o2o_all | 当前用户收到的所有单聊消息 | 无 |
user_im_message_receive_group_all | 当前用户收到的所有群聊消息 | 无 |
user_im_message_read_o2o | 指定单聊中当前用户发送的消息被已读 | --user 或 --open-dingtalk-id |
user_im_message_read_group | 指定群聊中当前用户发送的消息被已读 | --group |
user_im_message_recall_o2o | 指定单聊中的消息被撤回 | --user 或 --open-dingtalk-id |
user_im_message_recall_group | 指定群聊中的消息被撤回 | --group |
user_im_message_reaction_o2o | 指定单聊中的消息收到表情回应 | --user 或 --open-dingtalk-id |
user_im_message_reaction_group | 指定群聊中的消息收到表情回应 | --group |
user_im_group_updated | 指定群聊的标题发生变更 | --group |
user_im_group_member_added | 指定群聊有成员加入 | --group |
user_im_group_member_exited | 指定群聊有成员退出 | --group |
user_im_group_disbanded | 指定群聊被解散 | --group |
只承认上表 16 个事件码。其它身份模式、应用凭证模式、非个人 IM 事件不在本 skill 范围内。
dws auth login。dws event list 作为能力菜单;按用户意图直接选择上表事件。dws aisearch person --keyword "<name>" --dimension name --format json 解析 userId;多候选必须让用户确认。--user;用户明确提供 openDingtalkId,或目标是外部联系人、机器人、跨组织身份时,使用 --open-dingtalk-id。--user 与 --open-dingtalk-id 严格二选一。不要把 openDingtalkId 填入 --user,不要自动猜测或转换身份类型;缺少外部目标的 openDingtalkId 时先追问。user_im_message_receive_o2o;“监听某人发给我的消息/监听某人发送的消息”使用 user_im_message_receive_user,后者覆盖该发送人的单聊和群聊消息。user_im_message_receive_o2o_all / user_im_message_receive_group_all;指定人或指定群仍使用范围更小的事件。dws chat search --query "<group>" --format json 解析 openConversationId;多候选必须让用户确认。user_im_group_updated;“监听有人进群”使用 user_im_group_member_added;“监听有人退群”使用 user_im_group_member_exited;“监听群解散”使用 user_im_group_disbanded。群解散自测只能使用明确的测试群,并在执行解散操作前再次提示其不可逆影响。dws chat;只有“监听/订阅消息撤回”才使用 dws event consume user_im_message_recall_*。reaction。--flatten -f ndjson。抓一条样本可用 --flatten --max-events 1 -f json。--format 只控制 JSON 序列化,--flatten 才控制数据结构。consume 命令中:用户类事件共享一个 --user 或 --open-dingtalk-id,群类事件共享一个 --group,无目标事件可加入任一类组合。--subscribe-id、--rule、--event-types、--filter、--foreground、--force 或 --debug-raw-events。--query / --filter-json 时,所选事件必须全部是消息接收事件;已读、撤回、表情回应或群生命周期事件混入后不能使用消息过滤参数。--profile <corpId 或 profile 名>;漏传会退回默认 profile 而失败。isSelfLoop 过滤):边监听边 dws chat message send 回复不成环;测试投递用别人 / 机器人发(自发会看到 0 事件)。--debug-raw-events 只用于联调确认服务端推送是否到达本地连接;正常任务不要使用。它和 --flatten 互斥,-f raw 也不能与 --flatten 同时使用。dws --profile <x> auth status(非默认组织带对 --profile);本地日志见 ~/.dws/events/<edition>/personal_stream/<hash>/bus.log(hash 见 dws event status 的 Workdir);有残留先用 dws event stop --all --dry-run 预览,确认后加 --yes 清理。看着"挂住"无输出多是误加了 --foreground(那是跑 bus、不打印事件),去掉即可。以下约束适用于上表全部 16 个事件以及多事件命令中的每一项,只治理 [event] ready 之前的订阅创建;ready 之后的 Stream 断线由长连接重连机制处理。
0/2/1 是 Agent/host 编排约束,不是 CLI 持久化硬总次数上限。每次 dws event consume 调用对每个逻辑订阅最多发送一次订阅创建 HTTP 请求,进程内不会自动重试。CLI 本地状态只持久化 in_flight、cooldown、terminal_hold 三种保护状态,不持久化或计算跨调用的 Agent/host 尝试次数。event consume 以及后续 event status/stop 必须使用同一个 --profile。不得把其它 profile 下解析出的 userId、openDingtalkId 或 openConversationId 直接带入当前 profile 的订阅。subscribe_id、trace_id 以及重新启动进程都只是诊断或执行信息,不会生成新的逻辑操作;Agent/host 必须自行延续原编排预算。retryable=false:max_additional_attempts=0,立即停止,不得自动重跑。retryable=true:max_additional_attempts=2,初次失败后最多再尝试 2 次;错误若给出 retry_after_seconds 或 next_retry_at,不得提前重试。retryable(即 retryable=unknown):Agent/host 使用 max_additional_attempts=1,最多补偿尝试 1 次;仍无法确认时停止并上报错误与 trace。in_flight 表示同一逻辑订阅已有请求执行中;cooldown 或 terminal_hold 表示当前被退避或终态保护。遇到这些状态不得递归调用 event consume、并行启动相同订阅或通过新 subId / trace 绕过;等待原请求或保护时间结束,同时由 Agent/host 继续维护自己的编排次数。~/.dws/events/open/personal_stream/<identity_hash>/personal_subscription_attempts.json。设置 DWS_CONFIG_DIR 后配置根目录随之变化;其它 edition 使用对应 edition 目录,不固定为 open。0700;personal_subscription_attempts.json 与 personal_subscription_attempts.lock 权限均为 0600。terminal_hold 持续 1h。正常处理优先等待错误中的 next_retry_at,不要把删状态文件当成常规重试手段。personal_subscription_attempts.json,不要删除 lock 文件。删除 JSON 会清空该 identity 的全部保护记录,不只影响一个事件。dws event schema <event_key> --flatten,读取 schema.properties;此模式的 jq_root_path 为 .。dws event consume <event_key> [event_key...] ... --flatten -f ndjson。单事件等待 [event] ready event_key=<key> bus_pid=<pid> subscribe_id=<id>;多事件先记录每条 [event] subscription event_key=<key> subscribe_id=<id>,再等待 [event] ready event_count=<n> bus_pid=<pid>。不要用 sleep 猜测。payload 中实际存在的字段。dws event status --event <event_key>,查看 Subscriptions 和 Consumers。dws event stop <subscribe_id> --dry-run 预览,向用户确认后再加 --yes;临时测试可用 --max-events 或 --duration 自动退出。event consume 阻塞式长连接。stdout 只出事件;stderr 只出状态 / debug / 错误。[event] ready event_key=<key> bus_pid=<pid> subscribe_id=<id>;多事件在全部逻辑 consumer 就绪后使用 [event] ready event_count=<n> bus_pid=<pid>,其前每个事件各有一条 [event] subscription ...。父进程等对应 ready 行再处理 stdout;不要 --quiet。[event] exited — received N event(s) in Xs (reason: limit|timeout|signal|bus_shutdown);受控退出码 0,失败非 0 无 exited 行。--max-events/--duration 时生效;交互终端和 < /dev/null 不触发。用管道 stdin 又要常驻就喂 < <(tail -f /dev/null)。--output-dir watcher。--max-events N 或 --duration 10m。--subscribe-id 复用的保留,--ephemeral 强制退订。优雅停用 SIGTERM、关 stdin,或外部先用 dws event stop <subscribe_id> --dry-run 预览、确认后加 --yes。不要 kill -9(跳过退订、泄漏服务端订阅)。dws event stop --all --dry-run 预览,确认后加 --yes。event_type + subscribe_id 隔离。dws event stop <subscribe_id> 只移除对应事件,最后一个被移除后进程退出。# 当前用户被 @ 的消息
dws event consume user_im_message_receive_at --flatten -f ndjson
# 当前用户与指定用户的单聊消息
dws event consume user_im_message_receive_o2o \
--user test-user-001 \
--flatten \
-f ndjson
# 使用 openDingtalkId 监听外部联系人、机器人或跨组织身份的单聊消息
dws event consume user_im_message_receive_o2o \
--open-dingtalk-id open-user-1 \
--flatten \
-f ndjson
# 指定群聊/会话消息
dws event consume user_im_message_receive_group \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 指定发送人的消息(单聊和群聊)
dws event consume user_im_message_receive_user \
--user test-user-001 \
--flatten \
-f ndjson
# 当前用户收到的所有单聊消息(仅在用户明确要求“所有”时使用)
dws event consume user_im_message_receive_o2o_all --flatten -f ndjson
# 当前用户收到的所有群聊消息(仅在用户明确要求“所有”时使用)
dws event consume user_im_message_receive_group_all --flatten -f ndjson
# 使用 openDingtalkId 监听指定发送人的消息
dws event consume user_im_message_receive_user \
--open-dingtalk-id open-user-1 \
--flatten \
-f ndjson
# 指定单聊消息已读
dws event consume user_im_message_read_o2o \
--user test-user-001 \
--flatten \
-f ndjson
# 指定群聊消息撤回
dws event consume user_im_message_recall_group \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 指定单聊消息收到表情回应
dws event consume user_im_message_reaction_o2o \
--user test-user-001 \
--flatten \
-f ndjson
# 指定群标题变更
dws event consume user_im_group_updated \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 指定群有成员加入
dws event consume user_im_group_member_added \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 指定群有成员退出
dws event consume user_im_group_member_exited \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 指定群解散
dws event consume user_im_group_disbanded \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 同一用户的单聊消息、已读和撤回(一个进程)
dws event consume \
user_im_message_receive_o2o \
user_im_message_read_o2o \
user_im_message_recall_o2o \
--user test-user-001 \
--flatten \
-f ndjson
# 同一群的消息和生命周期事件(一个进程)
dws event consume \
user_im_message_receive_group \
user_im_group_updated \
user_im_group_disbanded \
--group cidxxxxxxxx \
--flatten \
-f ndjson
# 有界自测
dws event consume user_im_message_receive_at \
--duration 10m \
--flatten \
-f ndjson
# 抓一条样本
dws event consume user_im_message_receive_o2o \
--user test-user-001 \
--max-events 1 \
--flatten \
-f json所有 *_o2o 命令和 user_im_message_receive_user 都可将 --user <userId> 替换为 --open-dingtalk-id <openDingtalkId>,但两个参数不能同时使用。
dws event schema <event_key> --flatten 是 Agent 写解析逻辑的依据。--flatten 模式的顶层 jq_root_path 为 .;不传时为兼容存量脚本的 transport envelope,业务 payload 在 .data | fromjson。schema.properties 是业务字段列表,例如 content、sender、conversation_id、message_id、event_time。--flatten,消息接收、已读、撤回和表情回应事件直接读取顶层业务字段;不要对该模式再生成 fromjson 或内部 transport 路径。quoted_message;合并转发读取可选的 forward_messages 数组。两者保留内部消息的 message_id/conversation_id/sender/sender_open_dingtalk_id/content/create_time;不要通过“聊天记录”等本地化外层文案识别或拆分合并转发。conversation_id、operator、operator_open_dingtalk_id、members、event_time。operator 是执行操作的人,members 是本次加入或退出的成员数组;成员项读取 nick 和 open_dingtalk_id。系统操作或成员自行退出时,操作人字段可能为空。type/event_id/timestamp/subscribe_id/payload。读取 payload 时以实际键为准,不猜测群标题、操作者等尚未确认的字段;完整原始协议用 -f raw 或 --debug-raw-events 排查。conversation_id;单聊自动回复使用顶层 sender_open_dingtalk_id。reader、reader_open_dingtalk_id、read_time;撤回事件读取 recaller、recaller_open_dingtalk_id、recall_time。operator、operator_open_dingtalk_id、reaction_name、reaction_text、operation_type、operation_time。content 可能是可读描述;合并转发媒体的下载定位信息位于对应 forward_messages[].content。需要实际媒体文件时调用 dws chat message download-media。| Topic | Reference | Coverage |
|---|---|---|
| IM | references/event-im.md | 十六类个人 IM 事件命令、参数、生命周期、输出解析、自测和排障 |
1877870
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.