SlackとAWSを繋ぐはじめの一歩~SlackのChallenge認証へチャレンジする~

四月だし新しい事に挑戦(チャレンジ)してみました。
2020.04.01

エイプリルフールにつく嘘を考えていたら、嘘をつく機を逃しました。という嘘です。


▲ 分かりづらいな

AWS事業本部のShirotaです。
日々、冗談でそれっぽい嘘知識を友人にしれっと話す遊びをしてしまう為、逆に今日という日は自粛する事に決めていました。

SlackとAWSで便利に楽しくなりたい

リモートワーク(テレワーク)の日々、基本的に会社の人とのコミュニケーションで用いるものとしてコミュニケーションツールがメインになるかと思われます。
かく言う私も、Slackを日々重宝しております。家に一人でいる事が多いと(そうでなくても)このようなコミュニケーションツールが唯一外部の人々との接点になりがちです。
さて、折角Slackを使うなら便利に使いたい!そう思われている方も多いのではないでしょうか。
実際に私も、経費の申請をリマインドしたり勤怠の打刻を連携したりして使っております。便利にカスタマイズしたSlackの無い仕事環境なんてもう考えられません。
弊社でも、多くの人たちがSlackを思いのままに使い倒している事がブログ記事から読み取れます。

Slack | 検索結果: | Developers.IO

その中でもやはり SlackとAWSを連携させて使い倒している ものが多いと感じられます。

私も、SlackとAWSを連携させてやってみたい事が思い浮かんだので「いざやろう!」と意気込みいそいそと手を動かし始めたのですが、ふとある事に気付き手が止まりました。

思い描かれる夢想のアーキテクチャ、浮かばぬ作業

まず、やりたい事を決めてアーキテクチャを考えてみました。
実際に手を動かした経験は浅いのですが、ここはやりたい事と必要なサービスを頭の中で落とし込む事ができたので結構すんなりと行きました。
基本的には、必要なリクエストが生じた時だけ動作して管理の必要も少なめなアーキテクチャを考えています。


▲ 何を作るにしてもここが基本

つまり、SlackとAWSを連携させようと考えた時に、まず第一の関門は SlackとAPI Gatewayを連携させる 所である事が分かりました。
そもそも、これを考えた時には「まぁAPI GatewayもSlackのAppもあまり触った事が無いけど何となく理解できてやれるだろう」と考えていました。
ところが実際にやってみようとすると、どちらも圧倒的経験不足からか何をどうしていくべきかが簡単に思い浮かびませんでした。
「このままではやりたい事に辿り着けないまま心が折れてしまうぞ」そう思った私が格闘した経緯を辿りながら、今回はSlackとAWSを連携する際のChallenge認証を通るように設定した話をさせて頂こうと思います。

やりたい事を整理する

まずは、SlackとAWSを連携させる為にやる事になる作業を整理します。

  1. Slack Appを作成する
  2. Lambdaを作成する
  3. API Gatewayを作成する
  4. Lambda + API Gatewayを連携する
  5. API Gateway + Slack Appを連携する

Slack側でAppを用意して、AWS側では各マネージドサービスとの連携やSlackとの連携の玄関口となるサービスを準備します。
そして今回最も重要なゴールが、サービスのエンドポイントが認証される 事です。
これができないと、どんなにAWSで便利で楽しいサービスを用意できてもSlackにサービスが到達しません。Slack側からデータをAWSに渡す事もできません。
Slack AppにエンドポイントのURLを認証させる為には Challenge認証 が使われております。
Challenge認証……Challenge認証!?とサービスを作った事の無い私はそこで再び手が止まりました。
ここで、ちょっと寄り道してSlackのChallenge認証の話をしたいと思います。

SlackのChallenge認証について

頭に Slackの とつけているように、一般的に言われるチャレンジ/レスポンス認証とSlackのChallenge認証は異なります。
具体的に話すと、SlackのChallenge認証はよりシンプルな仕組みとなっています。
Slack Appは、エンドポイントのURLを登録すると以下のようなPOSTを送信します。

{
    "token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
    "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
    "type": "url_verification"
}

上記tokenとchallengeはSlack公式のリファレンスから引用したものです。
実際にもこんな感じでランダムな英数字が入ったJSON形式のPOSTが送信されます。
この「Challenge」の値をそのまま返す事で、Slack AppはエンドポイントのURLを認証し、呼び出してくれるようになります。

参考に、Slack公式のリファレンスページを載せておきますので参考にして下さい。

url_verification event | Slack

Challengeしてみた

では、やるべき事とChallenge認証の仕組みを理解したところで、早速やってみましょう。
整理したやりたい事順にまとめてみました。

Slack Appを作成する

まずは、Slack API | Slack にアクセスします。
ヘッダーの右上にある「Your Apps」をクリックすると以下のようなページが表示されるので、「Create New App」をクリックして下さい。


▲ はじめるぞ

次に、Appの名前とAppを利用したいSlackのワークスペースを選択します。


▲ これでターンエンド

Slack Appの完成です 。ね?簡単でしょ?
勿論、これだけだと本当にAppのガワができただけですが、これが全ての土台となります。全てのスタート地点に立ったところです。
次は、AWS側の準備を進めていきましょう。

Lambdaを作成する

今回の要、Challenge認証を通せるようなLambdaを作成します。
私は今回、Python3.8で動かす事にしました。

まず、Lambdaを作成……する前に、Lambdaがやりたい事をやれる権限を付与する為のIAMロールを事前に作成しておきます。
この作業は、Lambdaを作成する際にもできるのでここで絶対やっておく必要はありません。


▲ AWSLambdaBasicExecutionRoleをアタッチ

IAMロールの作成が済んだら、Lambdaを作成します。
今回は、「Author from scratch」を選択して、1からLambdaを作っていきます。


▲ ここで先ほど作成したIAMロールをアタッチ

ここからは、今回Challenge認証に用いる、POSTで送信されたChallengeの値を返す部分を作っていきます。

デフォルトで、LambdaのPythonは以下のような記述があります。

import json

def lambda_handler(event, context):

これは、Lambda関数を作成する際に必要となるハンドラー関数の定義です。
通常、ここでのeventパラメータはdict型となっています。
ここで、改めてどのようなデータがSlack Appから送信されてくるかを見てみましょう。

{
    "token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
    "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
    "type": "url_verification"
}

今回は、contextに入っているchallengeの値をSlack Appに返してあげられるとChallenge認証が通る筈です。
なので、シンプルにreturnで戻り値をそのまま返してあげます。

import json

def lambda_handler(event, context):
    # Return Slack challenge parameter
    return event['challenge']

これで、Lambdaの準備は整いました。
Pythonを記述した後、 右上のSaveが押せるようになっている筈なので押すことを忘れずに! (自戒)


▲ SaveするまでがLambda

API Gatewayを作成する

今回はLambdaの画面からAPI Gatewayの作成を実施して、そのまま次の「Lambda + API Gatewayを連携する」までやってしまいます。

LambdaのDesignerから、「Add trigger」を選択します。


▲ 今あるAPI Gatewayはこれからの作業で実際に作ったもの

今回は、API Gatewayを作成してこのLambdaに連携したいので、以下のように選択・入力します。


▲ 連携したいリソースをここで作れるの、便利

今回は、安くて手軽に使い始められるHTTP APIを選択しました。
先月GAされたばかりのHTTP APIについては、以下のブログが分かり易くまとめてあったので参考にして下さい。

[アップデート] より高速に!より低コストに!プライベート統合も可能に!API Gateway の HTTP API が GA されました! | Developers.IO

Amazon API Gatewayは「HTTP API」と「REST API」のどちらを選択すれば良いのか? #reinvent | Developers.IO

そうして作成して連携されたAPI Gatewayがこちらになります。


▲ ね?簡単でしょ?(二回目)

Lambdaから作成されたHTTP APIのRouteは以下のように「ANY」となっているので今回は特に変更をかけずにいきます。


▲ ここまでやってくれるの、便利

AWS側の作業はこれで完了です。
さあ、最後のキモであるChallenge認証にチャレンジしましょう!

API Gateway + Slack Appを連携する

先ほど作成した、API GatewayのエンドポイントのURLをコピーしておいてから、Slack Appのページに戻って「Event Subscriptions」を選択します。


▲ ゴールはすぐそこ!

Enable EventをONに切り替え、URLを入れると自動でChallenge認証が始まります。結果は……


▲ イエーイ!Challenge成功です

今回、API GatewayのCloudWatch Logsを有効化して、Challenge認証を実際に受け取り、レスポンスを返しているログを取得してみました。


▲ 燦然と輝く200番

これで、後はSlack AppとAWSでやりたい事をそれぞれ実装していけば、Slack Appで色々な事ができるようになりました!

たかが最初の一歩、されど最初の一歩

今回紹介したSlackのChallenge認証を突破するだけでは、実際にはまだ何もできてはいません。ここから本気出す
でも、ここで躓くと実は何もできるようにならないという事に実際躓いた私は感じました。
同じように最初の一歩で詰まってしまう人が少しでも居なくなり、また「何でChallenge認証をする必要があるんだろう」という人のお役にも立てれば幸いです。