Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions shortcuts/mail/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1933,6 +1933,23 @@ func validateConfirmSendScope(runtime *common.RuntimeContext) error {
return nil
}

// buildSendResult builds the output map for a successful send, including
// recall tip if the backend indicates the message is recallable.
func buildSendResult(resData map[string]interface{}, mailboxID string) map[string]interface{} {
result := map[string]interface{}{
"message_id": resData["message_id"],
"thread_id": resData["thread_id"],
}
if recallStatus, ok := resData["recall_status"].(string); ok && recallStatus == "available" {
messageID, _ := resData["message_id"].(string)
result["recall_available"] = true
result["recall_tip"] = fmt.Sprintf(
`This message can be recalled within 24 hours. To recall: lark-cli mail user_mailbox.sent_messages recall --params '{"user_mailbox_id":"%s","message_id":"%s"}'`,
mailboxID, messageID)
}
return result
}

// validateFolderReadScope checks that the user's token includes the
// mail:user_mailbox.folder:read scope. Called on-demand by listMailboxFolders
// before hitting the folders API. System folders are resolved locally and
Expand Down
5 changes: 1 addition & 4 deletions shortcuts/mail/mail_forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,7 @@ var MailForward = common.Shortcut{
if err != nil {
return fmt.Errorf("failed to send forward (draft %s created but not sent): %w", draftID, err)
}
runtime.Out(map[string]interface{}{
"message_id": resData["message_id"],
"thread_id": resData["thread_id"],
}, nil)
runtime.Out(buildSendResult(resData, mailboxID), nil)
hintMarkAsRead(runtime, mailboxID, messageId)
return nil
},
Expand Down
5 changes: 1 addition & 4 deletions shortcuts/mail/mail_reply.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,7 @@ var MailReply = common.Shortcut{
if err != nil {
return fmt.Errorf("failed to send reply (draft %s created but not sent): %w", draftID, err)
}
runtime.Out(map[string]interface{}{
"message_id": resData["message_id"],
"thread_id": resData["thread_id"],
}, nil)
runtime.Out(buildSendResult(resData, mailboxID), nil)
hintMarkAsRead(runtime, mailboxID, messageId)
return nil
},
Expand Down
5 changes: 1 addition & 4 deletions shortcuts/mail/mail_reply_all.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,7 @@ var MailReplyAll = common.Shortcut{
if err != nil {
return fmt.Errorf("failed to send reply-all (draft %s created but not sent): %w", draftID, err)
}
runtime.Out(map[string]interface{}{
"message_id": resData["message_id"],
"thread_id": resData["thread_id"],
}, nil)
runtime.Out(buildSendResult(resData, mailboxID), nil)
hintMarkAsRead(runtime, mailboxID, messageId)
return nil
},
Expand Down
5 changes: 1 addition & 4 deletions shortcuts/mail/mail_send.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,7 @@ var MailSend = common.Shortcut{
if err != nil {
return fmt.Errorf("failed to send email (draft %s created but not sent): %w", draftID, err)
}
runtime.Out(map[string]interface{}{
"message_id": resData["message_id"],
"thread_id": resData["thread_id"],
}, nil)
runtime.Out(buildSendResult(resData, mailboxID), nil)
return nil
},
}
Expand Down
24 changes: 24 additions & 0 deletions skill-template/domains/mail.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,30 @@ lark-cli mail user_mailbox.messages send_status --params '{"user_mailbox_id":"me

返回每个收件人的投递状态(`status`):1=正在投递, 2=投递失败重试, 3=退信, 4=投递成功, 5=待审批, 6=审批拒绝。向用户简要报告结果,如有异常状态(退信/审批拒绝)需重点提示。

### 撤回邮件

发送成功后,若响应中包含 `recall_available: true`,说明该邮件支持撤回(24 小时内已投递的邮件)。

**撤回操作:**
```bash
lark-cli mail user_mailbox.sent_messages recall --as user \
--params '{"user_mailbox_id":"me","message_id":"<message_id>"}'
```

- 返回 `recall_status: available` 表示撤回请求已受理(异步执行)
- 返回 `recall_status: unavailable` 表示不可撤回,`recall_restriction_reason` 说明原因

**查询撤回进度:**
```bash
lark-cli mail user_mailbox.sent_messages get_recall_detail --as user \
--params '{"user_mailbox_id":"me","message_id":"<message_id>"}'
```

- `recall_status: in_progress` — 撤回进行中,可稍后再查
- `recall_status: done` — 撤回完成,查看 `recall_result`(`all_success` / `all_fail` / `some_fail`)和每个收件人的详情

**注意:** 撤回是异步操作,`recall` 返回成功仅表示请求已受理,实际结果需通过 `get_recall_detail` 查询。若响应中无 `recall_available` 字段,说明该邮件或应用不支持撤回,不要主动提及撤回。

### 正文格式:优先使用 HTML

撰写邮件正文时,**默认使用 HTML 格式**(body 内容会被自动检测)。仅当用户明确要求纯文本时,才使用 `--plain-text` 标志强制纯文本模式。
Expand Down
31 changes: 31 additions & 0 deletions skills/lark-mail/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,30 @@ lark-cli mail user_mailbox.messages send_status --params '{"user_mailbox_id":"me

返回每个收件人的投递状态(`status`):1=正在投递, 2=投递失败重试, 3=退信, 4=投递成功, 5=待审批, 6=审批拒绝。向用户简要报告结果,如有异常状态(退信/审批拒绝)需重点提示。

### 撤回邮件

发送成功后,若响应中包含 `recall_available: true`,说明该邮件支持撤回(24 小时内已投递的邮件)。

**撤回操作:**
```bash
lark-cli mail user_mailbox.sent_messages recall --as user \
--params '{"user_mailbox_id":"me","message_id":"<message_id>"}'
```

- 返回 `recall_status: available` 表示撤回请求已受理(异步执行)
- 返回 `recall_status: unavailable` 表示不可撤回,`recall_restriction_reason` 说明原因

**查询撤回进度:**
```bash
lark-cli mail user_mailbox.sent_messages get_recall_detail --as user \
--params '{"user_mailbox_id":"me","message_id":"<message_id>"}'
```

- `recall_status: in_progress` — 撤回进行中,可稍后再查
- `recall_status: done` — 撤回完成,查看 `recall_result`(`all_success` / `all_fail` / `some_fail`)和每个收件人的详情

**注意:** 撤回是异步操作,`recall` 返回成功仅表示请求已受理,实际结果需通过 `get_recall_detail` 查询。若响应中无 `recall_available` 字段,说明该邮件或应用不支持撤回,不要主动提及撤回。

### 正文格式:优先使用 HTML

撰写邮件正文时,**默认使用 HTML 格式**(body 内容会被自动检测)。仅当用户明确要求纯文本时,才使用 `--plain-text` 标志强制纯文本模式。
Expand Down Expand Up @@ -340,6 +364,11 @@ lark-cli mail <resource> <method> [flags] # 调用 API
- `modify` — 本接口提供修改邮件会话的能力,支持移动邮件会话的文件夹、给邮件会话添加和移除标签、标记邮件会话读和未读、移动邮件会话至垃圾邮件等能力。不支持移动邮件会话到已删除文件夹,如需,请使用删除邮件会话接口。至少填写add_label_ids、remove_label_ids、add_folder中的一个参数。
- `trash` — 移动指定的邮件会话到已删除文件夹

### user_mailbox.sent_messages

- `recall` — 撤回指定邮件。前置条件:邮件须已投递,且发送时间在 24 小时以内;搬家中的域名不支持撤回。返回说明:若用户或邮件不满足撤回条件,接口仍返回 200,响应体中 recall_status 为 unavailable,recall_restriction_reason 标明具体原因。返回成功仅表示撤回请求已受理,实际撤回结果请调用「查询邮件撤回进度」接口获取。
- `get_recall_detail` — 查询指定邮件的撤回结果详情,包括整体撤回进度、成功/失败/处理中的收件人数量,以及每个收件人的撤回状态和失败原因。

## 权限表

| 方法 | 所需 scope |
Expand Down Expand Up @@ -391,4 +420,6 @@ lark-cli mail <resource> <method> [flags] # 调用 API
| `user_mailbox.threads.list` | `mail:user_mailbox.message:readonly` |
| `user_mailbox.threads.modify` | `mail:user_mailbox.message:modify` |
| `user_mailbox.threads.trash` | `mail:user_mailbox.message:modify` |
| `user_mailbox.sent_messages.recall` | `mail:user_mailbox.message:modify` |
| `user_mailbox.sent_messages.get_recall_detail` | `mail:user_mailbox.message:readonly` |

Loading