読者です 読者をやめる 読者になる 読者になる

tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

.NET Core on Lambda で Slack Slash Command を作ってみよう

AWSLambda C# AWS Serverless .NETCore

さて、前回、前々回と .NET Core on Lambda の下回りを見てきました。

tech.guitarrapc.com

tech.guitarrapc.com

大事なパッケージ周りやデプロイについては別の機会にするとして、そろそろ簡単なコマンドをWebhook で投げて返してみましょう。ついでに Lambda の環境変数も触っておきます。

目次

サンプル

今回実装のサンプルとするのは、Azure Functions の時に見かけた Slack の Slash Command を作ってみたという例です。Slack の Slash Command 入力を起点に、Slack (Post) -> Azure Functions (コード実行) -> Slack という流れです。

blog.xin9le.net

API Gateway + AWS Lambda

AWS Lambda はステートを持たないイベントドリブンなアプリケーション実行環境です。そのため、Azure Functions と異なり単体では外部Webリクエストを受け付けたり返却することはできません。

そこで、Slack -> Azure Functions / AzureFunctions -> Slack に該当する接続部分にAPI Gateway を用いるのが定石となっています。今回もそれに従いましょう。

AWS Lambda のコード作成

.NET Core on AWS Lambda の最も使いやすいポイントは、ローカル実行環境の整備 と ふつうのC# (.NET Core)を普通にかけることです。今回は、Slack Slash Command が送られてきたら、Hello from Lambda .NET Core. と返させてみます。

gist.github.com

コードはごく単純です。

Slack Slash Command で返ってくるJSON を SlackSlashCommand クラスでデシリアライズしてLambda関数に受けます。あとは、&でつながれている入力文字列を分割して、=で区切られた Key/Value から 値を取得しています。

続いて、Lambdaの環境変数に埋めたトークンと送信されてきたトークンの一致を検証しています。本来なら、処理内部ではなく前段のAPI Gateway 時点ではじきたいのですが、API Gateway の APIキー指定が Header 利用で、Slack Slash Command の送信ヘッダをいじれないためシカタナイです。

最後に、Slack に対してレスポンスを返しています。

AWS Lambda のコードをアップロードと環境変数操作

Visual Studio からのアップロードにて、Lambda関数の環境変数も併せて調整可能です。

f:id:guitarrapc_tech:20161206033705p:plain

今回は、SlackSlashCommandWebhook としてLambda関数を作成しました。

Azure Functions でもそうでしたが、環境変数を利用することでコードから機微情報を除外できるのでとてもいいです。特に AWS Lambda は KMS による暗号化もかかっていて一定の安心感があります。環境変数については参考にできるサイトがいくつもあります。より詳しく知りたい方はこちらへ。

dev.classmethod.jp

API Gateway に API を作成

続いて、Slack の Slash Command (という名の Webhook) を受けるため API Gateway で APIを作成します。Slack の Slash Command は POST でリクエストできるので、GET ではなく POST にします。

f:id:guitarrapc_tech:20161206034540p:plain

先ほど作成した、Lambda関数 をバックエンドに指定しておいてください。これで次のような API Gateway の設定ができたと思います。

f:id:guitarrapc_tech:20161206034803p:plain

さて、Slack Slash Command は JSON ではなく application/x-www-form-urlencoded としてリクエストしてくるのですが、Lambda関数は JSON で入力されることを期待しています。そこで、Integration Request を調整して、リクエストボディから JSONを抽出して Lambda 関数に渡します。具体的に、次の通り入力します。

Content-Type 処理
application/x-www-form-urlencoded { "body": $input.json("$") }

f:id:guitarrapc_tech:20161206035126p:plain

これでAPI Gateway の設定が出来ました。Deploy API でス任意の環境にデプロイしてみましょう。

f:id:guitarrapc_tech:20161206035230p:plain

デプロイすると、API のURL が定まります。

f:id:guitarrapc_tech:20161206035335p:plain

Slack の Slash Command を作成する

API Gateway の URL が定まったので、Slack に Slash Command を作成します。URL欄には、API Gateway で作成した APIのURL を入れます。

f:id:guitarrapc_tech:20161206035428p:plain

準備できましたか?

早速実行してみます。

f:id:guitarrapc_tech:20161206035515p:plain

うまくいきましたね!

まとめ

従来 Node.js や Python、Java でやっていたことは基本的に .NET Core でも同様にできるでしょう。手始めに Slackを用いましたが、別の様々なサンプルの移行が簡単にできます。当然、Azure Functions で実装していたものは、ほぼそのまま移行できます。次はそのあたりを。

今回のコードサンプルも追加しておきます。

github.com