9

我有一个回复用户的机器人。但有时当我的机器人发送回复时,用户或他们的电子邮件提供商会自动回复(假期消息、退回消息、来自 mailer-daemon 的错误等)。然后是来自用户的新消息(所以我的机器人认为)它又会回复。邮件循环!

我希望我的机器人只回复来自真实人类的真实电子邮件。我目前正在过滤掉承认为批量优先或来自邮件列表或自动提交的标头等于“自动回复”或“自动生成”的电子邮件(请参阅下面的代码)。但我想有一种更全面或更标准的方法来处理这个问题。(我很高兴看到 Perl 之外的其他语言的解决方案。)

注意:记得让你自己的机器人声明它是自动回复的!包括

Auto-Submitted: auto-reply

在您的机器人电子邮件的标题中。

下面是我避免邮件循环的原始代码。仅当 realmail 返回 true 时才回复。

sub realmail {
  my($email) = @_;
  $email =~ /\nSubject\:\s*([^\n]*)\n/s;
  my $subject = $1;
  $email  =~ /\nPrecedence\:\s*([^\n]*)\n/s;
  my $precedence = $1;
  $email  =~ /\nAuto-Submitted\:\s*([^\n]*)\n/s;
  my $autosub = $1;

  return !($precedence =~ /bulk|list|junk/i ||
           $autosub =~ /(auto\-replied|auto\-generated)/i ||
           $subject =~ /^undelivered mail returned to sender$/i
          );
}

(主题检查肯定是不必要的;我只是在出现问题时一次添加这些检查,而上面的方法现在似乎有效,所以我不想碰它,除非有明确的更好的东西。)

4

4 回答 4

8

RFC 3834 为您应该做什么提供了一些指导,但这里有一些具体的指导:

将您的信封发件人设置为与自动回复不同的电子邮件地址,这样退回邮件就不会反馈到系统中。

我总是将电子邮件响应从特定地址发送到另一个地址的密钥存储在数据库中。在任何情况下,我都不会在 10 分钟内多次回复同一个地址。仅此一项就停止了所有循环,但并不能确保良好的行为(对邮件列表的自动回复很烦人)。

确保添加其他人匹配的标题的任何排列以停止循环。这是我使用的列表:


X-Loop: autoresponder
Auto-Submitted: auto-replied
Precedence: bulk (autoreply)

以下是一些我用来避免循环并尝试玩得很好的标头正则表达式:


 /^precedence:\s+(?:bulk|list|junk)/i
 /^X-(?:Loop|Mailing-List|BeenThere|Mailman)/i
 /^List-/i
 /^Auto-Submitted:/i
 /^Resent-/i

如果其中任何一个是信封发件人,我也会避免回复:


if ($sender eq ""
    || $sender =~ /^(?:request|owner|admin|bounce|bounces)-|-(?:request|owner|admin|bounce|bounces)\@|^(?:mailer-daemon|postmaster|daemon|majordomo|ma
ilman|bounce)\@|(?:listserv|listsrv)/i) {
于 2009-11-30T00:26:54.977 回答
2

这听起来确实像是CPAN的一个模块,但我在五分钟的搜索中没有找到任何明显相关的东西。 Mail::Lite::Mbox::Processor看起来可能会做你想做的事:

Mail::Lite::Message::Matcher 是一个用于自动邮件处理的框架。例如,您有一个邮件服务器,并且您需要自动处理某些类型的传入邮件消息。例如,您可以从邮件流中提取自动通知、发票、警报等,并根据这些邮件的内容执行一些任务。

但是它的文档非常稀疏,以至于它本身是否提供这些示例函数或者您是否必须提供驱动它们的代码并不是很明显。

但是,无论如何,如果您还没有检查过 CPAN,如果我想做这样的事情,我会从那里开始。

于 2009-11-29T11:06:54.100 回答
1

我在这里的回答只处理更直接的反弹。

使用DSN(交付状态通知)标识符将帮助您检测 DSN/退回邮件。它应该去返回路径而不是回复。

下面是典型DSN 消息的示例。标头信息包括消息 id、内容类型具有特定值(交付状态)等。

无法为您提供 perl 中的任何代码,只是我的 2 美分想法。

PS:请注意,并非所有邮件服务器或MTA都符合这一点,但我想大多数都符合。

于 2009-11-29T03:28:03.473 回答
1

应该有一个标准的方法来处理这个问题,但问题是你必须假设发送自动回复的系统符合该标准,而大多数时候,他们只是不这样做。

你如何得到你回复的地址?我希望你没有使用From:标题。首先检查Reply-to:标题,如果不存在,请使用Return-path:.

但无论您做什么,您都只需要记录您发送给谁的内容,并将您的机器人限制为每次合理的消息值。

于 2009-11-29T12:38:05.130 回答