Slack Bot を Kotlin + Serverless Framework + AWS Lambda で作る

2023/11/16に公開

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.gradlebuild.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 TokenSigning Secret を取得します。

  1. https://api.slack.com/apps で アプリを作成する
  2. Basic informationApp CredentialsSigning Secret があるので手元にメモしておく
  3. OAuth & PermissionsScopeapp_mentions:readchat:write を追加する
  4. OAuth & PermissionsInstall to Workspace を選択して、Slack にインストールする
  5. インストールが完了すると Bot User OAuth Access Token(Bot Token) が表示されるのでこれもメモします( xoxb- から始まります )

Serverless Frameworkを使って deploy までやる

.envを用意する

先ほどのBot TokenSigning 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 eventsapp_mention を追加して Save Change を押してください。

動作確認

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

Discussion