Slack Bot を Kotlin + Serverless Framework + AWS Lambda で作る
Slack Bot を Kotlin + Serverless Framework + Lambda で作っていこうと思います。
使用技術
今回の使用技術は以下のようになっています。ツール系のインストールなどは完了しているとします。
| 技術 | 説明 | URL |
|---|---|---|
| Slack Bolt for Java | Slack の Java用の SDK | リンク |
| Amazon API Gateway + AWS Lambda | APIのエンドポイントおよびAPIの実装をここで | - |
| Serverless Framework | サーバーレスアプリケーションの開発、デプロイ、管理ツール | リンク |
| Kotlin | プログラミング言語 | リンク |
まずは実装していく
Kotlin のプロジェクトを立ち上げる
Gradle プロジェクトを作成して、 Bolt 関連と lambda 関連の依存ライブラリを build.gradle や build.gradle.kts に追加します.
dependencies {
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("com.slack.api:bolt-jetty:1.34.0")
implementation("com.slack.api:bolt-aws-lambda:1.34.0")
implementation("org.slf4j:slf4j-simple:1.7.36")
implementation("com.amazonaws:aws-lambda-java-core:1.2.1")
implementation("com.amazonaws:aws-java-sdk-lambda:1.11.907")
}
メンションに反応して返信する実装をする
今回は簡単にメンションがあれば Hello と返す Bot とします.
com.slack.api.bolt.App のインスタンスを作成して、app.event(AppMentionEvent::class.java) でメンションに反応するようになります。そして、chatPostMessage で返信が送信されます。
object SlackApp {
fun get(config: AppConfig? = null)): App {
val app = App(config)
app.event(AppMentionEvent::class.java) { payload, ctx ->
val event = payload.event
ctx.client().chatPostMessage {
it.channel(event.channel)
it.threadTs(event.ts)
it.text("Hello")
}
ctx.ack()
}
return app
}
}
RequestHandler を実装する
Lambda では RequestHandler を実装する必要があります。
bolt-aws-lambda には RequestHandler を継承した SlackApiLambdaHandler が用意されているので、これを使います。
下記のように SlackApiLambdaHandler のコンストラクタで com.slack.api.bolt.App のインスタンスを渡しつつ、 isWarmupRequest を実装すればOKです。
class SlackEventHandler() : SlackApiLambdaHandler(SlackApp.get()) {
override fun isWarmupRequest(awsReq: ApiGatewayRequest?): Boolean {
return false
}
}
実装はこれで完了です。 Graldeプロジェクトをビルドして fat jar ファイルを生成しておきます。
Slack Botの準備をする
Bot Token と Signing Secret を取得します。
- https://api.slack.com/apps で アプリを作成する
-
Basic informationのApp CredentialsにSigning Secretがあるので手元にメモしておく -
OAuth & PermissionsでScopeにapp_mentions:readとchat:writeを追加する -
OAuth & PermissionsでInstall to Workspaceを選択して、Slack にインストールする - インストールが完了すると
Bot User OAuth Access Token(Bot Token) が表示されるのでこれもメモします(xoxb-から始まります )
Serverless Frameworkを使って deploy までやる
.envを用意する
先ほどのBot Token と Signing Secretをもとに .env ファイルを作ります。
SLACK_BOT_TOKEN=xoxb-xxxxxxxxx <-- 先ほどのBot Tokenを設定
SLACK_SIGNING_SECRET=xxxxxxxxx <-- 先ほどのSigning Secretを設定
serverless.yml を記述する
.env ファイルと同じ場所に 次の serverless.yml を作ります。
内容は下記で、適宜書き換えてください。
service: example-slack-bot <--- lambda の名前を定義
useDotenv: true
provider:
name: aws
runtime: java11
stage: ${opt:stage, 'dev'}
region: ap-northeast-1
apiGateway:
shouldStartNameWithService: true
iamRoleStatements:
- Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:InvokeAsync
Resource: "*"
environment:
SERVERLESS_STAGE: ${opt:stage, 'dev'}
SLACK_SIGNING_SECRET: ${env:SLACK_SIGNING_SECRET}
SLACK_BOT_TOKEN: ${env:SLACK_BOT_TOKEN}
package:
artifact: ./path/sample-slack-bolt.jar <--- jarのパスを設定
functions:
api:
handler: com.xxx.slack.SlackEventHandler <--- 先ほど実装したクラスを設定
timeout: 30
events:
- http:
path: slack/events
method: post
deployする
serverless.yml があるところで下記を実行します.
serverless deploy
デプロイが完了すると endpoint が表示されているはずなので、これをメモします。
流れちゃった人は、下記で再度 endpoint などを見ることができます。
serverless info
Slack に Event Subscription Request URL を設定する
Slackアプリの設定画面に戻ります。 Event Subscriptions に移動して、 Enable Events をオンにします。 Event Subscriptions Request URL に 先ほどメモした endpoint を入力。
Verified と表示されたら、Subscribe to bot eventsで app_mention を追加して Save Change を押してください。

動作確認
あとは Slack で メンションを投げてみて Hello と返信がくることが確認できれば完了です。
Discussion