Existe uma maneira de apenas sondar o IMAP para e-mails recebidos

We are running now our own email server, and it works well for outgoing emails with Discourse. So now I am looking into receiving emails to reply to posts.

There is this POP3 polling, but our Dovecot has POP3 disabled, using IMAP only. There are settings for IMAP polling intervals, but none to enable IMAP polling, defining host, port, credentials etc, like for POP3 polling. Does IMAP polling just share the settings for POP3 polling, and is it then possible to effectively disable POP3 polling by setting its interval to 0 minutes or something like that?

The question has been asked before, but no answer: Is there a way to use IMAP instead of POP3 for replies by email?
I do not intend to run a second Postfix as Discourse mail-receiver container, and it wouldn’t work anyway as of port 25 use on the host.

Best would be, of course, to use the Discourse email-in API directly with the Postfix we have. It does not even look that complex: mail-receiver/lib/mail_receiver/discourse_mail_receiver.rb at main · discourse/mail-receiver · GitHub

So IMAP-only polling would be my preferred solution, I hope this is possble.

EDIT: Or we just install Ruby runtime and copy lib and executables of the mail receiver and fast reject in place on the host, like the Dockerfile does, and invoke it from our Postfix via transport_maps the same way: mail-receiver/Dockerfile at main · discourse/mail-receiver · GitHub
Has anyone tried this?

Okay, another team member mentioned that IMAP polling never worked properly, was somewhat removed, and these few settings seem to be some remaining cruft from when it was aimed to be implemented.

However, I managed to implement direct Discourse mail receiver API into our existing Postfix without the mail receiver container and even without its Ruby scripts, but following mostly the Postfix integration used in the Discourse mail receiver container: mail-receiver/Dockerfile at main · discourse/mail-receiver · GitHub

/etc/postfix/main.cf:

# For the Discourse reply email address, we override the default transport via transport mapping
transport_maps=hash:/etc/postfix/transport

/etc/postfix/transport

# A service named "discourse" is used as transport endpoint for emails to the defined Discourse reply address
forum.reply@dietpi.com discourse:

/etc/postfix/master.cf

# We define the "discourse" transport service as pipe daemon into curl listening on a (private) UNIX socket
# It cannot be unprivileged or chrooted for pipe into curl to work
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
  • So the transport mapping passes emails to the reply address to our custom discourse service.
  • Best performance should be a UNIX socket, and it can be private (first -), since nothing else must use it anyway. “private” means that the socket is located at /var/spool/postfix/private/discourse, in a directory where only the postfix user has access to, within the Postfix chroot dir /var/spool/postfix.
  • But it cannot be unprivileged or chrooted for pipe into curl to work (n n).
  • We then minimize permissions using nobody:nogroup user:group.
  • Following the receiver API, the email needs to be attached to an email form field, which can be done via curl’s <- STDIN call. Api-Username and Api-Key headers need to be added, the first being usually system, the 2nd can be generated in Discourse, as granular API key with receive_emails permissions only. Then using the respective HTTP endpoint.

We intentionally skip the fast rejection policy checks done by the receiver container:

  • It checks for the existence of From and To headers, whether sender is a full address with domain, and whether it is on a blacklist which can be optionally defined via BLACKLISTED_SENDER_DOMAINS container variable. And it sends sender and receiver addresses to another Discourse HTTP API endpoint which checks whether the receiver matches the configured reply email address template, and whether the sender address belongs to a registered user, unless the forum is configured to create new stale users on incoming emails, which weirdly was enabled by default in our case?
  • Most of this, and more, is checked by our public Postfix SMTP receiver service anyway, and everything goes through rspamd which implies DKIM, SPF, and DMARC checks.
  • But most importantly, the same checks are performed by the final Discourse email receiver backend anyway. Only somewhat downside: senders do not get a mailer daemon rejection/bounce email back, but errors in case of invalid sender/receiver are instead/only logged to our Discourse. But if sender and receiver were correct, only mail content is not as expected (especially Message-ID header missing), senders get a proper email from Discourse. The missing SMTP rejection/bounce mails are totally fine IMO, given that otherwise the implementation is with minimal overhead, has one network request and backend processing less per mail etc.
  • Generally: be careful with spaces in master.cf command arguments. Quotation to keep spaces literal does not work. Instead such an argument would need to be wrapped into curly braces: {some arg with spaces}. But in this case, no argument contains spaces, those between header key and value are also optional.

Works great so far, and integrates seamlessly into our existing setup with default virtual transport to Dovecot, and transport mapping also used to relay some emails to external addresses, as not everyone from the team wants/requires an additional mailbox at our server. If a catch-all address is defined in virtual alias mapping, the Discourse reply address needs to be added to that table, mapping to itself (like other local virtual users/addresses).