飞书Mail模块深度解析:邮件收发、草稿编辑与EML构建
摘要邮件是企业正式沟通的核心载体。本文深入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--tousercompany.com--subject测试--text内容# 发送邮件lark-cli mail send --draft-iddraft_xxx# 回复邮件lark-cli mail reply --message-idmsg_xxx--text收到# 获取邮件内容lark-cli mail message --message-idmsg_xxx二、Mail Shortcuts体系2.1 邮件生命周期draft-createdraft-edit修改send发送reply回复forward转发发送回复发送转发DraftSentReplyForward图1邮件生命周期状态图2.2 草稿编辑的Patch模型飞书Mail API使用JSON Patch风格编辑草稿{update_to:[{insert:{index:0,item:{address:newcompany.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// 将飞书邮件格式转换为标准EMLRFC 5322funcBuildEML(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; charsetutf-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,OptionalimportrequestsdataclassclassMailDraft:邮件草稿draft_id:strsubject:strto:List[str]body_text:strclassMailClient:飞书邮件客户端def__init__(self,access_token:str):self.tokenaccess_token self.basehttps://open.feishu.cndefcreate_draft(self,to:List[str],subject:str,text:str)-MailDraft:创建草稿urlf{self.base}/open-apis/mail/v1/draftsresprequests.post(url,json{subject:subject,to:[{address:addr}foraddrinto],body:{content:text,content_type:text/plain},},headers{Authorization:fBearer{self.token}})dataresp.json()[data]returnMailDraft(draft_iddata[draft_id],subjectsubject,toto,body_texttext,)defsend_draft(self,draft_id:str)-dict:发送草稿urlf{self.base}/open-apis/mail/v1/drafts/{draft_id}/sendresprequests.post(url,headers{Authorization:fBearer{self.token}})returnresp.json()defreply(self,message_id:str,text:str)-dict:回复邮件urlf{self.base}/open-apis/mail/v1/messages/{message_id}/replyresprequests.post(url,json{content:text,content_type:text/plain,},headers{Authorization:fBearer{self.token}})returnresp.json()defget_message(self,message_id:str)-dict:获取邮件详情urlf{self.base}/open-apis/mail/v1/messages/{message_id}resprequests.get(url,headers{Authorization:fBearer{self.token}})returnresp.json()# 使用示例if__name____main__:clientMailClient(u-xxxxxxxx)draftclient.create_draft(to[colleaguecompany.com],subject项目进度同步,text本周完成事项\n1. API接口开发\n2. 单元测试覆盖\n,)print(f草稿ID:{draft.draft_id})# 发送resultclient.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-v1RFC 5322: Internet Message FormatRFC 2047: MIME Part Three: Message Header Extensions本文基于 lark-cli Mail模块源码分析。