# 是否有办法仅对收到的电子邮件进行 IMAP 轮询

**URL:** <https://meta.discourse.org/t/is-there-a-way-to-only-imap-polling-for-incoming-emails/381571>\
**Category:** Support\
**Tags:** email-in\
**Created:** [2025年九月4日 12:44 UTC](https://meta.discourse.org/t/is-there-a-way-to-only-imap-polling-for-incoming-emails/381571 "2025-09-04T12:44:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![MichaIng](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michaing/32/251089_2.png) [@MichaIng](https://meta.discourse.org/u/MichaIng)\
**Post date:** [2025年九月4日 12:44 UTC](https://meta.discourse.org/t/is-there-a-way-to-only-imap-polling-for-incoming-emails/381571/1 "2025-09-04T12:44:36Z")

</div>

我们现在运行自己的邮件服务器，它在发送邮件方面与 Discourse 配合良好。所以现在我正在研究接收邮件以回复帖子。

有一个 POP3 轮询，但我们的 Dovecot 禁用了 POP3，只使用 IMAP。有 IMAP 轮询间隔的设置，但没有启用 IMAP 轮询、定义主机、端口、凭据等的设置，就像 POP3 轮询一样。IMAP 轮询是否共享 POP3 轮询的设置，然后可以通过将 POP3 轮询的间隔设置为 0 分钟或类似值来有效地禁用它？

这个问题以前问过，但没有答案：[Is there a way to use IMAP instead of POP3 for replies by email?](https://meta.discourse.org/t/is-there-a-way-to-use-imap-instead-of-pop3-for-replies-by-email/279012?u=michaing)  
我无意运行第二个 Postfix 作为 Discourse 邮件接收器容器，而且由于主机上的 25 端口使用，它无论如何都不会起作用。

最好是直接使用我们拥有的 Postfix 通过 Discourse 邮件接收 API。它看起来并不复杂：[mail-receiver/lib/mail\_receiver/discourse\_mail\_receiver.rb at main · discourse/mail-receiver · GitHub](https://github.com/discourse/mail-receiver/blob/main/lib/mail_receiver/discourse_mail_receiver.rb)

- 使用系统用户、API 密钥和发件人电子邮件作为表单数据发送 POST 请求。
- 但初步看来，健全性检查更复杂：[mail-receiver/lib/mail\_receiver/fast\_rejection.rb at main · discourse/mail-receiver · GitHub](https://github.com/discourse/mail-receiver/blob/main/lib/mail_receiver/fast_rejection.rb)
- 我或许可以将其实现为 shell 脚本，以有条件地（接收者电子邮件）进行管道传输，但保持其最新和功能正常可能不切实际/不合理。

所以 IMAP 仅轮询将是我的首选解决方案，我希望这是可能的。

编辑：或者我们只是安装 Ruby 运行时并将邮件接收器和快速拒绝的 lib 和可执行文件复制到主机上，就像 Dockerfile 所做的那样，并从我们的 Postfix 通过 `transport_maps` 以相同的方式调用它：[mail-receiver/Dockerfile at main · discourse/mail-receiver · GitHub](https://github.com/discourse/mail-receiver/blob/main/Dockerfile#L49-L52)  
有人试过这个吗？

---

<div class="post-metadata">

**Author:** ![MichaIng](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michaing/32/251089_2.png) [@MichaIng](https://meta.discourse.org/u/MichaIng)\
**Post date:** [2025年九月6日 19:41 UTC](https://meta.discourse.org/t/is-there-a-way-to-only-imap-polling-for-incoming-emails/381571/2 "2025-09-06T19:41:08Z")

</div>

好的，另一位团队成员提到 IMAP 轮询从未正常工作过，在某种程度上已被移除，而这些设置似乎是当时旨在实现它时留下的一些残余。  
_编辑：找到了一些关于它的声明：[IMAP support for group inboxes - #39 by martin](https://meta.discourse.org/t/imap-support-for-group-inboxes/160588/39?u=michaing)  
这似乎是倒退，因为对我来说，POP3 在如今已过时且不切实际，因为人们通常会使用多个邮件客户端（至少是手机+电脑）。因此，我看不出在 Dovecot 实例中启用 POP3 监听器有什么意义。_

然而，我设法将直接的 Discourse 邮件接收器 API 实现到我们现有的 Postfix 中，而无需邮件接收器容器，甚至无需其 Ruby 脚本，但主要遵循 Discourse 邮件接收器容器中使用的 Postfix 集成：[mail-receiver/Dockerfile at main · discourse/mail-receiver · GitHub](https://github.com/discourse/mail-receiver/blob/main/Dockerfile)

`/etc/postfix/main.cf`：

```plaintext
# 对于 Discourse 回复电子邮件地址，我们通过传输映射覆盖默认传输
transport_maps=hash:/etc/postfix/transport

```

`/etc/postfix/transport`

```plaintext
# 一个名为“discourse”的服务用作电子邮件到定义的 Discourse 回复地址的传输端点
forum.reply@dietpi.com discourse:

```

`/etc/postfix/master.cf`

```plaintext
# 我们将“discourse”传输服务定义为通过监听（私有）UNIX 套接字的 curl 的管道守护进程
# 为了让管道到 curl 工作，它不能是未授权的或 chrooted 的
discourse unix - n n - - pipe user=nobody:nogroup argv=/usr/bin/curl -X POST -F email=<- -H Api-Username:system -H Api-Key:fooooobaaaaarbaaaaaaz https://dietpi.com/forum/admin/email/handle_mail

```

- 因此，传输映射会将电子邮件传递到回复地址，然后传递到我们自定义的 `discourse` 服务。
- 最佳性能应该是 UNIX 套接字，并且它可以是私有的（第一个 `-`），因为没有其他任何东西必须使用它。_“私有”意味着套接字位于 `/var/spool/postfix/private/discourse`，在一个只有 `postfix` 用户可以访问的目录中，位于 Postfix chroot 目录 `/var/spool/postfix` 内。_
- 但为了让 `pipe` 到 `curl` 工作（`n n`），它不能是未授权的或 chrooted 的。
- 然后我们使用 `nobody:nogroup` 用户：组来最小化权限。
- 遵循接收器 API，电子邮件需要附加到 `email` 表单字段，这可以通过 curl 的 `<-` STDIN 调用完成。需要添加 `Api-Username` 和 `Api-Key` 标头，第一个通常是 `system`，第二个可以在 Discourse 中生成，作为仅具有 `receive_emails` 权限的精细 API 密钥。然后使用相应的 HTTP 端点。

我们有意跳过了接收器容器执行的快速拒绝策略检查：

- 它检查 `From` 和 `To` 标头的存在，发件人是否是带有域的完整地址，以及它是否在黑名单中，黑名单可以通过 `BLACKLISTED_SENDER_DOMAINS` 容器变量选择性地定义。它将发件人和收件人地址发送到另一个 Discourse HTTP API 端点，该端点会检查收件人是否与配置的回复电子邮件地址模板匹配，以及发件人地址是否属于注册用户，_除非论坛配置为在传入电子邮件时创建新的停用用户，在我们案例中奇怪的是默认启用了此功能？_
- 我们公开的 Postfix SMTP 接收器服务已经检查了大部分这些内容，还有更多。所有内容都通过 `rspamd`，这意味着 DKIM、SPF 和 DMARC 检查。
- 但最重要的是，最终的 Discourse 邮件接收器后端也会执行相同的检查。唯一的缺点是：发件人不会收到邮件守护进程拒绝/退回的电子邮件，但如果发件人/收件人无效，错误将仅记录到我们的 Discourse 中。但如果发件人和收件人正确，只有邮件内容不符合预期（特别是缺少 Message-ID 标头），发件人会收到 Discourse 的正确电子邮件。IMO，缺少 SMTP 拒绝/退回邮件是完全可以接受的，因为否则实现开销最小，每个邮件的网络请求和后端处理少等。
- 一般来说：在 `master.cf` 命令参数中要小心空格。引用以保留空格字面量不起作用。相反，这样的参数需要用花括号括起来：`{some arg with spaces}`。但在这种情况下，没有参数包含空格，标头键和值之间的空格也是可选的。

到目前为止工作得很好，并且无缝集成到我们现有的设置中，默认的虚拟传输到 Dovecot，传输映射也用于将一些电子邮件中继到外部地址，因为并非团队中的每个人都希望/需要我们在服务器上拥有额外的邮箱。_如果在虚拟别名映射中定义了通配符地址，则需要将 Discourse 回复地址添加到该表中，将其映射到自身（与其他本地虚拟用户/地址一样）。_

---

<div class="post-metadata">

**Author:** ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)\
**Post date:** [2025年十月6日 19:41 UTC](https://meta.discourse.org/t/is-there-a-way-to-only-imap-polling-for-incoming-emails/381571/3 "2025-10-06T19:41:30Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
