GroovyとSpring BootでSlack Appを作る

2020.09.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

概要

この記事ではJVM言語の1つであるGroovyとSpring Frameworkをより使いやすくまとめたSpring Bootを組み合わせて、簡単なSlack Appを作成します。

Slack Appの作成はBolt for JavaGetting Startに書かれているサンプルを参考とし、簡単なSlash Commandを実装していきます。

本記事ではローカル環境でSlack Appを稼働させ、ngrokを介してSlackと通信できるようになるまでをゴールとします。

また、本記事ではSpring Boot CLIは用いず、通常のGradleプロジェクトとしてアプリケーションを実装します。

Groovyについて

GroovyはJVM上で稼働するAltJava言語の一つであり、Javaのような静的型言語とPythonやRubyのような動的言語の性質を併せ持ったような特徴があります。

GradleのようなDSLを持つアプリケーションやメタプログラミングなどで利用されることが多くありますが、今回は型による補完などのIDEの支援をうけつつ、LL言語のように記述量やファイル数を抑えられることから、気軽にJava Frameworkを試すために利用することにしました。

プロジェクト構成

今回はGradleの構成に従ってプロジェクトを作成しました。

$ tree bolt-groovy/
bolt-groovy/
├── build.gradle
...snip...
└── src
    └── main
        ├── groovy
        │   └── hello
        │       └── HelloApp.groovy
        └── resources
            └── application.yaml

Groovyでは、@Grabアノテーションを使うことでソースコード中に依存ライブラリを宣言することができる機能がありますが、InteliJ IDEAでのコード支援がうまく機能しなかったこと、Gradle Task自体は必要となることなどから今回は利用しないことにしました。

build.gradle の設定は以下の通りです。

plugins {
    id 'org.springframework.boot' version '2.3.3.RELEASE'
    id 'groovy'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.codehaus.groovy:groovy-all:3.0.5'
    implementation 'org.springframework.boot:spring-boot-starter-web:2.3.3.RELEASE'
    implementation 'com.squareup.okhttp3:okhttp:4.8.1'
    implementation 'com.slack.api:bolt-servlet:1.1.3'
}

アプリケーションコード

Javaで書く場合、public class毎にjavaファイルを作成したり、packageに合わせてディレクトリを作成する必要がありますが、Groovyでは特にそのような制約はありません。そのため、Spring Bootに必要なクラスを一つのGroovyファイルにまとめることができます。

今回はsrc/main/groovy/HelloApp.groovyというファイルを作り、その中に必要なクラスをまとめていきます。

package hello

// importは省略

@Configuration
class SlackApp {
    @Bean
    App initSlackApp(){
        def app = new App()
        app.command('/hello', (req, ctx) -> ctx.ack('Whats up?'))
        return app
    }
}

@InheritConstructors
@WebServlet('/slack/events')
class SlackAppController extends SlackAppServlet {}

@SpringBootApplication
@ServletComponentScan
class Application {
    static void main(String[] args) {
        SpringApplication.run(Application, args)
    }
}

src/main/resource/application.yamlに設定ファイルも作成しておきます。

logging.level:
  com.slack.api: DEBUG
server:
  port: 3000

ソースコードや設定はこちらを参考にしました。

Slackとの接続

Slackと接続するには、事前にSlack側でSlack Appの作成や権限の設定、必要なTokenの取得などを行う必要があります。このあたりを参考にSlash Commandの設定を行います。今回はSlash Commandしか使わないので、SIGNING_SECRETのみ用意します。

取得後は、以下のコマンドでアプリケーションを起動させます。

SLACK_SIGNING_SECRET=xxxx....
./gradlew bootRun

別のターミナルからngrokを起動し、3000番ポートをngrokサービスにフォワードします。

ngrok http 3000

最後にフォワードされたURLをもとにSlash CommandのRequest URLを設定(例: https://xxxxxx.ngrok.io/slack/events)すれば接続は完了です。

試しにslack上で/helloを叩くとレスポンスが返ってきます。

参考