12 KiB
mail +reply
前置条件: 先阅读
../../lark-shared/SKILL.md了解认证、全局参数和安全规则。
回复指定邮件,自动处理:
- 主题前缀
Re:(已含常见回复前缀时不重复叠加) - 默认收件人为原邮件发件人
- RFC 2822 会话头(
In-Reply-To/References)维护邮件会话
默认草稿模式:
+reply默认保存为草稿,不会立即发送。如需立即发送,使用--confirm-send参数(须经用户明确确认)。优先使用+reply而不是+draft-create来创建回复草稿,因为+reply会自动处理主题、收件人和会话头。
本 skill 对应 shortcut:lark-cli mail +reply,内部步骤:
GET /open-apis/mail/v1/user_mailboxes/me/messages/{message_id}— 获取原邮件元数据GET /open-apis/mail/v1/user_mailboxes/me/profile— 获取邮箱主地址(primary_email_address,填入默认 From 头)POST /open-apis/mail/v1/user_mailboxes/me/drafts— 创建草稿POST /open-apis/mail/v1/user_mailboxes/me/drafts/{draft_id}/send— 发送草稿(仅在指定--confirm-send时执行)
CRITICAL — 发送工作流(必须遵循)
此命令默认只保存草稿,不会发送邮件。需要发送时,有两种合规方式:
方式 A(推荐) — 创建回复草稿(不带 --confirm-send):
lark-cli mail +reply --message-id <邮件ID> --body '<回复正文>'
→ 返回 draft_id
向用户展示回复摘要(目标邮件、回复内容、收件人);如果用户想先看效果,可引导其去飞书邮件里查看草稿。
用户明确同意后,发送该草稿:
lark-cli mail user_mailbox.drafts send --params '{"user_mailbox_id":"me","draft_id":"<Step 1 返回的 draft_id>"}'
方式 B(允许) — 用户已经明确确认回复对象和内容时,可直接使用 --confirm-send 立即发送。
禁止在用户未明确同意的情况下执行发送,无论是发送草稿还是直接使用 --confirm-send。
命令
# 回复一封邮件(默认保存为草稿,返回 draft_id)— HTML 推荐
lark-cli mail +reply --message-id <邮件ID> --body '<p><b>已收到</b>,稍后跟进。</p>'
# 回复并追加收件人/抄送(保存为草稿)
lark-cli mail +reply --message-id <邮件ID> --body '<p>已处理</p>' --to lead@example.com --cc colleague@example.com
# 回复时插入内嵌图片(推荐:直接用相对路径,自动解析)
lark-cli mail +reply --message-id <邮件ID> --body '<p>详见图示:<img src="./logo.png" /></p>'
# 纯文本回复(仅在内容极简时使用)
lark-cli mail +reply --message-id <邮件ID> --body '收到,谢谢!'
# 指定发件人地址
lark-cli mail +reply --message-id <邮件ID> --body '收到' --from me@example.com
# 确认发送回复(用户明确确认后使用)
lark-cli mail +reply --message-id <邮件ID> --body '<p>收到,谢谢!</p>' --confirm-send
# Dry Run(仅打印请求,不执行)
lark-cli mail +reply --message-id <邮件ID> --body '<p>测试</p>' --dry-run
参数
| 参数 | 必填 | 说明 |
|---|---|---|
--message-id <id> |
是 | 被回复的邮件 ID |
--body <text> |
是 | 回复正文。推荐使用 HTML 获得富文本排版;也支持纯文本。根据回复正文和原邮件正文自动检测 HTML。使用 --plain-text 可强制纯文本模式。支持 <img src="./local.png" /> 相对路径自动解析为内嵌图片(仅支持相对路径,不支持绝对路径) |
--from <email> |
否 | 发件人邮箱地址(EML From 头)。使用别名(send_as)发信时,设为别名地址并配合 --mailbox 指定所属邮箱。默认读取邮箱主地址 |
--mailbox <email> |
否 | 邮箱地址,指定草稿所属的邮箱(默认回退到 --from,再回退到 me)。当发件人(--from)与邮箱不同时使用。可通过 accessible_mailboxes 查询可用邮箱 |
--to <emails> |
否 | 额外收件人,多个用逗号分隔(追加到原发件人) |
--cc <emails> |
否 | 抄送邮箱,多个用逗号分隔 |
--bcc <emails> |
否 | 密送邮箱,多个用逗号分隔。与 --event-* 不兼容(见 +send 日程邀请约束) |
--plain-text |
否 | 强制纯文本模式,忽略所有 HTML 自动检测。不可与 --inline 同时使用 |
--attach <paths> |
否 | 附件文件路径,多个用逗号分隔。相对路径。当附件导致 EML 总大小超过 25 MB 时,超出部分自动上传为超大附件(HTML 邮件插入下载卡片,纯文本邮件追加下载链接),单个文件上限 3 GB |
--inline <json> |
否 | 高级用法:手动指定内嵌图片 CID 映射。推荐直接在 --body 中使用 <img src="./path" />(自动解析)。仅在需要精确控制 CID 命名时使用此参数。格式:'[{"cid":"mycid","file_path":"./logo.png"}]',在 body 中用 <img src="cid:mycid"> 引用。不可与 --plain-text 同时使用 |
--signature-id <id> |
否 | 签名 ID。附加邮箱签名到回复正文与引用块之间。运行 mail +signature 查看可用签名。不可与 --plain-text 同时使用 |
--priority <level> |
否 | 邮件优先级:high、normal、low。省略或 normal 时不设置优先级 |
--event-summary <text> |
否 | 日程标题。设置此参数即在邮件中嵌入日程邀请。需同时设置 --event-start 和 --event-end |
--event-start <time> |
条件必填 | 日程开始时间(ISO 8601) |
--event-end <time> |
条件必填 | 日程结束时间(ISO 8601) |
--event-location <text> |
否 | 日程地点 |
--confirm-send |
否 | 确认发送回复(默认只保存草稿)。仅在用户明确确认后使用 |
--send-time <timestamp> |
否 | 定时发送时间,Unix 时间戳(秒)。需至少为当前时间 + 5 分钟。配合 --confirm-send 使用可定时发送邮件 |
--request-receipt |
否 | 请求已读回执(RFC 3798 Message Disposition Notification)。在出站 EML 里写 Disposition-Notification-To: <sender> 头。收件人的邮件客户端可能弹出提示、自动发送或忽略——送达不保证 |
--dry-run |
否 | 仅打印请求,不执行 |
返回值
默认(草稿模式):
{
"ok": true,
"data": {
"draft_id": "草稿ID",
"tip": "draft saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'"
}
}
--confirm-send 模式(发送成功):
{
"ok": true,
"data": {
"message_id": "邮件ID",
"thread_id": "会话ID"
}
}
可选字段:
automation_send_disable_reason:发送被邮箱自动化设置拦截时返回的原因automation_send_disable_reference:发送被拦截时的草稿打开链接
字段语义:
- 若返回中包含
automation_send_disable_reason/automation_send_disable_reference,说明回复未真正发出,而是被邮箱设置拦截。此时应直接向用户展示原因和草稿打开链接,不要继续假设已经发送成功
典型场景
场景 1:用户说"帮我写个回复草稿"(只创建草稿)
lark-cli mail +reply --message-id <邮件ID> --body '<p>收到,谢谢!</p>'
→ 返回 draft_id,告诉用户回复草稿已创建。注意:用 +reply 而不是 +draft-create,这样草稿会自动关联原邮件的主题、收件人和会话头。
场景 2:用户说"回复这封邮件说已处理"(需要发送)
# 方式 A: 创建回复草稿
lark-cli mail +reply --message-id <邮件ID> --body '<p>已处理,谢谢。</p>'
# → 返回 draft_id
# 向用户确认 "回复给 alice@example.com,内容「已处理,谢谢。」如果你想先看效果,也可以先去飞书邮件里查看草稿。确认发送吗?"
# 用户确认后发送
lark-cli mail user_mailbox.drafts send --params '{"user_mailbox_id":"me","draft_id":"<draft_id>"}'
# 方式 B: 用户已明确确认时,直接发送
lark-cli mail +reply --message-id <邮件ID> --body '<p>已处理,谢谢。</p>' --confirm-send
场景 3:用户说"下午 3 点回复这封邮件说已处理"(定时发送)
# Step 1: 创建回复草稿
lark-cli mail +reply --message-id <邮件ID> --body '<p>已处理,谢谢。</p>'
# → 返回 draft_id
# Step 2: 向用户确认 "回复草稿已创建:回复给 alice@example.com,内容「已处理,谢谢。」定时 <目标时间> 发送。确认吗?"
# Step 3: 用户确认后定时发送(send_time 为 Unix 时间戳,需至少当前时间 + 5 分钟)
lark-cli mail user_mailbox.drafts send --params '{"user_mailbox_id":"me","draft_id":"<draft_id>"}' --data '{"send_time":"<unix_timestamp>"}'
场景 4:用户说"等等,先不回复了"(取消定时发送)
# 取消定时发送(取消后邮件变回草稿)
lark-cli mail user_mailbox.drafts cancel_scheduled_send --params '{"user_mailbox_id":"me","draft_id":"<draft_id>"}'
→ 取消成功后邮件恢复为草稿状态,用户可重新编辑或在之后重新发送。
实现说明
会话维护
本 shortcut 通过 raw EML 方式发送,包含标准 RFC 2822 会话头:
In-Reply-To: <原邮件smtp_message_id>
References: <原邮件references + smtp_message_id>
若原邮件有 thread_id,发送时会一并传入,确保回复归入同一会话。
收件人与引用
- 默认回复给原邮件发件人(
head_from) --to会在默认收件人基础上追加- 自动拼接引用块(纯文本或 HTML)
发送后跟进
回复发送后,分两种情况处理:
- 若返回中有
automation_send_disable_reason/automation_send_disable_reference:说明发送被邮箱设置拦截,应直接告诉用户原因并提供草稿打开链接,不要调用send_status
1. 确认投递状态(仅立即发送且返回非空 message_id 时必须)
用返回的 message_id 查询投递状态:
lark-cli mail user_mailbox.messages send_status --params '{"user_mailbox_id":"me","message_id":"<发送返回的 message_id>"}'
状态码:1=正在投递, 2=投递失败重试, 3=退信, 4=投递成功, 5=待审批, 6=审批拒绝。向用户简要报告投递结果,异常状态需重点提示。
1b. 定时发送(指定了 --send-time)
定时发送不会立即产生 message_id,因此 send_status 在定时发送成功后会返回"待发送"状态,不建议在定时发送后立即查询。可在预定发送时间后再查询。
如需取消定时发送:
lark-cli mail user_mailbox.drafts cancel_scheduled_send --params '{"user_mailbox_id":"me","draft_id":"<draft_id>"}'
取消后邮件会变回草稿,可继续编辑或在之后重新发送。
2. 标记已读(可选)— 询问用户是否需要将原邮件标记为已读。如果用户同意:
lark-cli mail user_mailbox.messages batch_modify_message --params '{"user_mailbox_id":"me"}' --data '{"message_ids":["<原邮件ID>"],"remove_label_ids":["UNREAD"]}'
编辑回复草稿
+reply 创建的草稿正文包含引用区(原邮件的引用块)。如果需要编辑回复草稿的正文,必须通过 --patch-file 使用 set_reply_body op,它仅替换用户撰写部分,自动保留引用区。value 只传新的用户撰写内容,不要包含引用区。
# 编辑回复草稿正文(自动保留引用区)
cat > ./patch.json << 'EOF'
{ "ops": [{ "op": "set_reply_body", "value": "<p>修改后的回复内容</p>" }] }
EOF
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
如果用户要修改引用区内容或去掉引用区,则使用 set_body 全量替换。
注意事项
- 需要已登录(
lark-cli auth login --scope "mail:user_mailbox.message:modify mail:user_mailbox.message:readonly mail:user_mailbox:readonly")且具备写/读邮件权限 - 邮件 ID 可从
lark-cli mail user_mailbox.messages list获取 --bcc仅在发送链路中生效,通常不会在收件方看到
相关命令
lark-cli mail user_mailbox.messages list— 列出邮件lark-cli mail user_mailbox.messages get— 读取邮件详情lark-cli mail +reply-all— 回复全部lark-cli mail +forward— 转发邮件