Django使用Mandrill发送邮件时如何附带日历日程附件
问题解答
方案1:直接通过Mandrill原生能力实现(推荐)
Mandrill的发送接口原生支持自定义附件,你只需要在现有发送参数中增加日历ICS附件即可,所有主流邮箱客户端都能自动识别这类附件,弹出「添加到日历」的提示,部分客户端还会直接展示会议接受/拒绝的操作按钮,不需要额外接入其他服务。
实现步骤:
- 首先生成符合iCalendar(RFC5545)标准的ICS格式日历内容,填充事件的标题、开始/结束时间、地点、描述、组织者等信息
- 将ICS内容转为Base64编码
- 在原有的message结构体中添加
attachments字段,传入日历附件配置 - 如果需要让客户端直接识别为会议邀请而非普通附件,可以在headers中补充对应日历协议头
修改后的核心代码示例:
import mandrill import base64 from datetime import datetime # 原有初始化逻辑 mandrill_client = mandrill.Mandrill(MANDRILL_API_KEY) # 新增:生成ICS日历内容 def generate_ics(event_name, start_time: datetime, end_time: datetime, location, description, organizer_email): # 时间需转成UTC时区的YYYYMMDDTHHMMSSZ格式 start_str = start_time.strftime("%Y%m%dT%H%M%SZ") end_str = end_time.strftime("%Y%m%dT%H%M%SZ") ics_content = f"""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Your Company//Event Calendar//CN METHOD:REQUEST BEGIN:VEVENT UID:{datetime.now().timestamp()}@yourdomain.com DTSTAMP:{datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")} DTSTART:{start_str} DTEND:{end_str} SUMMARY:{event_name} DESCRIPTION:{description} LOCATION:{location} ORGANIZER;CN=Event Host:mailto:{organizer_email} SEQUENCE:0 STATUS:CONFIRMED END:VEVENT END:VCALENDAR""" return base64.b64encode(ics_content.encode('utf-8')).decode('utf-8') # 替换为实际事件参数生成ICS ics_base64 = generate_ics( event_name="XX活动 参会确认", start_time=datetime(2024,10,1,14,0), end_time=datetime(2024,10,1,17,0), location="XX会议中心3号厅", description="您已成功报名XX活动,请准时到场", organizer_email="email@xyz" ) message = { 'html': template_func, 'from_email': 'email@xyz', 'from_name': 'any_name', 'global_merge_vars': [], 'headers': { 'Reply-To': 'email@xyz', # 新增:让客户端识别为会议邀请 'Content-Class': 'urn:content-classes:calendarmessage' }, 'merge': True, 'merge_language': 'mailchimp', 'subject': "Event Registered", # 建议将标签替换为业务匹配值,原password-resets为密码重置类标签,不适合活动注册场景 'tags': ['event-registration'], 'text': 'Example text content', 'to': [{'email': to_email, 'name': user_name, 'type': 'to'}], # 新增:日历附件配置 'attachments': [ { 'type': 'text/calendar', 'name': 'event_invite.ics', 'content': ics_base64 } ] } result = mandrill_client.messages.send(message = message) print(result) status = result[0]["status"]
注意事项:
- ICS里的时间必须使用UTC时区格式,否则会出现日程时间和实际不符的问题
- UID字段要保证每个事件唯一,避免客户端重复导入日程
- 如果不需要直接弹出会议邀请按钮,仅需要用户可下载导入日历,可去掉headers里新增的Content-Class字段,保留附件即可
方案2:无附件的轻量实现方案
如果不想处理ICS生成和编码的逻辑,可以直接在邮件HTML模板里加入各主流日历服务的一键添加链接,用户点击链接后会跳转到对应日历的事件预填页面,确认后即可加入日程。
你只需要提前把事件的标题、时间、地点、描述参数URL编码后,拼接到各日历服务的添加地址即可,支持常见的谷歌日历、Outlook日历、苹果日历、国内主流日历等服务。
这种方案的优点是实现简单,不需要处理附件编码和ICS格式兼容问题;缺点是用户需要跳转外部页面,无法在邮箱内直接完成日程添加。
内容的提问来源于stack exchange,提问作者JohnTerry
相关产品推荐
相关产品推荐

