如何用Python结合Gmail API实现生日定时批量邮件发送?
解决Gmail API定时发送生日邮件的问题
首先说你之前的代码为什么没用:Gmail会直接忽略邮件头里的Date字段,实际发送时间是按你调用API的时间算的,所以改这个表头根本实现不了定时发送。下面给你两种靠谱的方案:
方案一:用Gmail内置的延迟发送功能(推荐,适合49天内的任务)
Gmail本身支持延迟发送,通过API调用时只需指定sendAt参数即可,这个参数是未来时间的Unix时间戳(秒),而且最多只能设置49天以内的时间。
代码示例:
import time from datetime import datetime from googleapiclient.discovery import build # 假设你已经完成了Gmail API的OAuth2认证,拿到了credentials service = build('gmail', 'v1', credentials=credentials) # 计算发送时间的Unix时间戳(比如设置为目标生日当天上午9点) send_time = datetime(2024, 10, 15, 9, 0, 0) send_timestamp = int(send_time.timestamp()) # 构造邮件的raw字符串(复用你之前实现的基础发送代码生成) raw_string = "你的邮件base64编码后的raw字符串" # 构造请求体 message_body = { 'raw': raw_string, 'sendAt': send_timestamp, 'internalDateSource': 'sendAt' # 明确用sendAt作为邮件的时间来源 } # 发送定时邮件 service.users().messages().send(userId='me', body=message_body).execute()
方案二:自定义定时任务(适合超过49天的任务)
如果有些联系人的生日在49天之后,Gmail的内置延迟就用不了了,这时候可以用Python的定时任务库自己调度,比如APScheduler。
步骤:
- 先安装依赖:
pip install apscheduler pandas
- 示例代码:
from apscheduler.schedulers.background import BackgroundScheduler import pandas as pd from datetime import datetime from googleapiclient.discovery import build import base64 from email.mime.text import MIMEText # 初始化Gmail服务 service = build('gmail', 'v1', credentials=credentials) # 读取Excel联系人数据 df = pd.read_excel('contacts.xlsx') # 构造邮件的函数(复用你之前的基础发送逻辑) def create_message(sender, to, subject, message_text): msg = MIMEText(message_text) msg['to'] = to msg['from'] = sender msg['subject'] = subject return msg def send_birthday_email(recipient_email, name): # 生成邮件内容 msg = create_message('me', recipient_email, f'生日快乐,{name}!', f'亲爱的{name},祝你生日快乐!') raw_string = base64.urlsafe_b64encode(msg.as_bytes()).decode() # 发送邮件 service.users().messages().send(userId='me', body={'raw': raw_string}).execute() # 创建调度器 scheduler = BackgroundScheduler() # 遍历所有联系人,添加定时任务 for _, row in df.iterrows(): name = row['姓名'] email = row['邮箱'] birthday = row['生日'] # 假设Excel里的生日是datetime类型,不是的话要先转换 # 计算今年的生日,如果已过就用明年的 today = datetime.now() send_date = birthday.replace(year=today.year) if send_date < today: send_date = send_date.replace(year=today.year + 1) # 设置发送时间为生日当天上午9点 send_time = send_date.replace(hour=9, minute=0, second=0) # 添加定时任务 scheduler.add_job( send_birthday_email, 'date', run_date=send_time, args=[email, name] ) # 启动调度器 scheduler.start() # 保持程序运行(如果是服务器部署可以用守护进程等方式) try: while True: time.sleep(60) except (KeyboardInterrupt, SystemExit): scheduler.shutdown()
两种方案对比:
- 内置延迟发送:不用自己维护程序,Gmail帮你管调度,但只能处理49天内的任务。
- 自定义定时任务:支持任何未来时间,但需要你的程序一直运行,或者部署到云服务器(比如AWS Lambda、阿里云函数等)才能长期生效。
内容的提问来源于stack exchange,提问作者Francisco Rodriguez
相关产品推荐
相关产品推荐

