Guide
Gmail API:列出垃圾邮件与回收站邮件
你的脚本列出了邮箱里的每一封邮件,但你要找的那封钓鱼样本就是不出现。这不是你代码的 bug。Gmail API 默认从 messages.list 结果中排除 SPAM 和 TRASH,除非你显式请求它们。本指南介绍读取垃圾邮件和回收站的三种官方方式:includeSpamTrash 参数、labelIds 过滤器和 in:spam 搜索查询,外加只需一个标志的 CLI 等价命令。
Written by Aaron de Mello Senior Engineering Manager
本指南用到的命令参考: nylas email list 和 nylas email folders list。
为什么 Gmail API 不返回垃圾邮件或回收站邮件?
Gmail API 默认从 users.messages.list 的响应中排除 SPAM 和 TRASH 这两个系统标签。includeSpamTrash 查询参数控制这一行为,默认值为 false。根据 messages.list 参考文档,设为 true 时它会 "include messages from SPAM and TRASH in the results"(在结果中包含来自 SPAM 和 TRASH 的邮件)。
这个默认值对收件箱类应用来说很合理,但它会破坏三种真实工作负载:滥用与钓鱼分析、全邮箱备份,以及误判邮件恢复脚本。每次 messages.list 调用消耗 5 个配额单位,默认返回 100 个邮件 ID(配合 maxResults 可达 500 个),所以解决办法只是改一个参数,而不是发更多请求。
如何用 includeSpamTrash 包含垃圾邮件和回收站?
在 messages.list 上设置 includeSpamTrash=true,垃圾邮件和回收站邮件会与其余所有邮件一起返回。它扩大结果集而不是过滤结果集,所以在需要完整扫一遍邮箱时使用它。配合 maxResults=500,一次请求能覆盖默认分页大小的 5 倍。
下面的 Python 示例使用 google-api-python-client,统计前 500 条结果中有多少带有 SPAM 或 TRASH 标签。注意每次后续的 messages.get 消耗 20 个配额单位,是 list 调用本身的 4 倍。
from googleapiclient.discovery import build
service = build("gmail", "v1", credentials=creds)
# Include spam and trash in a full-mailbox listing
results = service.users().messages().list(
userId="me",
includeSpamTrash=True,
maxResults=500,
).execute()
ids = [m["id"] for m in results.get("messages", [])]
print(f"{len(ids)} messages, spam and trash included")
# Check which labels a specific message carries
msg = service.users().messages().get(
userId="me", id=ids[0], format="minimal"
).execute()
print(msg["labelIds"]) # e.g. ['SPAM'] or ['TRASH']不带这个参数时,同样的调用会悄悄丢弃所有标记为 SPAM 或 TRASH 的邮件。没有任何警告,也不会告诉你排除了多少封——这正是漏掉此标志的备份脚本会少报邮箱大小、错过可恢复邮件的原因。
如何用 labelIds 只列出垃圾邮件?
向 messages.list 传入 labelIds=["SPAM"] 就只返回垃圾邮件,不需要 includeSpamTrash。 API 参考文档 说明该过滤器返回 "with labels that match all of the specified label IDs"(标签与所有指定标签 ID 匹配)的邮件,所以单个标签 ID 给你的正是那个文件夹。同样地,用 ["TRASH"] 读取已删除邮件。
第三个选项是 q 参数。同一份参考文档写道,它 "supports the same query format as the Gmail search box"(支持与 Gmail 搜索框相同的查询格式)。这使得 q="in:spam" 与 labelIds 过滤器等价,而且它能和 from:、after: 等其他运算符组合在一个字符串里。
# Spam only, via labelIds
spam = service.users().messages().list(
userId="me", labelIds=["SPAM"], maxResults=100
).execute()
# Trash only
trash = service.users().messages().list(
userId="me", labelIds=["TRASH"], maxResults=100
).execute()
# Search-style: spam from one sender in the last week
recent = service.users().messages().list(
userId="me", q="in:spam from:billing@suspicious.example newer_than:7d"
).execute()按意图选择:要干净地读取单个文件夹用 labelIds;需要把垃圾邮件范围与发件人、日期或附件条件组合时用 q。两种方式每次 list 调用都同样消耗 5 个配额单位。SPAM 和 TRASH 是 Gmail 13 个内置系统标签中的 2 个,完整列表见 Gmail 标签指南。
Gmail 会把回收站邮件保留多久?
Gmail 会把已删除的邮件在回收站中保留最多 30 天。根据 Google 的恢复文档,"Up to 30 days after deletion: You can find the message in Trash"(删除后 30 天内:你可以在回收站中找到邮件),而 30 天后 "The message is permanently deleted."(邮件被永久删除)。你针对 TRASH 标签构建的任何恢复脚本,都在和这个时钟赛跑。
这个窗口决定了自动化的调度方式。每周把回收站导出为 JSON 的 cron 任务,在 Gmail 清除一封邮件前有 4 次机会抓到它;每月一次的任务则可能完全错过。垃圾邮件分诊的实用模式也一样:按短于团队事件响应窗口的周期列出 SPAM 标签,并把可能用作证据的内容持久化保存。
如何从 CLI 读取垃圾邮件和回收站?
nylas email list --folder SPAM 命令以 JSON 形式返回 Gmail 垃圾邮件,无需 Google Cloud 项目、OAuth 同意屏幕或 Python 客户端配置。CLI 的 --folder 标志接受任何 Gmail 系统标签 ID,所以 TRASH 同样适用,而 --all-folders 一次扫遍所有文件夹。认证只需一条 nylas auth login。
# List spam messages
nylas email list --folder SPAM --limit 20
# List trash as JSON for scripting
nylas email list --folder TRASH --json --limit 50
# Sweep every folder, spam and trash included
nylas email list --all-folders --json --limit 200
# Extract sender addresses from spam for a blocklist review
nylas email list --folder SPAM --json --limit 50 | \
jq -r '.[].from[0].email' | sort | uniq -c | sort -rn以上命令已在 CLI 3.1.16 上针对真实 Gmail 账户验证。同样的 --folder 语法在 Outlook 和 IMAP 账户上配合各自的文件夹名也能工作,所以为 Gmail 编写的垃圾邮件审查脚本可以直接移植到其他提供商,完全不用碰 Gmail API 的标签模型。运行 nylas email folders list 即可查看任意已连接账户上确切的文件夹 ID。
后续步骤
- Gmail API 搜索查询 — 每个 q 运算符,包括 in:、label: 和日期过滤
- Gmail 标签 API — 系统标签与用户标签的区别,以及如何以编程方式应用它们
- Gmail API batchDelete — 每次请求永久删除最多 1,000 封邮件,附安全防护措施
- 把邮件备份为 JSON — 在 30 天回收站窗口关闭前导出邮件
- 完整命令参考 — 每个标志和子命令的完整文档