AWSSESのSMTPを利用するとmessageIDが書き換わる

AWSSESのSMTPを利用してメール送信をすると、messageIDが上書きされてしまう。

そのため、以下のようなシステムは破綻することになる。

  • message_header_id を生成する
  • 生成した message_header_id をDBに保存
  • 返信メールの in_reply_to と突き合わせてどのメールに対する返信か紐づける

messageIDが上書きされてしまうのは避けられないとして、送信前のmessageIDと送信後のmessageIDさえ何かしらの方法で紐づけることができれば、一応、何とかはなるので、紐づける方法を紹介する。

  • SMTP送信の時にSNSトピックにメッセージを送る
  • SNSトピックでLambda関数を購読状態にする
  • lambda関数で送信前と送信後のmessageIDを取得
  • lambda関数でよしなにする(私の場合は、DBの送信前の message_header_id を 送信後の message_header_id に更新するクエリを実行)

さて、肝心のLambda関数の中身は以下である。

event 変数にメールの情報が入ってくるので、関数の通りに取得していくと、送信前と送信後のmessageIDを取得できる。

sns_obj['Message']JSON.parse している理由は、なぜかこの項目は文字列で値が返ってくるからである。

オブジェクトの中身の詳細は、公式ドキュメントを参照。

exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };

    const sns_obj = event['Records'][0]['Sns']
    console.log(sns_obj)
    const message_obj = JSON.parse(sns_obj['Message'])
    console.log(message_obj)
    const mail_obj = message_obj['mail']
    console.log(mail_obj)
    const new_message_id = `<${mail_obj['messageId']}@email.amazonses.com>`
    const original_message_id = mail_obj['headers'].find(x=>x['name']=='Message-ID')['value']

    // result
    console.log(original_message_id)
    console.log(new_message_id)

    return response;
};