通过AWS SES发送邮件后,如何理解“投递”和“退回”SNS通知?

9
我遇到了一些非常尴尬的情况,也许我误解了这些通知的使用方法。
我已经设置了AWS SES在发送邮件后发布到一个主题。我已经将其设置为Bounce、Complaint和Delivery。
我的做法是,当我在Web服务器上收到SNS通知时,我会在我的数据库中查找那个消息ID,然后更改它的状态。例如,如果送达通知到达,我会将消息状态更改为“已送达”。如果反弹通知到达,我会将消息状态更改为“反弹”。
但现在我注意到,许多这些电子邮件都向我发送了两个通知,而且它们并不总是按照特定的顺序。有时一个先来,有时则相反。
所以如果“反弹”先到达,然后是“已送达”,那么我在数据库中针对此消息的状态就变成了“已送达”,我认为这可能会产生误导。
第一个问题:我如何检查这些通知的顺序?
第二个问题:我觉得我误解了“Delivery”通知。我试着阅读AWS文档,但老实说,它们并不是最好的文档。有人能给我一个简单、清晰的解释吗?
第三个问题:我是否正确地处理了这些通知?还是有更好的方法?
感谢您的帮助。
谢谢!
--
供您参考,我附上了一个示例,其中包含一组2个通知。一个反弹,一个送达。
{
    "Type": "Notification",
    "MessageId": "2efb9ee6-6bd5-576d-b80d-d0f5e3f44f23",
    "TopicArn": "arn:aws:sns:us-east-1:#####:ses_beamstyle_com_hk",
    "Message": {
        "notificationType": "Delivery",
        "mail": {
            "timestamp": "2015-07-05T19:30:40.441Z",
            "source": "<no-reply@bs.com.hk>",
            "messageId": "xxxxx
            "destination": [
                "<ooto@simulator.amazonses.com>"
            ]
        },
        "delivery": {
            "timestamp": "2015-07-05T19:30:41.101Z",
            "processingTimeMillis": 660,
            "recipients": [
                "ooto@simulator.amazonses.com"
            ],
            "smtpResponse": "250 2.6.0 Message received",
            "reportingMTA": "a9-140.smtp-out.amazonses.com"
        }
    },
    "Timestamp": "2015-07-05T19:30:41.179Z",
    "SignatureVersion": "1",
    "Signature": "xxxxx",
    "SigningCertURL": "xxxxx",
    "UnsubscribeURL": "xxxxx"
}





{
    "Type": "Notification",
    "MessageId": "b6e8bb7d-4e73-52ae-b690-f56ec6527ce5",
    "TopicArn": "arn:aws:sns:us-east-1:#####:ses_beamstyle_com_hk",
    "Message": {
        "notificationType": "Bounce",
        "bounce": {
            "bounceSubType": "General",
            "bounceType": "Transient",
            "bouncedRecipients": [
                {
                    "emailAddress": "ooto@simulator.amazonses.com"
                }
            ],
            "timestamp": "2015-07-05T19:30:41.000Z",
            "feedbackId": "xxxxx"
        },
        "mail": {
            "timestamp": "2015-07-05T19:30:40.000Z",
            "messageId": "xxxxx",
            "destination": [
                "<ooto@simulator.amazonses.com>"
            ],
            "source": "<no-reply@bs.com.hk>"
        }
    },
    "Timestamp": "2015-07-05T19:30:41.315Z",
    "SignatureVersion": "1",
    "Signature": "xxxxx",
    "SigningCertURL": "xxxxx",
    "UnsubscribeURL": "xxxxx"
}
1个回答

17
SMTP投递的特性使得SES在所有出站投递中都使用SMTP(无论您使用SMTP还是API),因此有时会在同一封邮件中产生退回和投递。打个比方,假如我请你代表我给一家公司打电话,并为Jane Smith留言,但未告诉你该公司没有这个人。可能发生以下两种情况:1. 在通话结束前,你会被告知:“对不起,这里没有这个人。”2. 你将留下一条消息并结束通话,因为接听留言的人认为这里有这样一个人,或者是之前的员工姓名,接听者不知道已经离职了。在第一种情况下,如果我问“你给Jane留了言吗?”你会说“没有”。但在第二种情况下,你会说“是的”。
但是,在第二种情况中,当您结束通话后,公司中的某个人会意识到该消息是发给一个未知的人。如果他们很有礼貌,他们可能会打电话回来告诉您:“我们无法发送您的消息,因为这里没有这个名字的人。”
现在,您给我打电话并说:“我无法发送那条消息。”“等等,什么?你告诉我你已经发送了。”
但是,即使您说发送了,实际上没有发送该消息的原因是非常清楚的。
电子邮件也存在同样的问题。可以说,对于一个不可交付的消息,传入邮件服务器的正确行为是立即拒绝它。
很不幸,许多电子邮件提供商在SMTP事务开始时不验证电子邮件地址。相反,他们接受应该的域的所有邮件,并将可交付性检查推迟到以后,因此他们无法主动拒绝传入的消息......这是SES避免发送“误报”交付通知所必需的。通过推迟检查,需要收件系统实际生成一封回复发件人的电子邮件(由于它们格式化消息的方式,SES成为发件人)。在没有真正的退信的情况下,SES首先认为邮件已被投递,然后认为邮件已退回。
在大多数情况下,从SES返回退信通知的电子邮件确实已经退回了......无论您收到任何交付通知。通常,交付应该首先进行,但可能会出现顺序错误-虽然这应该是例外情况。
对于ISP退信,Amazon SES仅报告硬退信和不再由Amazon SES重试的软退信。在这些情况下,您的收件人未收到您的电子邮件,Amazon SES将不会尝试重新发送。 http://docs.aws.amazon.com/ses/latest/DeveloperGuide/notifications.html 这很简单明了...但是,当然还有一个令人烦恼的例外:
您通过与退信相同的方法收到离开办公室(OOTO)消息的通知,尽管它们不计入您的退信统计。
在电线上,离开办公室的回复看起来非常像退信。据推测,当SES无法确定更好的退信类型报告方式时,根据目的地已经--显然--接受您的消息后返回的退信消息的构造,使用您在示例中看到的内容。
        "bounceSubType": "General",
        "bounceType": "Transient",

请参见http://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html#bounce-types,了解可能的组合。
最好的方法可能是存储所有响应,以防此方法证明不够准确,并将瞬态/通用退信通知视为“离开办公室”警报。
其他瞬态子类型可能被解释为将来可以成功发送的收件人,而永久子类型是应避免发送的地址,因为该地址被认为是永久无法传递的。
除了离开办公室之外,退信应该(在收件人方面没有错误配置的情况下)对您来说是此特定消息未通过的一个相当可靠的指标。

当服务器因为发件人在黑名单上而拒绝邮件(这在SES中经常发生)时,您也会收到一个“一般短暂性弹回报告”。看起来您无法区分OOTO和由黑名单引起的拒绝。 - new name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接