AWSステップ機能を一度だけメールを送信する


ほとんどのメール配信API:Sは2つのメールを送信する場合は2つの要求を送信します.要求が重複することができる多くの方法があるので、これは問題であるかもしれません.必要以上にメールを送りたくないでしょう.例えば、SQSとEventBridgeは少なくとも一回の配送を保証します.

複数のメールを送信するのを避けるために、Step関数とDynamoDBを使用する方法を見てみましょう.我々は、すでにメールを処理しているかどうかを確認するためにDynamodbの条件式を使用します.ステートマシンの基本的な流れは以下の通りです.
  • メールに基づいてハッシュを作成します.
  • DynamoDBのハッシュを保存してください.項目が既に存在する場合、abortと何もしない.
  • アイテムが存在しない場合は、続行し、メールを送信します.

  • 同じ入力で複数の実行は、追加のメールを送信しません.私たちには、持分力があります.

    ハッシュの作成


    電子メールの短い文字列表現を作成し、データベースに保存します.送付者、受信機、主題と内容に基づいてユニークなストリングをつくるハッシュ関数を使いましょう.これは、データベース内のユニークなキーになります.これは、我々が以前にメールを処理したかどうかを判断するために使用します.
    const crypto = require('crypto');
    
    exports.handler = async (email) => {
        const combined = `${email.from}${email.to}${email.subject}${email.content}`
        const hash = crypto.createHash('sha256').update(combined).digest('base64');
        return hash;
    };
    

    アイテムを保存する


    次に、条件式を使用してデータベースにハッシュを挿入しようとします.項目は既に存在してはいけません.アイテムがすでに存在するならば、我々がすでにそれを処理したことを示している-我々はこの誤りを捕えて、電子メールを送らないことを望みます.それが存在しないならば、我々は電子メールを送り続けます.

    メールを送る


    電子メールを送信する多くの方法があります.あなたの電子メール配信APIに従って実装します.このステップは、あなたが一度だけしたいほとんど何でも置き換えられることができます.例えば、支払いと注文.
    exports.handler = async (email) => {
        // TODO implement send email
        return "sent email";
    };
    
    
    メールが以前に処理されていない場合、実行は次のようになります.

    メール処理済み


    キャッチConditionalCheckFailedException そして、ステップ関数でパス状態を使用します.私たちが実際に今回メールを送っていなかったとしても、成功状態で終わることは重要です.これはidemsible APIの特徴です.他のすべてのエラーに対してフェイル状態を使用します.
    メールが既に送られている場合、実行は以下のようになります.

    結論


    それはかなりだ!ステートマシンの定義は以下の通りです.https://gist.github.com/danielfyhr/4144dba260cc2bce1509d12cfd998664
    標準ワークフローは、各ワークフローステップの実行を一度だけ保証します.https://aws.amazon.com/step-functions/faqs/