AWSのLambda関数から、SlackのIncoming Webhooksでメッセージを送信する機会があり、少々躓いた箇所があったので備忘録として残しておきます。
Lambda関数やIncoming Webhooksは準備できている想定として、これらの作成手順は省略します。
環境
- macOS
- AWS Cloud9
- Node.js 12
実行コード
Lambda関数を1度実行する度に、Slackメッセージを1件だけ送るような場合は、以下のコードで動くと思います。
1度のLambdaで複数回メッセージを送る場合は、注意点があるので後ほど説明します。
constenv=process.envconstrequest=require('request');exports.handler=function(event,context){// リクエスト設定constoptions={url:env.WEB_HOOK_URL,headers:{'Content-type':'application/json'},body:{"username":"jinto","text":"Hello !!"},json:true};//メッセージ送信request.post(options);return"success !!";}
1度のLambdaで大量のメッセージを送る場合
2〜3件程度のメッセージであれば上記のコードをそのままfor文等で繰り返しても問題ないと思いますが、数十件〜数百件のメッセージを1度のLambdaで処理したい場合は注意が必要です。
仮に上記のコードを、
for(leti=0;i<100;i++){//メッセージ送信request.post(options);}
このように100回繰り返した場合、Slackにはメッセージが数件〜数十件しか届かないと思います。自分もここで躓きました。
どうやら、requestメソッドは非同期的に処理されるので、requestを100回実行し終わる前に、Lambda関数の実行そのものが終了してしまうようです。
大量のメッセージを送信したい場合には、requestをpromise化し、async〜awaitで1件ずつ止めてあげると上手く動きます。
Node.jsには、request-promise
という便利なモジュールがあったので、こちらを使用しました。コードを以下に示します。
constenv=process.envconstrequestPromise=require('request-promise');exports.handler=async(event,context)=>{// リクエスト設定constoptions={url:env.WEB_HOOK_URL,headers:{'Content-type':'application/json'},body:{"username":"jinto","text":"Hello !!"},json:true};for(leti=0;i<100;i++){awaitrequestPromise.post(options);// 通常のrequestだと非同期的に処理されるので、処理が終わる前にLambda関数が閉じてしまう}return"success !!";}
ご参考までに。