Claude Code 操作 Gmail 的完整指南

Claude Code 学习笔记

分类:应用案例

核心主题:Claude Code 与 Gmail API 协同操作邮箱的完整方法论

主要内容:本文全面讲解了如何利用 Claude Code 配合 Google Gmail API 实现邮箱的自动化操作,涵盖环境配置、邮件读取与发送、搜索过滤、标签管理、附件处理、自动化工作流等核心主题,并配有可直接运行的 Python 代码示例和提示词模板。

关键词:Claude Code, Gmail, Gmail API, Google API, Python, 邮件自动化, 邮箱管理, 收件箱, 邮件发送, IMAP, SMTP

一、Claude Code 操作 Gmail 的能力边界

Claude Code 是一个 AI 编程助手,本身不直接与 Gmail 服务器通信。要操作 Gmail 邮箱,需要理解它的能力边界和正确的协作方式。

核心认知:Claude Code 无法直接读取或发送邮件,但可以通过生成和运行 Python 代码来间接操作 Gmail。正确的工作流是:由 Claude Code 编写 Python 脚本,脚本利用 Gmail API(或 IMAP/SMTP)完成实际的邮箱操作。

能力边界表

操作类型 Claude Code 能否直接完成 推荐方案
读取收件箱邮件列表 不能 用 Gmail API 获取后分析
发送邮件 不能 用 Gmail API / SMTP 发送
搜索特定邮件 不能 用 Gmail API users.messages.list 查询
管理标签/分类 不能 用 Gmail API users.labels 管理
下载附件 不能 用 Gmail API attachments.get 下载
分析邮件内容语义 可以(提取文本后) 先通过 API 获取内容,再交给 Claude Code 分析
批量处理大量邮件 可以(通过编写脚本) Claude Code 编写循环脚本批量处理
编写邮件回复草稿 可以 Claude Code 根据上下文生成回复内容,API 发送

核心工作流

在向 Claude Code 发起 Gmail 操作任务时,只需描述你想要的最终结果,Claude Code 会自动生成对应的 Python 代码(基于 Google Gmail API)来完成操作。你不需要精通 Gmail API 的所有细节,Claude Code 会帮你处理技术实现。

二、环境搭建:Gmail API 认证与 Python 库安装

要使用 Claude Code 操作 Gmail,首先需要完成 Google Cloud 项目配置和 Gmail API 的启用。以下是完整的步骤。

2.1 Google Cloud 控制台配置

  1. 访问 Google Cloud Console 并登录你的 Google 账号
  2. 点击顶部下拉菜单,创建新项目(或选择已有项目)
  3. 在左侧导航栏进入 API 和服务 > 库
  4. 搜索 Gmail API,点击进入并启用
  5. 进入 API 和服务 > 凭据,点击 创建凭据 > OAuth 客户端 ID
  6. 应用类型选择 桌面应用,填写名称后创建
  7. 下载生成的 JSON 凭据文件,重命名为 credentials.json
重要提示:首次认证时,程序会在浏览器中打开 OAuth 授权页面,需要登录 Google 账号并授予 Gmail 访问权限。授权后会生成 token.json 文件,后续运行将自动使用该 token 而无需重复授权。

2.2 Python 库安装

# 安装 Google API 客户端库 pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib # 安装邮件处理库 pip install beautifulsoup4 lxml # 用于解析 HTML 邮件

2.3 认证模块基础代码

以下是由 Claude Code 生成的 Gmail API 认证基础模块,所有 Gmail 操作都基于此模块:

import os import pickle from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build # Gmail API 的权限范围 SCOPES = ['https://www.googleapis.com/auth/gmail.modify'] def get_gmail_service(): """获取已认证的 Gmail API 服务对象""" creds = None # 尝试读取已保存的 token if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # 如果没有有效的凭据,让用户登录 if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 保存凭据供下次使用 with open('token.json', 'w') as token: token.write(creds.to_json()) return build('gmail', 'v1', credentials=creds) # 测试连接 service = get_gmail_service() profile = service.users().getProfile(userId='me').execute() print(f"已连接到: {profile['emailAddress']}")

权限范围说明

Gmail API 的 OAuth 范围(SCOPES)决定了脚本能做什么:

  • gmail.readonly — 只读权限,不能发送或修改邮件
  • gmail.modify — 读写权限,可发送、修改、删除邮件(推荐)
  • gmail.compose — 仅允许创建和发送草稿
  • gmail.send — 仅允许发送邮件
  • gmail.labels — 仅允许管理标签
  • mail.google.com — 完全访问权限(最全面,但需谨慎)

日常使用推荐 gmail.modify,它覆盖了 95% 以上的操作场景。

提示词示例

"请帮我生成一个 Gmail API 的 Python 认证模块,使用 OAuth 2.0 桌面应用流程,权限范围使用 gmail.modify。要求能够自动刷新 token 并保存到 token.json 文件中。认证后获取用户邮箱地址并打印。"

三、读取收件箱邮件:列表、详情与内容解析

读取邮件是使用最频繁的操作。Gmail API 提供了灵活的查询接口,可以按多种条件筛选邮件。

3.1 获取邮件列表

def list_messages(service, query='', max_results=10): """获取邮件列表,支持搜索查询""" try: result = service.users().messages().list( userId='me', q=query, maxResults=max_results ).execute() messages = result.get('messages', []) return messages except Exception as e: print(f"获取邮件列表出错: {e}") return [] # 使用示例 # 获取最近 5 封邮件 messages = list_messages(service, max_results=5) for msg in messages: print(f"邮件 ID: {msg['id']}, 线程 ID: {msg['threadId']}") # 搜索来自特定发件人的未读邮件 unread_from = list_messages( service, query='from:example@gmail.com is:unread', max_results=20 )
Gmail 搜索语法:Gmail API 的 q 参数支持与 Gmail 网页版相同的搜索语法。常用关键词包括:from:(发件人)、to:(收件人)、subject:(主题)、after:/before:(日期)、is:unread/is:read(已读状态)、has:attachment(有附件)、label:(标签)。Claude Code 可帮你构建复杂的搜索查询。

3.2 获取邮件详情

import base64 from email import message_from_bytes def get_message_details(service, msg_id): """获取单封邮件的详细信息""" message = service.users().messages().get( userId='me', id=msg_id, format='full' ).execute() headers = message.get('payload', {}).get('headers', []) details = {} # 提取关键头部信息 for header in headers: name = header.get('name', '').lower() if name in ['from', 'to', 'subject', 'date']: details[name] = header.get('value', '') details['id'] = msg_id details['label_ids'] = message.get('labelIds', []) details['snippet'] = message.get('snippet', '') details['internal_date'] = message.get('internalDate', '') return details # 使用示例 if messages: details = get_message_details(service, messages[0]['id']) print(f"发件人: {details.get('from', 'N/A')}") print(f"主题: {details.get('subject', 'N/A')}") print(f"摘要: {details.get('snippet', 'N/A')}")

3.3 解析邮件正文(含 HTML)

from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from bs4 import BeautifulSoup def get_message_body(service, msg_id): """获取邮件正文内容(纯文本)""" message = service.users().messages().get( userId='me', id=msg_id, format='full' ).execute() payload = message.get('payload', {}) body = '' def _extract_text(part): mime_type = part.get('mimeType', '') data = part.get('body', {}).get('data', '') if not data: return '' text = base64.urlsafe_b64decode(data).decode('utf-8', errors='ignore') if mime_type == 'text/plain': return text elif mime_type == 'text/html': soup = BeautifulSoup(text, 'html.parser') return soup.get_text(separator='\n', strip=True) return '' def _walk_parts(part): nonlocal body if part.get('mimeType') == 'text/plain' and not body: body = _extract_text(part) return elif part.get('mimeType') == 'text/html' and not body: body = _extract_text(part) return if 'parts' in part: for sub_part in part['parts']: _walk_parts(sub_part) # 处理单部分和多部分邮件 if 'parts' in payload: _walk_parts(payload) else: body = _extract_text(payload) return body # 使用示例:获取邮件正文并让 Claude Code 分析 # body = get_message_body(service, msg_id) # print(f"邮件正文预览:\n{body[:500]}...")

提示词示例

"请帮写一个 Python 脚本,连接到 Gmail API,获取最近 20 封未读邮件的发件人、主题和正文摘要,并按时间倒序输出。正文中如果是 HTML 格式请用 BeautifulSoup 提取纯文本。"

四、发送邮件:纯文本、HTML 与带附件邮件

通过 Gmail API 发送邮件需要先构建符合 RFC 2822 标准的邮件消息,再进行 Base64 编码后发送。

4.1 发送纯文本邮件

import base64 from email.message import EmailMessage def send_email(service, to, subject, body_text): """发送纯文本邮件""" message = EmailMessage() message.set_content(body_text) message['To'] = to message['From'] = 'me' message['Subject'] = subject # 编码为 Base64 URL-safe 格式 encoded = base64.urlsafe_b64encode(message.as_bytes()).decode() # 发送 send_result = service.users().messages().send( userId='me', body={'raw': encoded} ).execute() print(f"邮件已发送,ID: {send_result['id']}") return send_result # 使用示例 # send_email(service, 'friend@example.com', '你好 from Claude Code', '这是一封由 Python + Gmail API 自动发送的邮件。')

4.2 发送 HTML 格式邮件

from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText def send_html_email(service, to, subject, html_body, text_body=None): """发送 HTML 格式邮件(含纯文本备用)""" message = MIMEMultipart('alternative') message['To'] = to message['From'] = 'me' message['Subject'] = subject # 添加纯文本备用内容(某些邮件客户端只显示纯文本) if text_body: message.attach(MIMEText(text_body, 'plain')) # 添加 HTML 内容 message.attach(MIMEText(html_body, 'html')) encoded = base64.urlsafe_b64encode(message.as_bytes()).decode() return service.users().messages().send( userId='me', body={'raw': encoded} ).execute() # 使用示例(Claude Code 可以自动生成这样的 HTML) # html = '''<html><body> # <h1 style="color:#6c5ce7;">周报通知</h1> # <p>您好,以下是本周的工作总结...</p> # </body></html>''' # send_html_email(service, 'team@company.com', '本周工作周报', html)

4.3 发送带附件的邮件

from email.mime.base import MIMEBase from email import encoders import os def send_email_with_attachment(service, to, subject, body, file_paths): """发送带附件的邮件""" message = MIMEMultipart() message['To'] = to message['From'] = 'me' message['Subject'] = subject # 正文 message.attach(MIMEText(body, 'plain')) # 添加附件 for file_path in file_paths: if not os.path.exists(file_path): print(f"文件不存在: {file_path}") continue with open(file_path, 'rb') as f: attachment = MIMEBase('application', 'octet-stream') attachment.set_payload(f.read()) encoders.encode_base64(attachment) filename = os.path.basename(file_path) attachment.add_header( 'Content-Disposition', f'attachment; filename="{filename}"' ) message.attach(attachment) encoded = base64.urlsafe_b64encode(message.as_bytes()).decode() return service.users().messages().send( userId='me', body={'raw': encoded} ).execute() # 使用示例 # send_email_with_attachment( # service, 'client@example.com', '季度报告', '请查收附件中的季度报告。', # ['report.pdf', 'data.xlsx'] # )

提示词示例

"请帮我写一个 Python 函数,使用 Gmail API 发送带附件的邮件。附件可以是多个文件,支持 PDF、Excel 和图片格式。邮件正文使用 HTML 格式,包含标题、段落和表格。要求有详细的错误处理。"

五、邮件搜索与高级过滤

Gmail API 提供了强大的搜索能力,结合 Python 可以构建复杂的邮件过滤和处理流水线。

5.1 常用搜索查询模式

def search_messages(service, query, max_results=50): """通用邮件搜索函数""" try: result = service.users().messages().list( userId='me', q=query, maxResults=max_results ).execute() return result.get('messages', []) except Exception as e: print(f"搜索出错: {e}") return [] # 各种实用搜索示例 # 1. 搜索某个发件人的所有邮件 msgs = search_messages(service, 'from:newsletter@company.com') # 2. 搜索最近7天的未读邮件 from datetime import datetime, timedelta date_from = (datetime.now() - timedelta(days=7)).strftime('%Y/%m/%d') msgs = search_messages(service, f'after:{date_from} is:unread') # 3. 搜索主题中包含关键字的邮件 msgs = search_messages(service, 'subject:(invoice OR payment) has:attachment') # 4. 搜索特定标签中的邮件 msgs = search_messages(service, 'label:IMPORTANT') # 5. 搜索较大邮件(大于5MB) msgs = search_messages(service, 'size:5m') # 6. 搜索特定时间范围 start = '2026/01/01' end = '2026/03/31' msgs = search_messages(service, f'after:{start} before:{end}')

5.2 构建复杂过滤流水线

def process_inbox(service, rules): """根据自定义规则处理收件箱邮件""" results = {'processed': 0, 'actions': []} for rule in rules: query = rule.get('query', '') action = rule.get('action', '') label = rule.get('label', None) mark_read = rule.get('mark_read', False) messages = search_messages(service, query) for msg in messages: msg_id = msg['id'] actions_taken = [] # 添加标签 if label: service.users().messages().modify( userId='me', id=msg_id, body={'addLabelIds': [label]} ).execute() actions_taken.append(f"加标签: {label}") # 标记已读 if mark_read: service.users().messages().modify( userId='me', id=msg_id, body={'removeLabelIds': ['UNREAD']} ).execute() actions_taken.append("标记已读") results['actions'].append({ 'msg_id': msg_id, 'rule': query, 'actions': actions_taken }) results['processed'] += 1 return results # 使用示例:定义过滤规则 rules = [ {'query': 'from:newsletter@', 'label': 'Newsletters', 'mark_read': True}, {'query': 'subject:(invoice OR bill)', 'label': 'Bills'}, {'query': 'from:alerts@', 'label': 'Alerts'}, ] # result = process_inbox(service, rules) # print(f"处理了 {result['processed']} 封邮件")

搜索性能优化

  • 缩小搜索范围:尽量使用具体的搜索条件,避免全量扫描收件箱
  • 分页处理:使用 pageToken 参数分页获取大量结果
  • 增量处理:记录上次处理时间,只处理新增邮件
  • 使用 history API:对于实时同步场景,使用 users.history 接口获取增量变更
提示词示例:"请帮我写一个 Python 脚本,用 Gmail API 搜索最近 30 天內来自 example.com 域名、主题包含'报告'字样的所有邮件,提取发件人、主题、日期和正文摘要,保存到 CSV 文件中。"

六、标签管理:创建、应用与自动分类

Gmail 的标签系统(Labels)相当于文件夹 + 分类标签的组合。通过 API 可以创建和管理自定义标签。

6.1 创建和管理标签

def list_labels(service): """列出所有标签""" results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) for label in labels: print(f"{label['name']} (ID: {label['id']}, 类型: {label.get('type', 'N/A')})") return labels def create_label(service, name, color=None): """创建自定义标签""" label_body = { 'name': name, 'labelListVisibility': 'labelShow', 'messageListVisibility': 'show', } if color: label_body['color'] = {'backgroundColor': color} label = service.users().labels().create( userId='me', body=label_body ).execute() print(f"标签已创建: {label['name']} (ID: {label['id']})") return label def apply_label(service, msg_id, label_id): """给邮件添加标签""" service.users().messages().modify( userId='me', id=msg_id, body={'addLabelIds': [label_id]} ).execute() def remove_label(service, msg_id, label_id): """从邮件移除标签""" service.users().messages().modify( userId='me', id=msg_id, body={'removeLabelIds': [label_id]} ).execute() # 使用示例 # 1. 创建分类标签 # create_label(service, 'AI_Generated', '#6c5ce7') # create_label(service, '需要回复') # 2. 列出所有标签 # labels = list_labels(service) # 3. 给特定邮件添加标签 # apply_label(service, msg_id, 'Label_ID_Here')

6.2 基于规则的自动分类系统

def auto_classify_emails(service, max_emails=30): """自动对收件箱邮件进行分类""" # 获取未分类的收件箱邮件 messages = search_messages(service, 'in:inbox', max_emails) # 分类规则 classifiers = { 'Newsletters': ['unsubscribe', 'newsletter', 'weekly', 'digest'], 'Bills': ['invoice', 'bill', 'payment', 'receipt', 'order confirmation'], 'Social': ['facebook', 'twitter', 'linkedin', 'instagram'], 'Work': ['@company.com', 'meeting', 'project', 'deadline'], } # 确保标签存在 existing_labels = {l['name']: l['id'] for l in service.users().labels().list(userId='me').execute().get('labels', [])} label_ids = {} for name in classifiers: if name in existing_labels: label_ids[name] = existing_labels[name] else: label = create_label(service, name) label_ids[name] = label['id'] # 对每封邮件分类 classified = {name: [] for name in classifiers} classified['Uncategorized'] = [] for msg in messages: details = get_message_details(service, msg['id']) subject = details.get('subject', '').lower() sender = details.get('from', '').lower() text = subject + ' ' + sender matched = False for category, keywords in classifiers.items(): if any(kw in text for kw in keywords): apply_label(service, msg['id'], label_ids[category]) classified[category].append(details.get('subject', '')) matched = True break if not matched: classified['Uncategorized'].append(details.get('subject', '')) return classified # 使用示例 # result = auto_classify_emails(service, 50) # for category, emails in result.items(): # print(f"{category}: {len(emails)} 封邮件")

提示词示例

"请帮我用 Gmail API 创建一个邮件自动分类系统。规则如下:1)来自 newsletter@ 的邮件归类到'订阅'标签并标记已读;2)主题含 invoice/bill 的归类到'账单';3)来自同事 @company.com 域名的归类到'工作'。如果标签不存在则自动创建。"

七、附件处理:下载、保存与分析

处理邮件附件是自动化工作流中的常见需求。Gmail API 提供了附件下载和上传接口。

7.1 下载邮件附件

import os import base64 def download_attachments(service, msg_id, download_dir='attachments'): """下载指定邮件的所有附件""" os.makedirs(download_dir, exist_ok=True) message = service.users().messages().get( userId='me', id=msg_id, format='full' ).execute() downloaded = [] def _process_parts(parts): for part in parts: filename = part.get('filename', '') if filename and part.get('body'): # 检查附件数据是否直接内嵌 data = part['body'].get('data') att_id = part['body'].get('attachmentId') if data: # 直接内嵌的附件数据 file_data = base64.urlsafe_b64decode(data) elif att_id: # 需要额外请求获取附件 attachment = service.users().messages().attachments().get( userId='me', messageId=msg_id, id=att_id ).execute() file_data = base64.urlsafe_b64decode(attachment['data']) else: continue file_path = os.path.join(download_dir, filename) with open(file_path, 'wb') as f: f.write(file_data) downloaded.append(file_path) print(f"已下载: {file_path} ({len(file_data)} 字节)") # 递归处理子部件 if 'parts' in part: _process_parts(part['parts']) payload = message.get('payload', {}) if 'parts' in payload: _process_parts(payload['parts']) return downloaded # 使用示例:下载含有附件的邮件中的文件 # msgs = search_messages(service, 'has:attachment') # for msg in msgs[:5]: # files = download_attachments(service, msg['id'], 'downloads') # print(f"邮件 {msg['id']}: 下载了 {len(files)} 个文件")

7.2 批量下载与附件分析

import pandas as pd from datetime import datetime import json def batch_download_reports(service, query, download_dir): """批量下载匹配条件的邮件附件,并生成索引文件""" messages = search_messages(service, query, max_results=100) index = [] for msg in messages: details = get_message_details(service, msg['id']) files = download_attachments(service, msg['id'], download_dir) if files: index.append({ 'msg_id': msg['id'], 'date': details.get('date', ''), 'from': details.get('from', ''), 'subject': details.get('subject', ''), 'files': files }) # 保存索引 index_path = os.path.join(download_dir, 'index.json') with open(index_path, 'w', encoding='utf-8') as f: json.dump(index, f, ensure_ascii=False, indent=2) print(f"共处理 {len(messages)} 封邮件,下载附件索引已保存至: {index_path}") return index # 使用示例 # 场景:批量下载某公司发来的所有报表附件 # index = batch_download_reports( # service, 'from:reports@company.com has:attachment', './reports' # ) # Claude Code 还可以帮你分析下载的附件内容 # 例如:读取下载的 CSV/Excel 文件,汇总分析结果
提示词示例:"请帮我写一个 Python 脚本,用 Gmail API 搜索最近一个月来自 reports@company.com 且含有附件的邮件,下载所有附件到本地文件夹(按日期分类存放),并生成一个 CSV 索引文件记录每个附件的来源邮件信息。"

八、邮件自动化工作流:自动回复、转发与归档

结合 Gmail API 与 Claude Code 的能力,可以构建强大的邮件自动化工作流。

8.1 智能自动回复(含 AI 生成回复内容)

def auto_reply(service, query, reply_template, mark_read=True): """自动回复匹配条件的邮件""" messages = search_messages(service, query) replied = [] for msg in messages: details = get_message_details(service, msg['id']) sender = details.get('from', '') subject = details.get('subject', '') # 构建回复内容(可以在这里让 Claude Code 生成个性化回复) reply_body = reply_template.format( sender=sender, subject=subject, date=details.get('date', '') ) # 发送回复 send_email(service, sender, f"Re: {subject}", reply_body) # 标记已读和归档 modify_body = {'removeLabelIds': ['UNREAD', 'INBOX']} service.users().messages().modify( userId='me', id=msg['id'], body=modify_body ).execute() replied.append({'to': sender, 'subject': subject}) return replied # 使用示例:休假自动回复 # template = '''您好, # 感谢您的来信。我正在休假中,将于 5月10日 返回。 # 紧急事项请联系我的同事 (colleague@company.com)。 # 祝好!''' # result = auto_reply(service, 'in:inbox', template) # print(f"已自动回复 {len(result)} 封邮件")

8.2 邮件汇总报告

def generate_daily_digest(service): """生成每日邮件摘要报告""" today = datetime.now().strftime('%Y/%m/%d') # 获取今日各类邮件 all_today = search_messages(service, f'after:{today}') unread = search_messages(service, f'after:{today} is:unread') with_attachments = search_messages(service, f'after:{today} has:attachment') # 获取关键邮件详情 important = [] for msg in unread[:10]: details = get_message_details(service, msg['id']) details['snippet'] = get_message_body(service, msg['id'])[:100] important.append(details) # 生成报告文本(这部分可以由 Claude Code 优化为 HTML 格式) report = f"""=== 每日邮件摘要 - {datetime.now().strftime('%Y-%m-%d')} === 今日邮件总数: {len(all_today)} 未读邮件: {len(unread)} 含附件邮件: {len(with_attachments)} --- 重要未读邮件 --- """ for item in important: report += f"\n[{item.get('from', 'N/A')}] {item.get('subject', 'N/A')}\n {item.get('snippet', '')[:80]}...\n" return report # 使用示例 # digest = generate_daily_digest(service) # print(digest)

8.3 完整的定时任务工作流

# 以下是一个完整的定时任务脚本框架 # 可以配合 cron(Linux/macOS)或 任务计划程序(Windows)定时运行 def scheduled_email_workflow(): """定时执行的完整邮件工作流""" try: # 1. 连接 Gmail service = get_gmail_service() # 2. 自动分类新邮件 auto_classify_emails(service, max_emails=30) # 3. 下载报表附件 batch_download_reports( service, 'from:reports@company.com has:attachment', './auto_downloads' ) # 4. 生成摘要日志 digest = generate_daily_digest(service) log_path = f'digest_{datetime.now().strftime("%Y%m%d")}.txt' with open(log_path, 'w', encoding='utf-8') as f: f.write(digest) print(f"工作流执行完成,摘要已保存至 {log_path}") except Exception as e: print(f"工作流出错: {e}") # 发送错误通知给自己 send_email(service, 'me', 'Gmail 自动化工作流出错', str(e)) # 如果直接运行此脚本,执行工作流 # if __name__ == '__main__': # scheduled_email_workflow()

定时任务配置

将上述脚本配置为定时任务:

  • Linux/macOS:使用 cron 定时执行 python3 gmail_workflow.py
  • Windows:使用"任务计划程序",触发器设置为每天/每小时执行
  • Claude Code:也可以通过 Claude Code 的 CronCreate 功能定时生成邮件处理脚本
提示词示例:"请帮我设计一个 Gmail 自动化工作流,每天上午9点执行以下操作:1)自动分类前一天的邮件;2)下载含附件的报表到指定文件夹;3)生成一份 Markdown 格式的邮件摘要报告。请提供完整的 Python 代码和 cron 配置。"

九、替代方案:IMAP/SMTP 方式操作 Gmail

除了 Gmail API,也可以通过 IMAP 和 SMTP 协议操作 Gmail。这种方式配置简单,但功能不如 API 全面。

9.1 IMAP 读取邮件

import imaplib import email from email.header import decode_header def read_via_imap(username, password, limit=5): """通过 IMAP 读取 Gmail 邮件(需要开启"允许不够安全的应用")""" # 连接 Gmail IMAP 服务器 mail = imaplib.IMAP4_SSL('imap.gmail.com') mail.login(username, password) mail.select('inbox') # 搜索邮件 status, messages = mail.search(None, 'ALL') msg_ids = messages[0].split()[-limit:] # 获取最近的 N 封 results = [] for msg_id in msg_ids: status, msg_data = mail.fetch(msg_id, '(RFC822)') for response_part in msg_data: if isinstance(response_part, tuple): msg = email.message_from_bytes(response_part[1]) results.append({ 'from': msg.get('From'), 'subject': msg.get('Subject'), 'date': msg.get('Date'), }) mail.close() mail.logout() return results # 使用示例 # emails = read_via_imap('yourmail@gmail.com', 'app_password') # for e in emails: # print(f"{e['from']}: {e['subject']}")

9.2 SMTP 发送邮件

import smtplib from email.mime.text import MIMEText def send_via_smtp(sender, password, recipient, subject, body): """通过 SMTP 发送邮件""" msg = MIMEText(body, 'plain', 'utf-8') msg['Subject'] = subject msg['From'] = sender msg['To'] = recipient with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: server.login(sender, password) server.send_message(msg) print("邮件已发送") # 使用示例 # send_via_smtp('you@gmail.com', 'app_password', 'friend@example.com', '你好', '这是一封测试邮件')

安全注意事项

使用 IMAP/SMTP 方式时:

  • 不要使用主密码:请在 Google 账号中生成"应用专用密码"(App Password)
  • 开启两步验证:需要先在 Google 账号中开启两步验证才能生成应用专用密码
  • Gmail API 更安全:API 方式使用 OAuth 2.0,权限粒度更细,且可以随时撤销
  • 不要在代码中硬编码密码:使用环境变量或配置文件管理敏感信息

9.3 方案对比

特性 Gmail API (推荐) IMAP/SMTP
认证方式 OAuth 2.0(更安全) 密码/应用专用密码
功能覆盖 全面(标签、过滤器、历史等) 基础(收发、搜索、标记)
搜索能力 支持 Gmail 搜索语法 基础 IMAP 搜索
附件处理 完整的下载/上传 API 通过 MIME 解析
配额限制 每天 10 亿配额单位(充足) 连接数限制
设置复杂度 需要 Google Cloud 配置 仅需开启 IMAP/SMTP
适合场景 正式项目、复杂自动化 快速脚本、个人工具

选择建议

对于大多数场景,推荐使用 Gmail API 方式。虽然初始配置稍复杂(需要设置 Google Cloud 项目),但安全性更高、功能更全面、长期维护更方便。IMAP/SMTP 方式适合快速原型或简单的一次性脚本。无论选择哪种方式,Claude Code 都可以帮你生成完整的代码实现。

十、常见问题与故障排除

问题 原因 解决方案
认证时出现"未验证应用"警告 应用未通过 Google 验证 在 OAuth 同意屏幕中设置为"测试中"状态,添加测试用户
token.json 过期或失效 OAuth token 有效期有限(通常7天) 删除旧的 token.json 重新认证,或实现 refresh_token 自动刷新
API 返回 403 错误 权限不足或 API 未启用 检查 OAuth 范围(scopes)是否包含所需权限,确认 Gmail API 已启用
邮件发送失败(429 错误) 超出 API 配额限制 降低发送频率,实现指数退避重试策略
中文邮件乱码 编码设置不正确 在 MIMEText 中设置 charset='utf-8',Base64 编码使用 UTF-8
附件下载后无法打开 解码方式不正确 使用 urlsafe_b64decode 而非标准 base64.b64decode
搜索不到已存在的邮件 Gmail 搜索结果有延迟或分页限制 使用更精确的查询条件,检查是否在垃圾邮件或归档中
IMAP 连接被拒绝 IMAP 访问未开启或密码错误 在 Gmail 设置中开启 IMAP 访问,使用应用专用密码

配额与限制

Gmail API 配额详情

  • 每日配额:每个项目每天 1,000,000,000 配额单位
  • 读取操作:每封邮件约 5 单位(get)/ 1 单位(list)
  • 写入操作:每封邮件约 25-50 单位(send/modify)
  • 速率限制:每 100 秒最多 250 单位,超出会返回 429 错误
  • 推荐实践:在脚本中添加 time.sleep(0.1) 或使用指数退避策略

"Gmail API 的配额对于个人使用非常充足。即使每天收发 1000 封邮件,也仅消耗约 5 万个配额单位,远不及每日 10 亿的配额上限。真正的限制在于速率(每秒配额),所以批量操作时适当添加延迟即可。"

提示词示例:"我的 Gmail API 脚本返回了 403 错误,请帮我分析可能的原因并给出解决方案。我的 OAuth 范围是 gmail.readonly,但我尝试修改邮件标签。"

核心要点总结

  1. 理解协作模式:Claude Code 不直接操作 Gmail,但能编写完整的 Python 代码通过 Gmail API 完成所有邮箱操作。
  2. 优先使用 Gmail API:相比 IMAP/SMTP,API 方式更安全(OAuth 2.0)、功能更全面(标签、过滤器、历史记录),适合正式项目和自动化任务。
  3. 环境配置是关键:需要先完成 Google Cloud 项目配置、启用 Gmail API、创建 OAuth 凭据,这是所有操作的前提。
  4. 搜索语法是基础:掌握 Gmail 搜索语法(from:/to:/subject:/after:/before:/is:unread/has:attachment 等),可以精确筛选目标邮件。
  5. 自动化工作流提升效率:自动分类、批量下载附件、汇总报告等任务可以定时执行,将重复性工作自动化。
  6. 安全第一:妥善保管 credentials.json 和 token.json,IMAP/SMTP 方式务必使用应用专用密码,不要在代码中硬编码敏感信息。
  7. Claude Code 降低门槛:无需精通 Gmail API,用自然语言描述需求,Claude Code 可自动生成完整可运行的 Python 解决方案代码。
10684