摘要:邮件是企业正式沟通的核心载体。本文深入
lark-cli的shortcuts/mail/包,从草稿的创建/编辑到邮件的发送/回复/转发,从EML文件的构建到附件的处理,完整解析飞书Mail模块的Shortcuts实现。包含邮件生命周期状态图、EML构建流程图、以及Python邮件客户端的实战代码。
一、引言:邮件不是HTTP请求
1.1 邮件操作的复杂性
邮件操作远比发送一条IM消息复杂:
- 编码:中文主题需要Base64编码(RFC 2047)
- 格式:纯文本 vs HTML vs 富文本(MIME multipart)
- 附件:需要multipart/mixed编码
- 回复/转发:需要引用原文(Quote)、处理Re/Fwd前缀
- EML导出:需要完整的RFC 5322格式
1.2 lark-cli的邮件Shortcuts
# 创建草稿lark-cli mail +draft-create--to"user@company.com"--subject"测试"--text"内容"# 发送邮件lark-cli mail +send --draft-id"draft_xxx"# 回复邮件lark-cli mail +reply --message-id"msg_xxx"--text"收到"# 获取邮件内容lark-cli mail +message --message-id"msg_xxx"二、Mail Shortcuts体系
2.1 邮件生命周期
图1:邮件生命周期状态图
2.2 草稿编辑的Patch模型
飞书Mail API使用JSON Patch风格编辑草稿:
{"update_to":[{"insert":{"index":0,"item":{"address":"new@company.com"}}}],"update_subject":[{"insert":{"index":0,"text":"新主题"}}],"update_body":[{"insert":{"index":0,"text":"新内容"}}]}Shortcuts封装:+draft-edit将用户友好的参数转换为Patch操作。
2.3 EML构建
// shortcuts/mail/emlbuilder/builder.go// 将飞书邮件格式转换为标准EML(RFC 5322)funcBuildEML(message*MailMessage)([]byte,error){varbuf bytes.Buffer// 头部fmt.Fprintf(&buf,"From: %s\n",message.From)fmt.Fprintf(&buf,"To: %s\n",strings.Join(message.To,", "))fmt.Fprintf(&buf,"Subject: %s\n",encodeRFC2047(message.Subject))fmt.Fprintf(&buf,"Date: %s\n",message.Date.Format(time.RFC1123))fmt.Fprintf(&buf,"Message-ID: %s\n",message.MessageID)// MIME边界boundary:=generateBoundary()fmt.Fprintf(&buf,"Content-Type: multipart/mixed; boundary=%s\n\n",boundary)// 正文fmt.Fprintf(&buf,"--%s\n",boundary)fmt.Fprintf(&buf,"Content-Type: text/html; charset=utf-8\n\n")buf.WriteString(message.HTMLBody)// 附件for_,att:=rangemessage.Attachments{fmt.Fprintf(&buf,"\n--%s\n",boundary)fmt.Fprintf(&buf,"Content-Type: %s\n",att.ContentType)fmt.Fprintf(&buf,"Content-Disposition: attachment; filename=%s\n",att.Filename)fmt.Fprintf(&buf,"Content-Transfer-Encoding: base64\n\n")buf.WriteString(base64.StdEncoding.EncodeToString(att.Data))}fmt.Fprintf(&buf,"\n--%s--\n",boundary)returnbuf.Bytes(),nil}三、Python实战:邮件自动化工具
#!/usr/bin/env python3# -*- coding: utf-8 -*-""" mail_automation.py 飞书邮件自动化工具 """importbase64fromdataclassesimportdataclassfromtypingimportList,Optionalimportrequests@dataclassclassMailDraft:"""邮件草稿"""draft_id:strsubject:strto:List[str]body_text:strclassMailClient:"""飞书邮件客户端"""def__init__(self,access_token:str):self.token=access_token self.base="https://open.feishu.cn"defcreate_draft(self,to:List[str],subject:str,text:str)->MailDraft:"""创建草稿"""url=f"{self.base}/open-apis/mail/v1/drafts"resp=requests.post(url,json={"subject":subject,"to":[{"address":addr}foraddrinto],"body":{"content":text,"content_type":"text/plain"},},headers={"Authorization":f"Bearer{self.token}"})data=resp.json()["data"]returnMailDraft(draft_id=data["draft_id"],subject=subject,to=to,body_text=text,)defsend_draft(self,draft_id:str)->dict:"""发送草稿"""url=f"{self.base}/open-apis/mail/v1/drafts/{draft_id}/send"resp=requests.post(url,headers={"Authorization":f"Bearer{self.token}"})returnresp.json()defreply(self,message_id:str,text:str)->dict:"""回复邮件"""url=f"{self.base}/open-apis/mail/v1/messages/{message_id}/reply"resp=requests.post(url,json={"content":text,"content_type":"text/plain",},headers={"Authorization":f"Bearer{self.token}"})returnresp.json()defget_message(self,message_id:str)->dict:"""获取邮件详情"""url=f"{self.base}/open-apis/mail/v1/messages/{message_id}"resp=requests.get(url,headers={"Authorization":f"Bearer{self.token}"})returnresp.json()# 使用示例if__name__=="__main__":client=MailClient("u-xxxxxxxx")draft=client.create_draft(to=["colleague@company.com"],subject="项目进度同步",text="本周完成事项:\n1. API接口开发\n2. 单元测试覆盖\n",)print(f"草稿ID:{draft.draft_id}")# 发送result=client.send_draft(draft.draft_id)print(f"发送结果:{result.get('msg')}")四、FAQ与最佳实践
Q1:为什么邮件发送要分"创建草稿"和"发送"两步?
这是邮件系统的经典设计。草稿允许用户在发送前预览、编辑、添加附件。Shortcuts提供了
+draft-create和+send两个命令,但也支持一步完成的快捷方式。
Q2:中文主题显示乱码怎么办?
飞书Mail API内部处理RFC 2047编码。如果直接调用API,需要确保Subject使用UTF-8并进行Base64编码:
=?UTF-8?B?{base64_encoded_subject}?=
五、总结
飞书Mail模块的设计要点:
- 草稿-发送分离:支持预览和修改
- Patch编辑:增量修改草稿,而非全量替换
- EML标准兼容:导出为RFC 5322标准格式
- 引用链处理:Reply/Fwd自动处理主题前缀和原文引用
参考资料
- lark-cli 源码-
shortcuts/mail/: Mail Shortcuts - 飞书Mail API: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/mail-v1
- RFC 5322: Internet Message Format
- RFC 2047: MIME Part Three: Message Header Extensions
本文基于 lark-cli Mail模块源码分析。