SNSでSlackにメッセージ送信する #slack

2018.11.25

こんにちは中村です。

今回はSNSでSlackにメッセージ送信する機能を作りたいと思います。AWSの他サービスとの連携において利用できそうです。(私の業務領域では、Code Buildなどの処理完了SNSをSlackやChatworkで受信したかったりします。)

はじめに

今回利用するAWSサービスは下記です。

  • SNS
  • Lambda

Slackには今回使用する用にチャネルを作っておきましょう。

作ってみた

まずはSlack APIのYour AppsでAppを作成します。作成にあたり、App NameDevelopment Slack Workspaceを入力する必要があります。

Appが作成されると、Basic Informationページに遷移します。ここでは、作成したいAppの機能などを選択します。今回はLambdaからメッセージを送信したいので、Incoming Webhooksをクリックしてください。

Incoming Webhooksをクリックすると、Activate Incoming Webhooksというページに遷移するので、スイッチをOnにしてAdd New Webhook to Workspaceをクリックし、チャンネル名を選択・許可するをクリックします。

これでWebhook URLが作成されます。POSTリクエストすることでメッセージが送信できます。認証等がないのでこのWebhook URLが外部に漏れないように気をつけましょう。

試しにターミナルで下記を実行してみてください。先ほど設定したWorkspaceのチャネルにHello, World!が送信されます。

curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/XXXXXXX/XXXXXXX/XXXXXXX

メッセージが届いたら、Slack側の設定は完了です。AWS側を構築していきましょう。

まずは、Lambdaを作成します。ランタイムは、node.js8.10を選択してください。名前・ロールについては適当なものを入力・選択でOKです。(サンプルコードはtypescriptになります。)

必要なモジュールをインストールします。

  • request-promise
  • request(request-promiseを使うため)

ちなみに必須ではありませんが@typesなどを入れておくと開発時に便利です。

先ほどのテストでわかるように基本的にWebhookにPOSTすることでメッセージが送信されます。 下記の簡単なサンプルコードをトランスパイルしモジュールと一緒にデプロイしましょう。

import * as rp from 'request-promise';

exports.handler = async(event: any) => {
    console.log(JSON.stringify(event));
    let url: string = '';
    if (process.env.HOOK_URL) {
        url = process.env.HOOK_URL; //Lambdaの環境変数 HOOK_URLにWebhook URLを登録しておく
    }

    let option = {
        'url': url,
        'header': {
            'Content-Type': 'application/json'
        },
        'method': 'POST',
        'json': true,
        'body': {
            'text': event.Records[0].Sns.Message
        }
    };
    let result = await rp(option).promise();
    console.log(result);
}

デプロイが完了したら、Lambdaのテストをしましょう。Amazon SNS Topic Notificationというイベントテンプレートがあります。このテンプレートを実行すると、example messageがSlackに送信されると思います。

Slack上で確認できたら完了です。 最後にSNSを設定していきます。

SNSのダッシュボードを開き、サイドバーのトピックをクリックします。新しいトピックを作成をクリックし、トピック名・表示名を入力し作成します。

作成が完了すると一覧に表示されるので、ARNをクリックして詳細に遷移します。

このSNSトピックにLambdaを紐づけていきます。サブスクリプションの作成をクリックします。

  • プロトコル: AWS Lambda
  • エンドポイント: LambdaのARN
  • バージョンまたはエイリアス: default

を入力しサブスクリプションの作成をクリックします、サブスクリプションの一覧に登録されていれば完成です。

テスト

SNSを発行してみましょう。SNSトピック詳細ページのトピックに発行をクリックします。 ここでメッセージに入力した内容がSlackにメッセージが送信されます。

Slackを確認してみましょう。ちゃんと送信されて来るはずです。

まとめ

いかがでしたでしょうか。 簡単に機能を追加できるようになっているので、業務の色々な部分に役立つインテグレーションができると思います。