Play Framework 2.8 (Java) からSlackに投稿する

# 概要

Play Framework 2.8でSlack APIを使用する方法です。
シンプルな投稿機能の実装をします。

SlackのWeb APIを簡単に利用できるSlack公式のJava用クライアントを使います。

公式の記事にある内容をPlay Frameworkで実践しようという趣旨の記事です。
https://slack.dev/java-slack-sdk/guides/ja/web-api-basics

# 下準備

### プロジェクトの作成

省略します。
Play FrameworkのJava用テンプレートを使い、空のプロジェクトを用意してください。

### 依存性の記述

SlackのWeb APIをJavaで楽に扱うためのクライアントをSlack公式が用意しています。
これを先程作ったプロジェクトにインストールしていきます。

↓セットアップについての公式ページ
https://slack.dev/java-slack-sdk/guides/ja/web-api-client-setup

公式ページではMavenを使ってプロジェクトにインストールする方法を紹介していますが、Play FrameworkではMaven2を使用しており、簡単な記述でインストールを行うことができます。

プロジェクトファイルの一番上のディレクトリにある```build.sbt```を開き、以下の依存性を追記します。

```sbt:build.sbt
libraryDependencies += "com.slack.api" % "slack-api-client" % "1.0.8"
```

依存性の内容は、左からグループID・アーティファクトID・バージョンですので、必要に応じて変更してください。

Play Frameworkプロジェクトでの準備は以上です。
初回のコンパイル時にクライアントのダウンロードやインストールも自動でやってくれます。
あとはjavaファイル中のimport文でクライアントを使えるようになります。

### トークンの取得

今度はSlack側の設定です。
トークンはSlackのワークスペースから発行されるもので、いわば「それを持ってたらSlackに投稿してもいいよ、という許可証」です。
この文字列があればSlackに投稿できるようになります。

詳細は省きますが、

- 新しいアプリケーションの作成
- 必要なトークン情報
- ワークスペースへのアプリケーションの追加

をすればトークンの発行が可能です。

トークンの種類として、ボットとユーザーがありますが投稿を試すだけならどちらでも構いません。
スコープには```chat:write```が必要です。

以下の公式ページを参考にしてみてください。

https://slack.com/intl/ja-jp/help/articles/115005265703-%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90
https://slack.com/intl/ja-jp/help/articles/215770388-API-%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E7%94%9F%E6%88%90%E3%81%A8%E5%86%8D%E7%94%9F%E6%88%90

### チャンネルの設定

投稿したいチャンネルにアプリケーションを追加してあげましょう。
Slackのアプリケーションから設定できます。

# 実装

今回は簡単のために、起動時に実行される```HomeController.java```のindexメソッドに記述しています。
実際のアプリケーション作成のときはモデルかなんかに書きましょう。

```java:HomeController.java
package controllers;
import com.slack.api.model.Message;
import play.mvc.*;
import com.slack.api.Slack;
import java.io.IOException;
import com.slack.api.methods.response.chat.ChatPostMessageResponse;
import com.slack.api.methods.MethodsClient;
import com.slack.api.methods.request.chat.ChatPostMessageRequest;
import com.slack.api.methods.SlackApiException;

public class HomeController extends Controller {

  public Result index() {
    Slack slack = Slack.getInstance();
    String token = "トークンの文字列";
    MethodsClient methods = slack.methods(token);
    ChatPostMessageRequest request = ChatPostMessageRequest.builder().channel("#general").text(":wave: Hi from a bot written in Java!").build();

    try {
      ChatPostMessageResponse response = slack.methods(token).chatPostMessage(request);
      if (response.isOk()) {
        Message postedMessage = response.getMessage();
        System.out.println("成功");
      } else {
        String errorCode = response.getError();
        System.out.println("失敗1"+errorCode);
      }
    } catch (SlackApiException requestFailure) {
      System.out.println("失敗2");
    } catch (IOException connectivityIssue) {
      System.out.println("失敗3");
    }
    return ok(views.html.index.render());
  }

}
```

トークンの文字列の部分には取得したトークンが入っていれば大丈夫です。
公式ページでは、環境変数に格納したトークンを取得する方式を取っています。
直接入力するのは、汎用性の観点でもセキュリティの観点でもアウトなので実際のアプリケーションでは**絶対に**やめましょう。

流れとしては、

- Slackインスタンスの初期化
- トークンの格納
- リクエスト生成用のインスタンスにトークンをセット
- リクエストの生成
- （リクエストを送って）レスポンスを受け取る（例外処理付き）

って感じです。

Slack Web APIに沿ってリクエストを生成しているので、どうやってリクエストを生成しているかはわかりやすいと思います。

例外処理を書かないと実行時に注意されるので、公式ページを参考に書いてください。

うまくいけば実行時にコンソールに```成功```と表示され、指定したチャンネルに投稿されると思います。
失敗してしまう場合は公式ドキュメントを参考にエラーを確認してみてください。
自分の場合ははトークンがちゃんと設定できていなかった、投稿チャンネルの指定が間違っていたというエラーを吐かれていました。

# まとめ
- Slack APIのクライアントをPlay Frameworkで利用できるようにした。
- Play FrameworkからSlackにメッセージを投稿した。