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