はじめに
AWS Step Functionsで処理結果をSlackに通知したいなぁ…でもそのためにLambdaを一つ作るのも面倒くさいなぁ…と思っていたのですが、ちょっと工夫したらLambdaを作らずにSlackのIncoming Webhookを呼び出せることに気づいたので、ちょっと実装してみました。
さっそく実装
で、こんな感じで実装してみました。
- API GatewayはAWSサービスだけでなくて、外部のWebAPIのラップにも使うことができる
- Step FunctionsのタスクとしてAPI Gateway呼び出しを行うことができる
この2点を組み合わせた形です。
なお、今回はCDKを使ってサンプル実装をしています。
CDKプロジェクトはgithubの方に置いてあります。
API Gatewayの実装
単純にAPI GatewayでのPOSTをSlackのIncoming WebhookのPOSTに繋げてあげているだけです。
本当はプライベートAPIにする方がいいのかな、とも思ったのですが、Step FunctionsからはプライベートAPIは呼び出せない旨がAWSのドキュメントに記載されていたので、リージョンAPIにした上でIAM認証にすることで、無関係の他者から呼び出せないようにしています。
2021/05/24 修正
プライベートAPIにしてもAWS内からだったら他者から呼び出されてしまうことを忘れて記載してました。リージョンAPIだろうがプライベートAPIだろうが、何らかの制限をかける必要はありますね。
今回はIAM認証を使うことで、期待外から使用されることを避けています。
Step Functionsの実装
{
"StartAt": "Initialize",
"States": {
"Initialize": {
"Type": "Pass",
"Result": {
"text": "Hello, World!"
},
"ResultPath": "$.message",
"Next": "PostMessage"
},
"PostMessage": {
"End": true,
"Type": "Task",
"Resource": "arn:aws:states:::apigateway:invoke",
"Parameters": {
"ApiEndpoint": "XXXXX.execute-api.ap-northeast-1.amazonaws.com",
"Method": "POST",
"Stage": "prod",
"Path": "/messages",
"RequestBody.$": "$.message",
"AuthType": "IAM_ROLE"
}
}
}
}
サンプルなので、InitializeステートでSlackのIncoming WebhookへPOSTするデータを作成していますが、実際の処理の際には通知内容を作成するLambdaなどを呼び出す形になると思います。
API Gatewayに送る箇所は見ればわかるレベルの内容だと思います。
実行結果
こんな感じでSlackの方に通知されました。
おわりに
これを作った後に「SNSからChatbot経由でSlackへ通知する方が自然じゃない?」と思ったりもしましたが、手段が多いに越したことはないということで。
それはさておき。
今までStep FunctionsってLambdaでの処理を繋げていくもの、というイメージが強かったのですが、Lambda以外のAWSサービスへ接続がいろいろできるということで、処理の分離をしやすくなっているのかな、という印象をもちました。
私の個人開発ではLambdaの実行結果の通知にLine NotifyやSlackのIncoming Webhookを使うことが多く、それぞれのLambdaの中でaxiosなど使ってこれらのWebAPIを呼び出す、ということをしていたのですが、今回のサンプル実装のように通知部分はStep Functionsから直接呼び出せるようになると、Lambdaは処理に専念でき、面倒なI/O系の記述を減らすことができる、というメリットがあるのかな…と感じています。