Help us understand the problem. What is going on with this article?

Darkを使用して、Slack App作成する

はじめに

本書では、Darkを使用したSlack Appの作成を行う。Darkに関しては、「新たな開発プラットフォーム "Dark/Darklang" を実際に触ってみて」を参考して頂ければと思う。

Darkでは、トレース駆動開発を駆使する事で、ビジネスロジックのみを記述するだけで開発が可能であるので、その点も注目して貰えたらと思う。

1. Slackアプリケーションの開発

Slack Appの開発を始めていく。アプリケーション名はsampleAppとした。

今回は、簡単にスラッシュコマンド/testを入力するとワニの画像が返されるようにする。

1.1. キャンバスの作成

開発する為にキャンバスを新規作成する。

アカウントには、darklang.com/a/USERNAME-CANVASNAMEからアクセスできる。今回は、Slack Appを作成するので、darklang.com/a/USERNAME-slackappと名付けた。

入力後にアクセスすると、キャンバスが立ち上がる。

1.2. Slackコマンドの追加

次に、Slack APIからSlack Appを新規作成する。

アプリケーションをワークスペースにインストールする為には権限が必要である。その為、筆者は独自のワークスペースを作成し、その中にSlack Appをセットアップする事にした。

Slackコマンドに/testコマンドを追加し、USERNAME-CANVASNAME.builtwithdark.com/testでリクエストURLを指定する。今回は以下の様に設定した。

Screen Shot 2020-03-27 at 1.54.13.png

必要に応じて、ここでSlackbot等の他の機能を追加できるが、今回はこれをベースに開発していく。

1.3. OAuthのセットアップ

1.3.1 リダイレクトURLの設定

アプリを配布できるようにする為、OAuthをセットアップする。Slack APIのOAuth & Permissionsから、リダイレクトURLを追加する。

Screen Shot 2020-03-24 at 10.55.51.png

DarkではOAuthの使用する際は以下の形式でURLを指定する必要があるので、それに則って記述する。

https://USERNAME-CANVASNAME.builtwithdark.com/OAUTH-REDIRECT

URLを保存後、Settings/Manage Distributionから共有可能なURLをブラウザのアドレスバーにコピーする。アクセスするとアプリケーションをインストールできるのでインストールする。この段階ではアクセスしてもバックエンドのロジックは何も記述していない為、以下の様なエラーが表示される。

404 Not Found: No route matches

しかし、この様な振る舞いを行う事でDarkは痕跡を確認する事ができ、それをトレースする事で開発を行う。

筆者自身、このトレース駆動開発にはまだ慣れていない部分もあるが、敢えてこの様に異常検知を起こす事でアクセスに必要な情報をトレースして開発を行う事がDarkを使用する上での1つのメリットである。

Darkのキャンバス(https://darklang.com/a/USERNAME-slackapp)に戻り、セクションを確認してみると404セクションに/oauth-redirectが表示されている事が確認できる。

Screen Shot 2020-03-23 at 4.41.38.png

この404にある/oauth-redirectをプロダクショントレースしてバックエンドを構築していく。+をクリックすると、GETメソッドのOAuthリクエストに応答するHTTPハンドラを作成する。

Screen Shot 2020-03-23 at 5.11.57.png

作成したものを確認してみると、SlackがDarkアプリに対して行ったリクエストを示すトレースが表示されている。ここには、Slackに返答する際に必要なコードが含まれる。(一部個人情報を含む為、加工している)

1.3.2. トークンの取得

Slackアプリに送信する為にはclient_idclient_secretが必要である。これらの情報は、SlackのSettings/App Credentialsから確認する事ができる。

Screen Shot 2020-03-27 at 1.58.55.png

確認後、作成した/oauth-redirectハンドラにコードを記述していく。ここで、client_idclient_secretをペーストする際は最初に文字リテラル"を入力してからでないと、Darkではフロート型の様に扱われ、全ての文字列がペーストされない。

Screen Shot 2020-03-27 at 0.16.49.png

また、実行すると偶にoauth_authorization_url_mismatchと返される場合があるが、それはOAuthの認証URLが異なるからである。どちらのURLを使用するかは、Settings/App CredentialsのClient IDを見ると右下に小さく書いているので、それで判断する事が可能である。

# どちらかのURLを使用する
https://slack.com/api/oauth.access
https://slack.com/api/oauth.v2.access

※ 今回、筆者はoauth.v2.accessを使用しているが、oauth.v2.accessからレスポンスで返されるJSONの仕様が変更されている。その為、oauth.accessを使用する場合は、後述で説明するトークン保存時のパラメータの指定方法が異なるので注意して欲しい。

これにより、Slack APIの一部(oauth.v2.access)が呼び出され、リクエストされたSlackにアクセス可能になる。実行すると、正しくレスポンスが返されればteam.idaccess_tokenが取得できる。

しかし、コードの有効期限が切れると以下の様なエラーが表示される。その場合は、面倒だが再度ブラウザから共有リンクを開き、認証を行う必要がある。

Screen Shot 2020-03-23 at 21.28.21.png

1.3.2. トークンの保存

次に、取得したトークンとデータストアに保存する。アドレスバーから新しいデートストアを作成し、保存するフィールドにスキーマを設定する。bot_tokenoauth.v2.accessを使用する場合は不要である。

Screen Shot 2020-03-23 at 21.59.02.png

データストアの作成が完了すれば、/oauth-redirectにロジックを記述していく。

Screen Shot 2020-03-27 at 0.15.31.png

1.4. アプリケーション機能の構築

ワークスペースにアプリケーションをインストールしたので、Slackを起動して確認してみる。設定したスラッシュコマンド/testを入力してもまだロジックが実装されていない為、エラーが表示される。

Screen Shot 2020-03-23 at 22.50.43.png

しかし、このトリガーからDarkの404セクションにルートが表示されるので、それをトレースして機能を構築していく。404セクションからエンドポイントを作成するとトレースを操作可能である。

Screen Shot 2020-03-23 at 22.43.57.png

今回のアプリケーションでは以下の様に実装した。リクエストURLを取得し、そのリクエストに対してテキストを返す。

Screen Shot 2020-03-27 at 0.31.16.png

1.5. 動作検証

実際にSlack側で動作させてみる。/testと入力すると、Darkで設定したテキストと成功した事を証明するJSONが出力された事が確認できる。

ezgif.com-video-to-gif (3).gif

JSONの出力を非表示にしたい場合は、Http::respondWithTextを使用して200コードに対して空白を指定すると表示されなくなる。

Screen Shot 2020-03-27 at 0.44.35.png

以上で、DarkでSlack Appの実装する事ができた。

2. データストアを活用したアプリケーションの実装

応用として、データストアに保存された50音を行ごとにランダムに出力する様に実装してみる。

まず、RandomMessagesと言うデータストアを用意し、フィールドにmessageと言うスキーマを用意する。そこにREPLでデータストアに対して登録を行うaddMessagesを用意する。続けて、データストアに登録された情報を確認する為にREPLでsetMessagesも用意した。

Screen Shot 2020-03-27 at 1.09.40.png

次に、先程使用した/testのロジックを一部修正し、その結果をSlack側に送信する。

Screen Shot 2020-03-27 at 1.11.13.png

追加した変数の概要は以下の通りである。

変数名 内容
allMessages RandomMessagesに保存されている情報を全て取得し、配列に保存する。
messageCount 配列の長さを取得する。
messageCountLessOne 配列は0から始まる為、1除算する。
index ランダム値を取得する。範囲として0からmessageCountLessOneを指定する。
message indexの値に該当する情報をデータストアから取得する。

実際に動かしてみると、以下の様にランダムに結果が表示される事がわかる。先程、実装したHttp::respondWithTextによりJSONが出力されない事も併せて見て貰うと良い。

ezgif.com-video-to-gif (4).gif

3. 最後に

今回は、DarkでSlack Appの実装を行った。筆者は、Slack Appの開発は初めてであった為、Dark以外でいくつか躓く点が多かったのだが、開発した事のある方であれば比較的容易に開発できるのではないだろうか。実際に今回開発した全体図を見ると、非常に少ないコードで開発できている事がわかる。

Screen Shot 2020-03-27 at 1.41.55.png

また、Darkでは定義した変数名をクリックすると即座に値を確認できるので、意図した値が返ってきているかどうかを知ることができる。これにより、コードを記述している間も修正箇所に気づきやすいので、逐一デバッグを行い確認する必要はない。

最後に開発を通して発見した事だが、Darkで日本語文字列を入力しようとすると変換をする際にスペースも誤入力されてしまう様である。この点に関しては、今後の改善希望として報告しておこうと思う。

【2020/03/27 03:43追記】
ベータ版と言う事もあり、現段階ではテキスト構成のサポートがまだ十分ではないとの事。回避策として、もし日本語入力を行いたい際はコピー&ペーストを使用して入力して欲しい。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした