8

我正在尝试做 craigslist 的匿名电子邮件所做的事情,但使用 Rails,也很便宜。能够在电子邮件中添加标题对我来说很重要,这就是基本电子邮件转发不起作用的原因。

我想到的一种方法是使用 SMTP 服务器,每当我通过 POP/IMAP 阅读电子邮件时,我都会向电子邮件的真正收件人发送一封电子邮件,其中包含正确的 FROM 地址并添加标题。这可行,但 SMTP 服务器相对昂贵。

另一种方法是转发/重定向电子邮件,但在两者之间添加标题。我找不到任何服务或宝石来做到这一点。

请不要只说“电子邮件管道”,因为这实际上意味着将电子邮件提供给您的 Rails 程序,收到电子邮件后您会做什么?您实际上如何转发它。

有任何想法吗?

4

2 回答 2

13

您需要一个使用域的电子邮件地址,该域具有您的系统管理员可以控制的 MX 服务器。这可能是您的主域的子域。那么你要做的是配置 MTA 软件(Exim、Postfix...希望不是 qMail!)以将该电子邮件通过管道传输到 Rails:

http://guides.rubyonrails.org/action_mailer_basics.html#receiving-emails

如果 MTA 未与 rails 应用程序本身安装在同一台服务器上,则您必须将电子邮件传送到一个小的临时转发器脚本,该脚本执行将电子邮件发布到您的应用程序的操作,然后您手动把它传给你的邮寄者。

在您的邮件程序中,您可以访问所有标题、正文、附件等。如果您在主题或回复地址中放置了一些唯一标识符,您可以决定实例化哪个邮件程序以将邮件转发到其预期的收件人。

我们还没有这样做,但出于同样的原因,我们将这样做。但是,如果您不熟悉配置 MTA,这可能有点过头了。您是否有系统管理员可以执行此任务?

在代码级别,我会这样做:

  1. 用户 A (id = 1234) 向用户 B (id = 5678) 发送电子邮件

  2. 从您拥有的任何您想要的地址发送电子邮件,但将其设置Reply-To:为类似Reply-To: <mail-1234-5678-abcdefabcd1234567890abcdefabcdef@usermessages.your-domain.com>

    这绝对是这项工作的关键。它包括发件人的 ID、收件人的 ID 和防止伪造的校验和。校验和可以从每个用户唯一的盐生成,并且很简单:

    checksum = Digest::MD5.hexdigest("#{sender.id}-#{recipient.id}-#{sender.mailer_salt}")

  3. 现在,当您通过为“usermessages.your-domain.com”域配置的 MX 收到回复时,您要做的第一件事就是通过解析To:字段来识别发件人和收件人。您可以通过split“找出”部分轻松识别发件人和收件人。然后,您可以生成校验和并确保它匹配,以确保没有人试图恶意发送邮件,就好像它来自另一个用户一样。

  4. 一旦你弄清楚了所涉及的用户,继续发送另一封电子邮件,其中一个特殊的Reply-To:标题(很明显,ID 颠倒了,摘要使用不同的盐完成)。

这是一个非常基本但功能完善的示例。您可以将此摘要放在您想要的任何位置,前提是它会在回复返回时保留(这使得Reply-To:标题非常适合。某些服务使用主题行代替。

我会避免使盐成为用户控制的东西,例如用户的密码哈希,因为如果用户更改该信息(更改他们的密码),校验和将不再有效。

于 2011-05-21T02:40:23.463 回答
4

如果您的应用程序要扩展,尤其是跨多个服务器,那么我不会推荐默认的 Rails 接收电子邮件的方式。看看我在这里写的关于一些选项的博客文章。

基本前提是您希望在一个包罗万象的域上接收邮件。您可以使用 imap/pop3 从 gmail 之类的服务器转发/收集,也可以使用 CloudMailin 之类的服务来负责将消息传递到您的应用程序。您可以给每个用户一个唯一的地址,甚至只使用消息的一次性部分,例如 normal+disposable@domain.com。

然后,这只是使用邮件 gem来检查邮件并添加您需要的任何标题并再次发送邮件的情况。同样,您可以使用自己的电子邮件服务器进行此交付,或者如果您想提高您的交付能力,则可以依赖亚马逊的简单电子邮件服务之类的服务。

于 2011-05-21T08:22:19.810 回答