LoginSignup
3

posted at

updated at

LambdaからSlackにメッセージを送る際のソースコードと複数回メッセージを送る際の注意点

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 !!";
}

ご参考までに。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3