fix(mail): clarify that file path flags only accept relative paths (#141)

This commit is contained in:
feng zhi hao
2026-03-31 20:36:37 +08:00
committed by GitHub
parent 5da3075646
commit 1ffe870dc8
12 changed files with 46 additions and 44 deletions

View File

@@ -43,8 +43,8 @@ var MailDraftCreate = common.Shortcut{
{Name: "cc", Desc: "Optional. Full Cc recipient list. Separate multiple addresses with commas. Display-name format is supported."},
{Name: "bcc", Desc: "Optional. Full Bcc recipient list. Separate multiple addresses with commas. Display-name format is supported."},
{Name: "plain-text", Type: "bool", Desc: "Force plain-text mode, ignoring HTML auto-detection. Cannot be used with --inline."},
{Name: "attach", Desc: "Optional. Regular attachment file paths. Separate multiple paths with commas. Each path must point to a readable local file."},
{Name: "inline", Desc: "Optional. Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<local-path>\"}. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "attach", Desc: "Optional. Regular attachment file paths (relative path only). Separate multiple paths with commas. Each path must point to a readable local file."},
{Name: "inline", Desc: "Optional. Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<relative-path>\"}. All file_path values must be relative paths. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
input, err := parseDraftCreateInput(runtime)

View File

@@ -32,7 +32,7 @@ var MailDraftEdit = common.Shortcut{
{Name: "set-to", Desc: "Replace the entire To recipient list with the addresses provided here. Separate multiple addresses with commas. Display-name format is supported."},
{Name: "set-cc", Desc: "Replace the entire Cc recipient list with the addresses provided here. Separate multiple addresses with commas. Display-name format is supported."},
{Name: "set-bcc", Desc: "Replace the entire Bcc recipient list with the addresses provided here. Separate multiple addresses with commas. Display-name format is supported."},
{Name: "patch-file", Desc: "Edit entry point for body edits, incremental recipient changes, header edits, attachment changes, or inline-image changes. All body edits MUST go through --patch-file. Two body ops: set_body (full replacement including quote) and set_reply_body (replaces only user-authored content, auto-preserves quote block). Run --inspect first to check has_quoted_content, then --print-patch-template for the JSON structure."},
{Name: "patch-file", Desc: "Edit entry point for body edits, incremental recipient changes, header edits, attachment changes, or inline-image changes. All body edits MUST go through --patch-file. Two body ops: set_body (full replacement including quote) and set_reply_body (replaces only user-authored content, auto-preserves quote block). Run --inspect first to check has_quoted_content, then --print-patch-template for the JSON structure. Relative path only."},
{Name: "print-patch-template", Type: "bool", Desc: "Print the JSON template and supported operations for the --patch-file flag. Recommended first step before generating a patch file. No draft read or write is performed."},
{Name: "inspect", Type: "bool", Desc: "Inspect the draft without modifying it. Returns the draft projection including subject, recipients, body summary, has_quoted_content (whether the draft contains a reply/forward quote block), attachments_summary (with part_id and cid for each attachment), and inline_summary. Run this BEFORE editing body to check has_quoted_content: if true, use set_reply_body in --patch-file to preserve the quote; if false, use set_body."},
},
@@ -307,10 +307,10 @@ func buildDraftEditPatchTemplate() map[string]interface{} {
{"op": "set_reply_body", "shape": map[string]interface{}{"value": "string (user-authored content only, WITHOUT the quote block; the quote block is re-appended automatically)"}},
{"op": "set_header", "shape": map[string]interface{}{"name": "string", "value": "string"}},
{"op": "remove_header", "shape": map[string]interface{}{"name": "string"}},
{"op": "add_attachment", "shape": map[string]interface{}{"path": "string"}},
{"op": "add_attachment", "shape": map[string]interface{}{"path": "string(relative path)"}},
{"op": "remove_attachment", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}}},
{"op": "add_inline", "shape": map[string]interface{}{"path": "string", "cid": "string", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "replace_inline", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}, "path": "string", "cid": "string(optional)", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "add_inline", "shape": map[string]interface{}{"path": "string(relative path)", "cid": "string", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "replace_inline", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}, "path": "string(relative path)", "cid": "string(optional)", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "remove_inline", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}}},
},
"supported_ops_by_group": []map[string]interface{}{
@@ -340,10 +340,10 @@ func buildDraftEditPatchTemplate() map[string]interface{} {
{
"group": "attachments_and_inline",
"ops": []map[string]interface{}{
{"op": "add_attachment", "shape": map[string]interface{}{"path": "string"}},
{"op": "add_attachment", "shape": map[string]interface{}{"path": "string(relative path)"}},
{"op": "remove_attachment", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}}},
{"op": "add_inline", "shape": map[string]interface{}{"path": "string", "cid": "string", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "replace_inline", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}, "path": "string", "cid": "string(optional)", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "add_inline", "shape": map[string]interface{}{"path": "string(relative path)", "cid": "string", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "replace_inline", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}, "path": "string(relative path)", "cid": "string(optional)", "filename": "string(optional)", "content_type": "string(optional)"}},
{"op": "remove_inline", "shape": map[string]interface{}{"target": map[string]interface{}{"part_id": "string(optional)", "cid": "string(optional)"}}},
},
},
@@ -360,6 +360,7 @@ func buildDraftEditPatchTemplate() map[string]interface{} {
},
"notes": []string{
"`ops` is executed in order",
"all file paths (--patch-file and `path` fields in ops) must be relative — no absolute paths or .. traversal",
"all body edits MUST go through --patch-file; there is no --set-body flag",
"`set_body` replaces the ENTIRE body including any reply/forward quote block; when the draft has both text/plain and text/html, it updates the HTML body and regenerates the plain-text summary, so the input should be HTML",
"`set_reply_body` replaces only the user-authored portion of the body and automatically re-appends the trailing reply/forward quote block (generated by +reply or +forward); the value you pass should contain ONLY the new user-authored content WITHOUT the quote block — the quote block will be re-inserted automatically; if the user wants to modify content INSIDE the quote block, use `set_body` instead for full replacement; if the draft has no quote block, it behaves identically to `set_body`",

View File

@@ -30,8 +30,8 @@ var MailForward = common.Shortcut{
{Name: "cc", Desc: "CC email address(es), comma-separated"},
{Name: "bcc", Desc: "BCC email address(es), comma-separated"},
{Name: "plain-text", Type: "bool", Desc: "Force plain-text mode, ignoring all HTML auto-detection. Cannot be used with --inline."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated (appended after original attachments)"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<local-path>\"}. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated, appended after original attachments (relative path only)"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<relative-path>\"}. All file_path values must be relative paths. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "confirm-send", Type: "bool", Desc: "Send the forward immediately instead of saving as draft. Only use after the user has explicitly confirmed recipients and content."},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {

View File

@@ -28,8 +28,8 @@ var MailReply = common.Shortcut{
{Name: "cc", Desc: "Additional CC email address(es), comma-separated"},
{Name: "bcc", Desc: "BCC email address(es), comma-separated"},
{Name: "plain-text", Type: "bool", Desc: "Force plain-text mode, ignoring all HTML auto-detection. Cannot be used with --inline."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<local-path>\"}. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated (relative path only)"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<relative-path>\"}. All file_path values must be relative paths. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "confirm-send", Type: "bool", Desc: "Send the reply immediately instead of saving as draft. Only use after the user has explicitly confirmed recipients and content."},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {

View File

@@ -29,8 +29,8 @@ var MailReplyAll = common.Shortcut{
{Name: "bcc", Desc: "BCC email address(es), comma-separated"},
{Name: "remove", Desc: "Address(es) to exclude from the outgoing reply, comma-separated"},
{Name: "plain-text", Type: "bool", Desc: "Force plain-text mode, ignoring all HTML auto-detection. Cannot be used with --inline."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<local-path>\"}. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated (relative path only)"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<relative-path>\"}. All file_path values must be relative paths. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "confirm-send", Type: "bool", Desc: "Send the reply immediately instead of saving as draft. Only use after the user has explicitly confirmed recipients and content."},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {

View File

@@ -28,8 +28,8 @@ var MailSend = common.Shortcut{
{Name: "cc", Desc: "CC email address(es), comma-separated"},
{Name: "bcc", Desc: "BCC email address(es), comma-separated"},
{Name: "plain-text", Type: "bool", Desc: "Force plain-text mode, ignoring HTML auto-detection. Cannot be used with --inline."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<local-path>\"}. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "attach", Desc: "Attachment file path(s), comma-separated (relative path only)"},
{Name: "inline", Desc: "Inline images as a JSON array. Each entry: {\"cid\":\"<unique-id>\",\"file_path\":\"<relative-path>\"}. All file_path values must be relative paths. Cannot be used with --plain-text. CID images are embedded via <img src=\"cid:...\"> in the HTML body. CID is a unique identifier, e.g. a random hex string like \"a1b2c3d4e5f6a7b8c9d0\"."},
{Name: "confirm-send", Type: "bool", Desc: "Send the email immediately instead of saving as draft. Only use after the user has explicitly confirmed recipients and content."},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {

View File

@@ -48,8 +48,8 @@ lark-cli mail +draft-create --to alice@example.com --subject '测试' --body 'te
| `--cc <emails>` | 否 | 完整抄送列表,多个用逗号分隔 |
| `--bcc <emails>` | 否 | 完整密送列表,多个用逗号分隔 |
| `--plain-text` | 否 | 强制纯文本模式,忽略 HTML 自动检测。不可与 `--inline` 同时使用 |
| `--attach <paths>` | 否 | 普通附件文件路径,多个用逗号分隔 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:a1b2c3d4e5f6a7b8c9d0">` 引用 |
| `--attach <paths>` | 否 | 普通附件文件路径,多个用逗号分隔。相对路径 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`(相对路径)。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:a1b2c3d4e5f6a7b8c9d0">` 引用 |
| `--format <mode>` | 否 | 输出格式:`json`(默认)/ `pretty` / `table` / `ndjson` / `csv` |
| `--dry-run` | 否 | 仅打印请求,不执行 |

View File

@@ -69,7 +69,7 @@ lark-cli mail +draft-edit --draft-id <draft-id> --set-subject '测试' --dry-run
| `--set-to <emails>` | 否 | 用此处提供的地址替换整个 To 收件人列表 |
| `--set-cc <emails>` | 否 | 用此处提供的地址替换整个 Cc 抄送列表 |
| `--set-bcc <emails>` | 否 | 用此处提供的地址替换整个 Bcc 密送列表 |
| `--patch-file <path>` | 否 | 所有正文编辑、增量收件人编辑、邮件头编辑、附件变更和内嵌图片变更的入口。先运行 `--print-patch-template` 查看 JSON 结构 |
| `--patch-file <path>` | 否 | 所有正文编辑、增量收件人编辑、邮件头编辑、附件变更和内嵌图片变更的入口。相对路径。先运行 `--print-patch-template` 查看 JSON 结构 |
| `--print-patch-template` | 否 | 打印 `--patch-file` 的 JSON 模板和支持的操作。建议在生成补丁文件前先运行此命令。不会读取或写入草稿 |
| `--inspect` | 否 | 查看草稿但不修改。返回包含 `has_quoted_content`(是否有引用区)、`attachments_summary`(含每个附件的 `part_id``cid``filename`)和 `inline_summary` 的草稿投影 |
| `--format <mode>` | 否 | 输出格式:`json`(默认)/ `pretty` / `table` / `ndjson` / `csv` |
@@ -222,6 +222,7 @@ lark-cli mail +draft-edit --draft-id <draft_id> --inspect
- `ops` 按顺序执行
- `target` 接受 `part_id``cid`;优先级:`part_id` > `cid`
- **所有文件路径(`--patch-file` 及 ops 中的 `path`)必须为相对路径**
- **正文编辑没有 flag必须通过 `--patch-file`**
- **`set_body` 是完整替换** — 它替换整个正文内容(包括引用区)
- **`set_reply_body` 仅替换引用区前面的用户撰写部分** — 引用区自动重新拼接value 只传用户撰写内容,不要包含引用区;如果用户要修改引用区内容,用 `set_body` 全量覆盖
@@ -250,10 +251,10 @@ lark-cli mail +draft-edit --draft-id <draft_id> --inspect
lark-cli mail +draft-edit --draft-id <draft_id> --inspect
# 2. 编辑草稿(元数据用 flag正文用 patch-file
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{ "ops": [{ "op": "set_body", "value": "<p>更新后的内容</p>" }] }
EOF
lark-cli mail +draft-edit --draft-id <draft_id> --set-subject '最终版本' --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --set-subject '最终版本' --patch-file ./patch.json
# 3. 发送草稿
lark-cli mail user_mailbox.drafts send --params '{"user_mailbox_id":"me","draft_id":"<draft_id>"}'
@@ -271,10 +272,10 @@ lark-cli mail +draft-edit --draft-id <draft_id> --inspect
# body_html_summary: "<div>原有回复内容</div>..."
# 2. 使用 set_reply_body 编辑正文value 只传用户撰写内容,不含引用区)
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{ "ops": [{ "op": "set_reply_body", "value": "<p>修改后的回复内容</p>" }] }
EOF
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
```
**注意:** 如果误用 `set_body`,引用区将被覆盖丢失。如果用户明确要去掉引用区或修改引用区内容,则应使用 `set_body`
@@ -288,7 +289,7 @@ lark-cli mail +draft-edit --draft-id <draft_id> --inspect
# [{"part_id":"1.3","filename":"report.pdf","content_type":"application/pdf"}]
# 2. 编写补丁文件,使用步骤 1 中获取的 part_id
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{
"ops": [
{ "op": "remove_attachment", "target": { "part_id": "1.3" } }
@@ -298,7 +299,7 @@ cat > /tmp/patch.json << 'EOF'
EOF
# 3. 应用补丁
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
```
### 在正文中插入内嵌图片
@@ -313,7 +314,7 @@ lark-cli mail +draft-edit --draft-id <draft_id> --inspect
# projection.inline_summary: [{"part_id":"1.1.2","cid":"existing.png", ...}]
# 2. 编写补丁(注意:回复草稿用 set_reply_body普通草稿用 set_body
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{
"ops": [
{ "op": "set_body", "value": "<div>原有内容<img src=\"cid:existing.png\" /><img src=\"cid:new-image\" /></div>" },
@@ -324,7 +325,7 @@ cat > /tmp/patch.json << 'EOF'
EOF
# 3. 应用补丁
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
```
### 使用 patch-file 进行高级编辑
@@ -334,7 +335,7 @@ lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --print-patch-template
# 2. 编写补丁文件(例如添加一个抄送并移除一个附件)
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{
"ops": [
{ "op": "add_recipient", "field": "cc", "address": "carol@example.com", "name": "Carol" },
@@ -345,7 +346,7 @@ cat > /tmp/patch.json << 'EOF'
EOF
# 3. 应用补丁
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
```
## 相关命令

View File

@@ -63,8 +63,8 @@ lark-cli mail +forward --message-id <邮件ID> --to alice@example.com --dry-run
| `--cc <emails>` | 否 | 抄送邮箱,多个用逗号分隔 |
| `--bcc <emails>` | 否 | 密送邮箱,多个用逗号分隔 |
| `--plain-text` | 否 | 强制纯文本模式,忽略所有 HTML 自动检测。不可与 `--inline` 同时使用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔追加在原邮件附件之后 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:...">` 引用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔追加在原邮件附件之后。相对路径 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`(相对路径)。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:...">` 引用 |
| `--confirm-send` | 否 | 确认发送转发(默认只保存草稿)。仅在用户明确确认后使用 |
| `--dry-run` | 否 | 仅打印请求,不执行 |
@@ -157,10 +157,10 @@ lark-cli mail user_mailbox.messages batch_modify_message --params '{"user_mailbo
```bash
# 编辑转发草稿正文(自动保留引用区)
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{ "ops": [{ "op": "set_reply_body", "value": "<p>修改后的转发附言</p>" }] }
EOF
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
```
如果用户要修改引用区内容或去掉引用区,则使用 `set_body` 全量替换。

View File

@@ -67,8 +67,8 @@ lark-cli mail +reply-all --message-id <邮件ID> --body '测试' --dry-run
| `--bcc <emails>` | 否 | 密送邮箱,多个用逗号分隔 |
| `--remove <emails>` | 否 | 从自动聚合结果中排除的邮箱,多个用逗号分隔 |
| `--plain-text` | 否 | 强制纯文本模式,忽略所有 HTML 自动检测。不可与 `--inline` 同时使用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:...">` 引用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔。相对路径 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`(相对路径)。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:...">` 引用 |
| `--confirm-send` | 否 | 确认发送回复(默认只保存草稿)。仅在用户明确确认后使用 |
| `--dry-run` | 否 | 仅打印请求,不执行 |

View File

@@ -70,8 +70,8 @@ lark-cli mail +reply --message-id <邮件ID> --body '<p>测试</p>' --dry-run
| `--cc <emails>` | 否 | 抄送邮箱,多个用逗号分隔 |
| `--bcc <emails>` | 否 | 密送邮箱,多个用逗号分隔 |
| `--plain-text` | 否 | 强制纯文本模式,忽略所有 HTML 自动检测。不可与 `--inline` 同时使用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:...">` 引用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔。相对路径 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid`(唯一标识符,可用随机十六进制字符串,如 `a1b2c3d4e5f6a7b8c9d0`)和 `file_path`(相对路径)。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用,在 body 中用 `<img src="cid:...">` 引用 |
| `--confirm-send` | 否 | 确认发送回复(默认只保存草稿)。仅在用户明确确认后使用 |
| `--dry-run` | 否 | 仅打印请求,不执行 |
@@ -162,10 +162,10 @@ lark-cli mail user_mailbox.messages batch_modify_message --params '{"user_mailbo
```bash
# 编辑回复草稿正文(自动保留引用区)
cat > /tmp/patch.json << 'EOF'
cat > ./patch.json << 'EOF'
{ "ops": [{ "op": "set_reply_body", "value": "<p>修改后的回复内容</p>" }] }
EOF
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file /tmp/patch.json
lark-cli mail +draft-edit --draft-id <draft_id> --patch-file ./patch.json
```
如果用户要修改引用区内容或去掉引用区,则使用 `set_body` 全量替换。

View File

@@ -67,8 +67,8 @@ lark-cli mail +send --to alice@example.com --subject '测试' --body '<p>test</p
| `--cc <emails>` | 否 | 抄送邮箱,多个用逗号分隔 |
| `--bcc <emails>` | 否 | 密送邮箱,多个用逗号分隔 |
| `--plain-text` | 否 | 强制纯文本模式,忽略 HTML 自动检测。不可与 `--inline` 同时使用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid``file_path`。CID 为唯一标识符,可使用随机十六进制字符串(如 `a1b2c3d4e5f6a7b8c9d0`)。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用 |
| `--attach <paths>` | 否 | 附件文件路径,多个用逗号分隔。相对路径 |
| `--inline <json>` | 否 | 内嵌图片 JSON 数组,每项包含 `cid``file_path`(相对路径)。CID 为唯一标识符,可使用随机十六进制字符串(如 `a1b2c3d4e5f6a7b8c9d0`)。格式:`'[{"cid":"a1b2c3d4e5f6a7b8c9d0","file_path":"./logo.png"}]'`。不可与 `--plain-text` 同时使用 |
| `--confirm-send` | 否 | 确认发送邮件(默认只保存草稿)。仅在用户明确确认收件人和内容后使用 |
| `--dry-run` | 否 | 仅打印请求,不执行 |
@@ -131,8 +131,8 @@ lark-cli mail user_mailbox.messages send_status --params '{"user_mailbox_id":"me
## 实现说明
- 使用 EML 构建器生成完整 MIME 邮件并 base64url 编码后发送。
- `--attach` 作为普通附件添加。
- `--inline` 接受 JSON 数组,每项需提供 `cid`(唯一标识符,可用随机十六进制字符串)和 `file_path`,作为 inline part 嵌入邮件。
- `--attach` 作为普通附件添加。相对路径。
- `--inline` 接受 JSON 数组,每项需提供 `cid`(唯一标识符,可用随机十六进制字符串)和 `file_path`(相对路径),作为 inline part 嵌入邮件。
## 相关命令