LoginSignup
13
6

More than 1 year has passed since last update.

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

Last updated at Posted at 2020-05-29

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

ご参考までに。

13
6
0

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
  3. You can use dark theme
What you can do with signing up
13
6