agentic_huge_data_base / wiki
页面 Paperless-ngx · 5 邮件处理·DeepWiki 中文全文译文

5 · 邮件处理(Mail Processing)

文档归档与消费管道 · 聚焦本章的模块关系、源码依据与实现要点。

项目Paperless-ngx 章节5 状态全文译文 模块工作流与编排、认证、权限与安全、文档对象与元数据、界面与交互
源码线索
  • src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html
  • src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts
  • src-ui/src/app/data/mail-rule.ts
  • src/documents/tests/test_migration_workflows.py
  • src/paperless_mail/admin.py
  • src/paperless_mail/mail.py
  • src/paperless_mail/models.py
  • src/paperless_mail/oauth.py
  • src/paperless_mail/serialisers.py
  • src/paperless_mail/tasks.py
模块标签
  • 工作流与编排
  • 认证、权限与安全
  • 文档对象与元数据
  • 界面与交互
  • 系统架构

章节正文

邮件处理

邮件处理

相关源文件

本章引用的主要源码文件:

  • .mypy-baseline.txt
  • .pyrefly-baseline.json
  • docker/compose/test-nginx.conf
  • src-ui/src/app/components/admin/trash/trash.component.scss
  • src-ui/src/app/components/admin/trash/trash.component.spec.ts
  • src-ui/src/app/components/admin/trash/trash.component.ts
  • src-ui/src/app/components/admin/users-groups/users-groups.component.html
  • src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html
  • src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts
  • src-ui/src/app/components/manage/mail/mail.component.html
  • src-ui/src/app/components/manage/mail/mail.component.scss
  • src-ui/src/app/components/manage/mail/mail.component.spec.ts
  • src-ui/src/app/components/manage/mail/mail.component.ts
  • src-ui/src/app/components/manage/workflows/workflows.component.html
  • src-ui/src/app/components/manage/workflows/workflows.component.scss
  • src-ui/src/app/components/manage/workflows/workflows.component.spec.ts
  • src-ui/src/app/components/manage/workflows/workflows.component.ts
  • src-ui/src/app/data/mail-rule.ts
  • src-ui/src/app/services/rest/mail-rule.service.spec.ts
  • src/documents/loggers.py
  • src/documents/tests/test_api_trash.py
  • src/paperless_mail/admin.py
  • src/paperless_mail/mail.py
  • src/paperless_mail/models.py
  • src/paperless_mail/oauth.py
  • src/paperless_mail/serialisers.py
  • src/paperless_mail/tasks.py
  • src/paperless_mail/tests/conftest.py
  • src/paperless_mail/tests/factories.py
  • src/paperless_mail/tests/test_api.py
  • src/paperless_mail/tests/test_live_mail.py
  • src/paperless_mail/tests/test_mail.py
  • src/paperless_mail/tests/test_mail_oauth.py
  • src/paperless_mail/tests/test_preprocessor.py
  • src/paperless_mail/views.py

目的与范围

Paperless-ngx 中的邮件处理系统支持从电子邮件账户自动获取文档。它提供了一个灵活的框架,用于定义规则,以确定应处理哪些邮件和附件、如何对文档进行分类,以及在提取文档后对邮件执行哪些操作(例如,标记为已读、删除或移动到文件夹)。

本页面记录了邮件处理的架构、组件和行为。有关处理提取文档的文档消费管线的信息,请参阅文档处理管线

系统架构

邮件处理系统由多个相互连接的组件组成,这些组件协同工作,以获取、过滤和处理邮件,从而提取文档。

标题:邮件处理系统流程

Paperless-ngx · 系统架构 · 图 1
Paperless-ngx · 系统架构 · 图 1

来源:src/paperless_mail/mail.py:515-523src/paperless_mail/mail.py:79-210src/paperless_mail/tasks.py:13-33

该系统主要由 process_mail_accounts Celery 任务驱动 src/paperless_mail/tasks.py:14-14,该任务调用 MailAccountHandler src/paperless_mail/mail.py:515-515 来处理一个或多个邮件账户。对于每个账户,处理器会处理所有已启用的规则,根据规则条件过滤邮件,并根据规则规范提取文档。文档提取后,会对邮件执行指定的邮件操作(删除、标记为已读等)。

邮件账户

邮件账户表示与邮件服务器的连接,文档将从这些服务器获取。每个账户存储访问邮件服务器所需的连接详细信息。

标题:MailAccount 数据结构

Paperless-ngx · 邮件账户 · 图 2
Paperless-ngx · 邮件账户 · 图 2

来源:src/paperless_mail/models.py:8-85

账户类型

Paperless-ngx 支持以下邮件账户类型 src/paperless_mail/models.py:18-21

  1. IMAP - 使用用户名/密码认证的标准 IMAP 服务器。
  2. Gmail OAuth - 使用 OAuth2 认证的 Gmail 账户。
  3. Outlook OAuth - 使用 OAuth2 认证的 Microsoft Outlook/Office365 账户。
安全选项

对于 IMAP 账户,可以使用以下安全选项 src/paperless_mail/models.py:13-16

  1. 无加密 - 未加密的连接(不推荐)。
  2. SSL - 使用 SSL 加密的安全连接。
  3. STARTTLS - 连接以未加密方式开始,然后升级为 TLS。

邮件规则

邮件规则定义了要处理哪些邮件以及如何处理它们。每条规则属于一个特定的邮件账户,并包含匹配邮件的条件、文档提取的规范以及处理完成后要执行的操作。

标题:MailRule 数据结构

Paperless-ngx · 邮件规则 · 图 3
Paperless-ngx · 邮件规则 · 图 3

来源:src/paperless_mail/models.py:87-305src-ui/src/app/data/mail-rule.ts:1-87

邮件过滤

邮件规则支持多种过滤邮件的条件:

  • 文件夹 - 要检查邮件的 IMAP 文件夹 src/paperless_mail/models.py:156-164
  • 发件人过滤 - 匹配发件人电子邮件地址 src/paperless_mail/models.py:166-171
  • 收件人过滤 - 匹配收件人电子邮件地址 src/paperless_mail/models.py:173-178
  • 主题过滤 - 匹配邮件主题中的文本 src/paperless_mail/models.py:180-185
  • 正文过滤 - 匹配邮件正文中的文本 src/paperless_mail/models.py:187-192
  • 最大天数 - 仅处理指定天数内的新邮件 src/paperless_mail/models.py:218-222
附件过滤

规则还可以过滤要处理的附件:

  • 附件文件名包含过滤 - 仅处理与指定模式匹配的文件(例如,*.pdf*invoice*src/paperless_mail/models.py:194-204
  • 附件文件名排除过滤 - 排除与指定模式匹配的文件 src/paperless_mail/models.py:206-216
  • 附件类型 - 仅处理常规附件,或同时处理内联附件 src/paperless_mail/models.py:114-116
消费选项

邮件规则通过 ConsumptionScope 支持从邮件中提取文档的不同方式 src/paperless_mail/models.py:103-112

  1. 仅附件 - 仅将附件作为文档处理。
  2. 仅 EML - 将整个邮件作为文档处理(.eml 文件)。
  3. 全部 - 将邮件作为文档处理,同时将附件作为单独的文档处理。
文档元数据分配

规则可以自动为处理的文档分配元数据 src/paperless_mail/models.py:252-300

  • 标题 - 来自邮件主题、附件文件名或不设置。
  • 标签 - 为文档分配特定标签。
  • 文档类型 - 分配特定的文档类型。
  • 通信方 - 来自电子邮件地址、发件人名称或自定义通信方。
  • 所有者 - 可选地通过 assign_owner_from_rule 将规则所有者设置为文档所有者。
邮件操作

处理完邮件后,Paperless-ngx 可以执行以下操作之一 src/paperless_mail/models.py:125-131

  1. 删除 - 从服务器删除邮件。
  2. 移动 - 将邮件移动到指定的文件夹。
  3. 标记为已读 - 将邮件标记为已读。
  4. 标记 - 标记/星标邮件。
  5. 标签 - 使用指定的标签标记邮件(适用于 Gmail 标签和 Apple Mail 标签)。

处理管线

邮件处理管线遵循以下步骤来获取和处理邮件:

标题:邮件处理管线逻辑

Paperless-ngx · 处理管线 · 图 4
Paperless-ngx · 处理管线 · 图 4

来源:src/paperless_mail/mail.py:525-893src/paperless_mail/tasks.py:13-33

管线中的关键组件
1. 邮件账户处理

MailAccountHandler.handle_mail_account src/paperless_mail/mail.py:525-525 方法是处理邮件账户的入口点。它连接到邮件服务器,在需要时刷新 OAuth 令牌 src/paperless_mail/mail.py:539-548,并处理该账户的每条已启用规则。

2. 邮件规则处理

对于每条规则,_handle_mail_rule src/paperless_mail/mail.py:593-593 方法会:

  • 选择合适的文件夹 src/paperless_mail/mail.py:611-618
  • 根据规则过滤条件和邮件操作构建搜索条件 src/paperless_mail/mail.py:623-637
  • 使用 imap_tools 获取匹配的邮件 src/paperless_mail/mail.py:643-643
  • 处理每封之前未处理过的邮件 src/paperless_mail/mail.py:651-659
3. 消息处理

_handle_message src/paperless_mail/mail.py:674-674 方法根据规则的消费范围从邮件中提取文档:

  • 对于附件,它会根据文件模式和内容类型进行过滤 src/paperless_mail/mail.py:760-785
  • 对于仅邮件处理,它会使用 MailMessagePreprocessor 创建一个 .eml 文件 src/paperless_mail/mail.py:821-826
4. 文档消费和 Celery Chord

queue_consumption_tasks src/paperless_mail/mail.py:864-864 函数使用 Celery chord 模式 src/paperless_mail/mail.py:15-15。它为提取的每个文档排队多个 consume_file 任务。一旦单封邮件的所有消费任务完成,就会执行回调任务 apply_mail_action src/paperless_mail/mail.py:304-304,以在服务器上执行邮件操作。

5. 邮件操作

apply_mail_action src/paperless_mail/mail.py:304-304 任务仅在文档成功排队等待消费后,才对邮件执行指定的操作(删除、标记为已读等)。

邮件操作的实现

邮件操作被实现为 BaseMailAction src/paperless_mail/mail.py:79-79 的子类,每个子类负责一个特定的操作:

标题:邮件操作类层次结构

Paperless-ngx · 邮件操作的实现 · 图 5
Paperless-ngx · 邮件操作的实现 · 图 5

来源:src/paperless_mail/mail.py:79-210

每个邮件操作类实现了两个关键方法:

  1. get_criteria() - 返回过滤条件,以避免处理已执行过该操作的邮件(例如,MarkReadMailAction{'seen': False}src/paperless_mail/mail.py:122-123
  2. post_consume() - 在文档消费后对邮件执行实际的操作(例如,M.flag(...)src/paperless_mail/mail.py:125-126

TagMailAction 对 Gmail 标签有特殊处理,通过 +X-GM-LABELS src/paperless_mail/mail.py:184-185 实现,对 Apple Mail 标签则使用 $MailFlagBit 关键字 src/paperless_mail/mail.py:64-72

OAuth 集成

Paperless-ngx 通过 PaperlessMailOAuth2Manager src/paperless_mail/oauth.py:16-16 支持 Gmail 和 Outlook 账户的 OAuth2 认证。

标题:OAuth 令牌管理

Paperless-ngx · OAuth 集成 · 图 6
Paperless-ngx · OAuth 集成 · 图 6

来源:src/paperless_mail/oauth.py:16-118src/paperless_mail/views.py:127-148src/paperless_mail/mail.py:539-550

令牌刷新机制

OAuth 访问令牌会定期过期。Paperless 在 MailAccountHandler src/paperless_mail/mail.py:539-550 中处理此问题:

  1. 检查账户的 is_token 是否为 true,以及 expiration 是否已过 src/paperless_mail/mail.py:540-542
  2. 使用 PaperlessMailOAuth2Manager().refresh_account_oauth_token(account) 获取新的访问令牌 src/paperless_mail/mail.py:544-544
  3. 使用新的 password(访问令牌)和 expiration 更新 MailAccount 记录 src/paperless_mail/oauth.py:110-116

管理 API 和 UI

该系统通过 MailAccountViewSet src/paperless_mail/views.py:71-71MailRuleViewSet src/paperless_mail/views.py:215-215 进行管理。

API 操作
  • 测试连接MailAccountViewSet 上的 test 操作 src/paperless_mail/views.py:86-86 允许在不保存账户的情况下验证凭据。
  • 手动处理process 操作 src/paperless_mail/views.py:157-157 会立即为特定账户触发 process_mail_accounts Celery 任务。
网页界面

MailRuleEditDialogComponent src-ui/src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts:156-156 提供了配置规则的前端界面。它使用 MailRuleSerializer src/paperless_mail/serialisers.py:77-77 与后端通信。

跟踪已处理的邮件

Paperless-ngx 在 ProcessedMail 模型 src/paperless_mail/models.py:308-308 中跟踪已处理的邮件,以确保去重。

标题:ProcessedMail 实体

Paperless-ngx · 跟踪已处理的邮件 · 图 7
Paperless-ngx · 跟踪已处理的邮件 · 图 7

来源:src/paperless_mail/models.py:308-367src/paperless_mail/mail.py:651-659

在处理消息之前,处理器会检查是否存在给定 rulefolderuidProcessedMail 记录 src/paperless_mail/mail.py:651-653。如果记录存在且状态不是 FAILED,则跳过该邮件。记录的状态包括 SUCCESS src/paperless_mail/models.py:313-313FAILED src/paperless_mail/models.py:314-314PROCESSED_WO_CONSUMPTION src/paperless_mail/models.py:315-315

定时处理

process_mail_accounts src/paperless_mail/tasks.py:14-14 任务被设计为定期运行。它会遍历所有账户 src/paperless_mail/tasks.py:21-21,检查它们是否有已启用的规则 src/paperless_mail/tasks.py:22-24,并使用 MailAccountHandler().handle_mail_account(account) src/paperless_mail/tasks.py:26-26 进行处理。

来源:src/paperless_mail/tasks.py:13-33