[AWS Step Functions] Mapステートを使用して複数の宛先にSMSメッセージを送信する

2021.10.29

こんにちは、CX事業本部 IoT事業部の若槻です。

前回のエントリでは、AWS Step Functionsを使用してSMSのメッセージを送信しました。

今回は、同じくAWS Step Functionsを使用して、Mapステートにより複数の宛先にSMSのメッセージを送信してみました。

Mapステートとは

Step Functionsでは、何らかの処理を実施する「Task」、実行を分岐させる「Choice」などのステートを組み合わせることによりステートマシンを作ります。

このうち、動的な繰り返し処理を実装するのがMapです。

やりたいこと

Mapによる繰り返し処理により、複数通のSMSのメッセージの送信を動的に行えるようにしたいです。宛先によりメッセージは異なりますが、送信者IDは同じです。

やってみた

前提として、ステートマシンの入力は下記を指定することにします。

{
  "mapped": [
    {
      "message": "おはようございます。",
      "phoneNumber": "+8170XXXXXXXX"
    },
    {
      "message": "こんばんは。",
      "phoneNumber": "+8180XXXXXXXX"
    }
  ],
  "common": {
    "messageAttributes": {
      "AWS.SNS.SMS.SenderID": {
        "DataType": "String",
        "StringValue": "classmedhod"
      }
    }
  }
}

ステートマシンの作成

Step Functions Workflow Studioでステートマシンを作成します。

Step Functionsのマネジメントコンソールで、[ステートマシン]の作成をクリックします。

[次へ]をクリックします。

すると「Workflow Studio」が開きます。[フロー]からMapをドラッグします。

Mapの[設定]-[項目配列へのパス]で$.mappedを指定します。

同じくMapの[入力]で[配列項目を変換]をチェックして、以下のJSONを指定します。

{
  "mapped.$": "$$.Map.Item.Value",
  "messageAttributes.$": "$.common.messageAttributes"
}

[アクション]から[Amazon SNS]のPublishをMapステートの中にドラッグします。

SNS Publishの[設定]で[Integration type]をAWS SDKに変更し、[APIパラメータ]に以下のJSONを指定します。

{
  "PhoneNumber.$": "$.mapped.phoneNumber",
  "Message.$": "$.mapped.message",
  "MessageAttributes.$": "$.messageAttributes"
}

その後、[次へ]をクリックします。

生成されたコードを確認したら[次へ]をクリックします。

生成されたコード(ステートマシン定義)は下記のようになります。

{
  "Comment": "A description of my state machine",
  "StartAt": "Map",
  "States": {
    "Map": {
      "Type": "Map",
      "End": true,
      "Iterator": {
        "StartAt": "SNS Publish",
        "States": {
          "SNS Publish": {
            "Type": "Task",
            "Resource": "arn:aws:states:::aws-sdk:sns:publish",
            "Parameters": {
              "PhoneNumber.$": "$.mapped.phoneNumber",
              "Message.$": "$.mapped.message",
              "MessageAttributes.$": "$.messageAttributes"
            },
            "End": true
          }
        }
      },
      "ItemsPath": "$.mapped",
      "Parameters": {
        "mapped.$": "$$.Map.Item.Value",
        "messageAttributes.$": "$.common.messageAttributes"
      }
    }
  }
}

[ステートマシンの作成]をクリックして作成を完了します。

動作

作成されたステートマシンで[実行の開始]をクリックします。

冒頭でも記載した下記のJSONを入力としてステートマシンを実行します。

{
  "mapped": [
    {
      "message": "おはようございます。",
      "phoneNumber": "+8170XXXXXXXX"
    },
    {
      "message": "こんばんは。",
      "phoneNumber": "+8180XXXXXXXX"
    }
  ],
  "common": {
    "messageAttributes": {
      "AWS.SNS.SMS.SenderID": {
        "DataType": "String",
        "StringValue": "classmedhod"
      }
    }
  }
}

ステートマシンの実行が成功しました。

いずれの電話番号の端末でもSMSのメッセージが受信できています。

別解

別解として、下記のステートマシン定義でも同じ動作となります。

{
  "Comment": "A description of my state machine",
  "StartAt": "Map",
  "States": {
    "Map": {
      "Type": "Map",
      "End": true,
      "Iterator": {
        "StartAt": "SNS Publish",
        "States": {
          "SNS Publish": {
            "Type": "Task",
            "Resource": "arn:aws:states:::aws-sdk:sns:publish",
            "Parameters": {
              "PhoneNumber.$": "$.phoneNumber",
              "Message.$": "$.message",
              "MessageAttributes.$": "$.messageAttributes"
            },
            "End": true
          }
        }
      },
      "ItemsPath": "$.mapped",
      "Parameters": {
        "phoneNumber.$": "$$.Map.Item.Value.phoneNumber",
        "message.$": "$$.Map.Item.Value.message",
        "messageAttributes.$": "$.common.messageAttributes"
      }
    }
  }
}

mappedからの各プロパティ値の取り出しを、[SNS Publish]ではなく[Map]のParametersで行っています。

まとめ

  • Step Functionsではステートを組み合わせてステートマシンを作る。
  • Mapステートを使用すれば繰り返し処理を実装可能。
  • 実現したいことによっては、ItemsPathParametersを駆使する必要がある。

以上