您需要一个使用域的电子邮件地址,该域具有您的系统管理员可以控制的 MX 服务器。这可能是您的主域的子域。那么你要做的是配置 MTA 软件(Exim、Postfix...希望不是 qMail!)以将该电子邮件通过管道传输到 Rails:
http://guides.rubyonrails.org/action_mailer_basics.html#receiving-emails
如果 MTA 未与 rails 应用程序本身安装在同一台服务器上,则您必须将电子邮件传送到一个小的临时转发器脚本,该脚本执行将电子邮件发布到您的应用程序的操作,然后您手动把它传给你的邮寄者。
在您的邮件程序中,您可以访问所有标题、正文、附件等。如果您在主题或回复地址中放置了一些唯一标识符,您可以决定实例化哪个邮件程序以将邮件转发到其预期的收件人。
我们还没有这样做,但出于同样的原因,我们将这样做。但是,如果您不熟悉配置 MTA,这可能有点过头了。您是否有系统管理员可以执行此任务?
在代码级别,我会这样做:
用户 A (id = 1234) 向用户 B (id = 5678) 发送电子邮件
从您拥有的任何您想要的地址发送电子邮件,但将其设置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}")
现在,当您通过为“usermessages.your-domain.com”域配置的 MX 收到回复时,您要做的第一件事就是通过解析To:
字段来识别发件人和收件人。您可以通过split
“找出”部分轻松识别发件人和收件人。然后,您可以生成校验和并确保它匹配,以确保没有人试图恶意发送邮件,就好像它来自另一个用户一样。
一旦你弄清楚了所涉及的用户,继续发送另一封电子邮件,其中一个特殊的Reply-To:
标题(很明显,ID 颠倒了,摘要使用不同的盐完成)。
这是一个非常基本但功能完善的示例。您可以将此摘要放在您想要的任何位置,前提是它会在回复返回时保留(这使得Reply-To:
标题非常适合。某些服务使用主题行代替。
我会避免使盐成为用户控制的东西,例如用户的密码哈希,因为如果用户更改该信息(更改他们的密码),校验和将不再有效。