DeepL を Slack から使おう！

## DeepL Pro 日本上陸

DeepL Pro のアナウンスが話題になっていますね！

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/6aa4783b-d097-cb2c-50f8-eb3192e857b9.png">

* https://twitter.com/DeepLcom/status/1272654474771927041
* https://www.deepl.com/blog/20200615.html

DeepL の Translate API の仕様は非常にシンプルで、よいですね。早速、簡単ですが、とても実用的な Slack 連携を作ってみました。

このアプリは Heroku に DeepL の認証キー（Authentication Key）を環境変数に設定した状態でデプロイすれば、どのワークスペースでもすぐに使い始められます。

実装は https://github.com/seratch/deepl-for-slack にあります。役に立ったらスターを増やしてください！この README だけで、どうやればよいかわかるという方はそのままやってみてください。

この記事では、アニメーション・スクリーンショットも交えながら、順を追って説明します。数分でできると思うので、試してみてください。

## 準備するもの

* DeepL Pro 開発者向け（for Developers）
* Slack ワークスペース
* Heroku

## DeepL Pro 開発者向け（for Developers）

DeepL のアカウント作成と Pro プランの有効化を行いましょう。

https://www.deepl.com/ja/pro

ここで注意すべきことは、「開発者向け（for Developers）」のプランはブラウザやアプリで翻訳を使えるプランとは 2020 年 6 月時点で別物となっている点です。そのため、もしすでに Pro アカウントを持っていても API の利用には別のアカウントの作成が必要です。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/009b9728-2597-c9b5-09ab-6e87ebf28ba6.png">

正常に登録が完了すると、以下のようにアカウントページに認証キーが表示されます。これを後ほどデプロイするときに使用します。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/0b87ef65-4369-bb20-1af6-4cee8b4d83c9.png">

## Slack アプリの設定（前半）

Slack アプリの設定は二段階で行います。ここではまず前半の設定です。

### Slack アプリを作成

対象の Slack ワークスペースにブラウザでログインした状態で、以下のリンクから Slack アプリをつくります。

https://api.slack.com/apps?new_app=1

Slack アプリというのは Slack のカスタム拡張のようなものです。独自のスラッシュコマンドやショートカットなどのアクションを Slack に追加したり、Slack 内で発生したイベントをリアルタイムで受け取って何か処理をしたりと言ったことができます。

「DeepL 翻訳アプリ」という名前にしてみましょう。Development Slack Workspace は後から変更できない（作り直しになります）ので、間違えないようにしてください。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/fe05b706-cad3-2f4e-41ff-925563655ae5.png">

### 権限を付与

アプリが作成されたら、必要な権限を設定するために左のペインから **Features > OAuth & Permissions** に移動してください。そこで **Scopes > Bot Token Scopes** に移動して、以下を追加します。

* `channels:history` - リアクションがついたメッセージの参照、スレッドに重複なく投稿するための履歴の参照に使用します
* `groups:history` - 同上（private チャンネルで使用しないなら不要です）
* `chat:write` - 翻訳結果をチャンネルに書き込むために使用します
* `reactions:read` - リアクションがつけられたイベントをサブスクライブするために使用します

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/20e05acc-8820-5fde-9900-364aef7fd354.gif" width=600 />

正しく設定できている場合は、以下のようになっているはずです。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/73d21dc0-f35d-625d-5ff2-91e79addda06.png">

### ボットの設定

ボットの名前を設定します。左のペインから **Features > App Home** に移動してください。そこで **App Display Name** の **Edit** ボタンをクリックして、設定します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/e3acabb9-e505-cdcd-29bd-d696ff03f330.gif" width=600 />

名前は何でも大丈夫ですが、このように「翻訳くん」のような馴染みやすい名前をつけてもよいでしょう。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/d9c6b37e-3945-6470-c6b2-d7b6df53faa9.png">

### Slack ワークスペースにインストール

この状態で一度ワークスペースにインストールして bot token を取得します。左のペインから **Settings > Install App** に移動してください。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/332dfc4b-4bcf-c7e0-3863-a909b6c75e9e.gif">

これによって `xoxb-` から始まる **Bot User OAuth Access Token** が取得できました。

ちなみに、このトークンは漏洩するとまずいものなのですが、このアニメーションでは思い切り映り込んでしまっていますね。もし、このように意図せず（今回は意図的ですが）公開してしまった場合は **OAuth & Permissions** のページの最下部から Revoke することができます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/f23720f6-63da-785a-d000-1dee3a2948e4.gif">

が、もちろん、私のこのデモ以外では revoke する必要はありませんので、発行された token をそのままお使いいただけます。

ということで、Slack アプリの設定の前半はこれで完了です。

## Heroku にデプロイ

Heroku のアカウントは設定済の前提で説明します。

アプリのリポジトリは https://github.com/seratch/deepl-for-slack です。カスタマイズしたい場合は自由に fork してお使いください。	

README に Heroku へのデプロイボタンがあるので、こちらを使ってやってみましょう。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/8a70c126-d1cc-db17-72c9-539214cbfee2.gif">

すると `app.json` の内容を設定するだけで初回デプロイが行える画面に遷移します。

このような感じで設定します。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/3ddaaa36-b7fe-dc91-ef1a-661bddd3dc4e.png">

重要な設定項目について説明しておきます。

* `DEEPL_AUTH_KEY`: これは https://www.deepl.com/pro-account.html で確認できる認証キーです
* `DEEPL_RUNNER_LANGUAGES`: 以下のうち、モーダルでの検索実行時にプルダウンに含めたいものをその順序とともにカンマ区切りで指定してください。この記事の例では `ja,zh,en` としたので、日本語、中国語、英語の三つがこの順で表示されます。
    * "de" - ドイツ語
    * "en" - 英語
    * "fr" - フランス語
    * "it" - イタリア語
    * "ja" - 日本語
    * "es" - スペイン語
    * "nl" - オランダ語
    * "pl" - ポーランド語
    * "ru" - ロシア語
    * "zh" - 中国語

* `SLACK_BOT_TOKEN`: これは先ほど Slack ワークスペースへのインストール時に発行された **Bot User OAuth Access Token** です。Slack アプリの管理画面で、左のペインから **Settings > Install App** に移動した先で参照できます。
* `SLACK_SIGNING_SECRET`: これは Slack アプリの管理画面で **Settings > Basic Information > App Credentials > Signing Secret** にアクセスすると参照できます。

準備ができたら **Deploy App** ボタンを押しましょう！

デプロイが正常に完了すると、以下のような表示となります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/36c735bb-9b9e-08b7-52c1-47b17da4fb6f.png">

必要に応じて **Manage App** ボタンから遷移した先で Dyno Type を変更しておきましょう。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/8256cedf-eae7-6200-e496-3e9d18f4855a.png">

`https://{あなたの app name}.herokuapp.com/` という URL が払い出されていますので、これを Slack アプリ設定の後半で使用します。

## Slack アプリの設定（後半）と動作確認

あと一息です！今デプロイされた Slack アプリサーバーの URL を Slack 側に設定します。

https://api.slack.com/apps で先ほど作ったアプリの管理画面へ移動します。

## ショートカットを有効化

ショートカットというのは、メッセージ投稿フォームに表示されている稲妻マークのアイコンから起動できるアクションです。検索窓で名前を入れて呼び出すこともできます。


左のペインから **Features > Interactivity & Shortcuts** へ遷移して、以下の画面イメージのように設定してください。注意点としては `https://{あなたの app name}.herokuapp.com` に続いて `/slack/events` というパスが必要です。この URL が間違っていると動作しないので注意して設定してください。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/6b397c38-c978-4ad1-be80-d615dbba6631.png">

ショートカットの設定画面では **Global** の方を選択し、以下のような内容で設定してください。 **Callback ID** は必ず「**deepl-translation**」にしてください。それ以外の項目は任意の値で OK です。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/becfd949-318c-8193-ee22-967d1a792456.png">

最後にこの画面では **Save Changes** という緑色のボタンを押さないと保存されないので、忘れないように押してください。

そして、この管理画面で別の画面に遷移するとこのような黄色いバナーが表示されるようになっています。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/f9802773-c1cb-5c4f-29e1-91fbf09fd65d.png">

これは「ワークスペースに再インストールしないと新しく設定した内容は有効化されません」ということを意味します。 **Settings > Install App** からもう一度このアプリをインストールしてください。

インストールが終わったら、Slack のワークスペースを開いて、動作確認してみましょう。メッセージ投稿画面の稲妻マークからも

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/16ed653d-690d-048c-a036-6ca558f73e60.png">

検索窓からも、このショートカットが呼び出せるようになっているはずです。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/d2d1a3fb-b955-1734-196f-131f94fc614a.png">

実際に試してみるとこのようになります。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/5523e52b-62dd-6bf4-2005-58523f767bb6.gif">

このデモを撮っていて気付いたのですが、UI 上の文言が一部日本語になっていないところを、デプロイ時の設定で変更できるようにするとよりよいですね（プルリクエストをお待ちしています！）。

## リアクションがついたイベントのサブスクライブ

これは、チャンネル内のメッセージに国旗のリアクション絵文字がついたときに、対応している言語であれば翻訳結果をその元のメッセージのスレッドに投稿するという機能です。

これは元々は [reacjilator](https://github.com/slackapi/reacjilator) というデモアプリがオリジナルのアイデアです。実際にこの reacjilator を使っている方もたくさんいるのですが、今回はそれと同等のものを DeepL API を使って実装してみました（reacjilator は Google の API を使っています）。

設定内容としては以下のように機能を有効にして Request URL を設定し、bot events の方に `reaction_added` を追加し **Save Changes** ボタンを押して保存するだけです。

Request URL は先ほどのショートカットの時と同じものを使用してください。再掲ですが `https://{あなたの app name}.herokuapp.com/slack/events` のような URL になります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/758fe89d-c7dc-8366-54a1-2022ba6cac50.png">

これがうまくいったら、今回作った Slack アプリのボットユーザーをテストするチャンネルに招待してください。

そして、

>In functional programming, a monad is a design pattern that allows structuring programs generically while automating away boilerplate code needed by the program logic. Monads achieve this by providing their own data type (a particular type for each type of monad), which represents a specific form of computation, along with one procedure to wrap values of any basic type within the monad (yielding a monadic value) and another to compose functions that output monadic values (called monadic functions).

という英文をチャンネルに投稿して :flag_jp: `:flag-jp:` のリアクション絵文字をつけてみましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/ae0a647e-a854-1882-c78e-a6a6ebdc6f8b.gif" width=600/>

すると上記のように

>関数型プログラミングでは、モナドとは、プログラム・ロジックに必要な定型的なコードを自動化しながら、プログラムを汎用的に構造化することができる設計パターンのことです。モナドは、特定の計算形式を表す独自のデータ型（モナドの型ごとに特定の型）と、モナド内で任意の基本型の値をラップする（モナド値を生成する）手順と、モナド値を出力する関数を構成する（モナド関数と呼ばれる）手順を提供することで、これを実現します。

という翻訳が投稿されます。便利ですね！

### アプリの見た目を調整

最後にアプリの設定画面で、アイコン画像など設定しておきましょう。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/368ff141-c074-a794-5968-fa00367fe62b.png">

Slack 上での見た目がよりそれらしくなるかと思います。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/778e6b50-079d-e4ea-a331-8759e9523aaa.png">

## お試しください！

この記事を読みながらやれば、どなたでもインストールできるはずです！

また https://github.com/seratch/deepl-for-slack への機能追加などのプルリクエストは大歓迎ですし、フォークして自由にいじっていただいても OK です。

それではまた！（回头见 / See you soon!）