Slackアプリを作る〜サーバーレスでサクッと〜

# はじめに
こんにちは！株式会社80&Companyの技術広報です。
弊社の開発部署では毎週火曜日の朝9:30から社内勉強会を行なっています。

今回の記事は、バックエンド開発や情シスを行なっているエンジニアが社内勉強会で「Slackアプリを作る〜サーバーレスでサクッと〜」というテーマでSlackアプリの導入方法について発表したものを紹介します。

Slackアプリの導入に興味のある方は、ぜひ参考にしてみて下さい♪

# 読者の対象
* Slackアプリについて知りたい方
* Slackアプリの導入を検討している方

# テーマ選定の理由
弊社では、その日1日何かしらお世話になった従業員に対して、感謝を送り合う「タコス制度🌮」というものがあります。
制度の内容は、Slack内のタコス制度用のチャンネルで、お世話になった従業員をメンションして感謝のメッセージとタコススタンプを押すというものです。
その際に「[HeyTaco](https://heytaco.com/)」というピアボーナス用アプリを用いることによって、タコスをたくさんもらった方が計測されます。

そういったタコス制度用アプリを発表者が作り直す過程で、Slackアプリの作成過程に触れたため、今回発表に至ったそうです！

# Slackアプリについて！ざっくり概要
最初にSlackアプリの概要について、ざっくり説明します。
Slackでのアプリ使用について、より詳しく知りたい方は、ぜひ[こちら](https://slack.com/intl/ja-jp/help/articles/360001537467-Slack-%E3%81%A7%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E4%BD%BF%E7%94%A8%E3%82%AC%E3%82%A4%E3%83%89)のSlackヘルプセンターガイドラインをご覧ください🙌

## Slackアプリの機能について
最初にSlackアプリの機能について大まかなものを説明します。
Slackアプリの活用方法としては下記の6点があります。

**1.ホームタブやメッセージタブ**
アプリのホームタブでは、アプリ情報の表示やアプリの設定を行います。
メッセージタブでは、アプリから届いたメッセージを表示します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/c4a45656-f82b-27c9-1b6e-da4c1c141fda.png"  width="500" height="130" />

**2.インタラクティブなUI（モーダルやフォームなど)**
文字の入力を行うフォームや画面をスクロールできるモーダルなどが存在し、ユーザーがマウスやキーボードを入力して操作を進めていくことができます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/429f5a0c-3d04-f02e-d50c-7d30d636d34b.png"  width="500" height="100" />

**3.アプリのショートカットやスラッシュコマンド**
Slackでアクションを実行するために使用可能なショートカットがあります。
フォーム入力の左側にある+(プラス)アイコンをクリックして、アプリの[ショートカット](https://slack.com/intl/ja-jp/help/articles/360057554553-Slack-%e3%81%ae%e3%82%b7%e3%83%a7%e3%83%bc%e3%83%88%e3%82%ab%e3%83%83%e3%83%88%e3%81%a7%e3%82%a2%e3%82%af%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e3%81%99%e3%81%b0%e3%82%84%e3%81%8f%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b)または[スラッシュコマンド](https://slack.com/intl/ja-jp/help/articles/201259356-Slack-%e3%81%ae%e3%82%b9%e3%83%a9%e3%83%83%e3%82%b7%e3%83%a5%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89)を検索します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/b8fce50b-55ee-8605-7173-0ed80ce3817e.png"  width="500" height="100" />

**4.ボットユーザー**
ボットユーザーと呼ばれるユーザーを登録することができます。
ボットユーザーからDMでメッセージが届いたり、チャンネル内で投稿したメッセージを目にすることができます。
ボットユーザーのより詳しい説明は、ぜひ[こちら](https://api.slack.com/bot-users#bots-overview)をご覧ください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/09195468-9591-4112-3690-eb6e166c9564.png"  width="500" height="100" />

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/3473f051-c62e-7ce4-1f50-eeb8db29a2d1.png"  width="500" height="100" />

**5.ワークスペース内イベントのサブスクライブ**
アプリ開発者は、Slackアプリを無料で利用できるようにするか、サービスの有料アカウントを必須にするかを選択できます。
アプリ開発者がアプリの料金プランの要件を提出している場合、その情報はSlack Appディレクトリのアプリページに表示されます。

**6.Webhookを受け取ってコンテンツを通知**
Webhookを利用して、コンテンツの更新時にSlackに通知を行うことができます。
操作手順を紹介したチュートリアルを知りたい方は、ぜひ[こちら](https://www.newt.so/docs/tutorials/slack-notification-with-webhooks)をご覧ください。

## Slackアプリ概念図
下記の画像は、Slackアプリの概念図です。
Slackアプリの表面的な様相はSlack Appが利用されています。
詳しいロジックはApp Serverに入っており、Slack apiを介してやりとりを行っています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/876228fa-a8f8-99ec-87d4-4965013b6f9e.png"  width="500" height="130" />

## Slack APIの概要
上記のSlackアプリ概念図でご紹介したSlack APIですが、SlackアプリはこのSlack APIによって様々な種類のデータの読み取り、書き込み、更新へのアクセスを行うことができます。
Slack APIは大きく分けて３種類存在します。

* [Web API](https://api.slack.com/methods)
    * Slack APIにリクエストを送ってSlackワークスペースを操作したり情報を取得するもの
* [Events API](https://api.slack.com/events)
    * Slackワークスペース上でのイベントを送ってくれるもの
* Interactivity系の通信
    * Interactive Componentの操作情報を送ってくれるもの(ショートカットやスラッシュコマンドなど）
  
# Slackアプリの権限周り
Slackアプリの裏側では、Slack APIへのアクセス管理を行うためトークンを発行したり、アプリとSlack間でアクセスできる情報範囲を選択するなど、権限周りの動作が多く行われています。
今回は**Access tokenの発行**と**権限スコープ**について説明します。
## Access token について
Slackアプリは、OAuthを使用してSlackのAPIへのアクセスを管理しています。
アプリがインストールされるとトークンが発行され、そのトークンを使い、アプリはAPIメソッドを呼び出すことができます。
Slackアプリで使用できるトークンには、下記の3種類があります。
* ユーザートークン
    * アプリをインストールまたは認証したユーザーに成り代わって、APIメソッドを呼び出すことができます。
1つのワークスペースに複数のユーザートークンが存在する可能性があります。
* ボットトークン
    * ボットユーザーに関連付けられ、1つのワークスペースでは、最初に誰かがそのアプリをインストールした際に一度だけ発行されます。
どのユーザーがインストールを実行しても、アプリが使用するボットトークンは同じです。
* アプリレベルトークン
    * 全ての組織(とその配下のワークスペースでの個々のユーザーによるインストール)を横断して、アプリを代理するものです。
アプリレベルトークンは、アプリのWebSocketコネクションを確立するためによく使われます。

## 権限スコープについて
Slackワークスペースを安全に保つために、アプリがSlackとどのように連携して動作するかを理解することが大切です。
権限スコープは、Web APIメソッドの呼び出しやEvents APIのイベントの受信といったSlackでの機能を実行する権限をアプリに付与するために使用されます。

ユーザーはアプリのインストールフローに従って進むと、アプリがリクエストするスコープへのアクセスを許可する必要があります。

それぞれのSlackアプリには独自の[権限スコープ](https://api.slack.com/scopes)のセットがあり、Slackでアクセスできる情報と、その情報の使用方法が決められています。

# Slackアプリ開発で使えるツール
Slackアプリ開発を行った際に、アプリのレイアウト作成や開発で用いられたフレームワークについて説明します。
## UI周りについて
レイアウト周りを直感的に意識しつつ、簡単に構築ができる[Block Kit Builder](https://app.slack.com/block-kit-builder)というツールがあります。
左画面がレイアウト画面を表示し、右画面がJSON形式で構成されたブロックを表示しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/3afb1ce5-e697-4c27-9d56-c1dc50e73e77.png"  width="600" height="430" />

右画面で新たにブロックを加えることができ、直感的にレイアウトを作ることができます。
また少しコードを消すと、左側でエラーが表示されます。
リアルタイムでレイアウトを調整できるので、とても便利なツールです👏

### 主要なUI
また、これらのツールにより再現できるレイアウト形式は大きく3種類あります。
* Messages
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/57f7354c-5cbe-4a5f-e278-e931bb83dcd0.png"  width="300" height="100" />

* Modals
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/63b81f83-b649-bb44-faed-4a1692524a63.png"  width="300" height="100" />

* App Home
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/1f39ba05-850f-b026-970c-d148e3a5a26e.png"  width="300" height="100" />

また、レイアウトごとにテンプレートが存在します。
**Use Message Template**というボタンを押すとレイアウトのブロックコードをコピーできます。
このコピーしたコードを右画面のJSON形式で構成されたブロックに追加すると、そのまま左画面にレイアウトが反映されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/2118484c-11ac-42f3-7285-7caeb9680462.png"  width="300" height="100" />

## Boltについて
Slackアプリの開発を行う際に、**Bolt**と呼ばれるSlack API Client + スラッシュコマンド用のレシーバを兼ね備えた、Slackアプリ開発用の公式フレームワークが使用されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/c518fa51-fd8c-8642-2066-13c4f6e92e6a.png"  width="300" height="100" />
JavaScript(Node.js)、Python、Javaでの利用が可能です。

**Bolt Bolt logo for JavaScript**

https://github.com/slackapi/bolt-js

**Bolt for Java**

https://github.com/slackapi/java-slack-sdk

**Bolt logo for Python**

https://github.com/slackapi/bolt-python

上記に各言語での利用方法が記載されているため、ぜひお試しください！

**Bolt**は、上記のSlackアプリ概念図で記載された**App Server**にインストールして使用されます。
公式の[入門ガイド](https://slack.dev/bolt-js/ja-jp/tutorial/getting-started)があるため、こちらのガイドラインをぜひご参考に🙌

# Slackアプリを作る
では、発表者が実際に作成したSlackアプリの構成について、ご紹介します。
## どんなアプリにするか
* 「HeyTaco」のようなピアボーナス用アプリ
* タコス以外の絵文字も使いたい
* 絵文字ではなくて、特定の文字もカウントできるとよい
* リアクションもカウント出来たら面白そう？

## 機能要件
* 誰かへのメンションが含まれていて、かつ特定のキーワードを含むメッセージを集計する(誰から誰に、キーワードがいくつ含まれるか）
* 特定のキーワードを受け取った時にアプリから通知される
* リアクションを集計すす(誰から誰に、どの絵文字か）
* App Homeから集計データ(受け取り分)を確認できる

## 使用するサービス
* AWS Lambda
サーバー管理しなくてもコードが実行できるサービス

* AWS DynamoDB
フルマネージドでサーバーレスのkey-value型のNoSQLデータベース

## 構成
Slackから誰かがコメントやリアクションをした際に、Lambdaにイベントが飛んできます。
Lambda上でBoltを使ってロジックを組んでいきますが、受け取ったデータをDynameDBデータベースに保存します。
Slack側でAppホームを開いた際に、開いた旨を伝達するイベントをLambdaに送り、データベースからデータを収集して、またWeb APIを叩き、Slack側にデータを返します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/550020ff-ff33-5b12-6790-0f2970876991.png"  width="600" height="430" />

## 完成したアプリの様子
**1.タコススタンプを相手に送ります。**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/7f785db1-442e-237e-9f11-afd49ec90a56.png"  width="600" height="430" />
**2.するとデモアプリによって、タコススタップをもらった数が計測されます。**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/3f652d0d-a573-a58b-143c-aec00c625bdf.png"  width="600" height="430" />
**3.先ほどのスレにリアクション✅ボタンを押します。**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/64782a5b-2fc9-ad84-3af4-e638f1e3f84f.png"  width="600" height="430" />
**4.Slackアプリのホームにリアクション✅ボタンが計測されます。**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/2d8b14d9-e5a1-47b8-80a5-4f079b558d40.png"  width="600" height="430" />

[HeyTaco](https://heytaco.com/)のようなピアボーナス用アプリができましたね😊

# 最後に
今回は、弊社社内勉強会で発表された「Slackアプリを作る〜サーバーレスでサクッと〜」について扱いました。
今後も継続的に80&Companyでの社内勉強会の取り組みを発信していきます！
[Qiita Organization](https://qiita.com/organizations/80andco)や[Twitter](https://twitter.com/80andcoDev)公式アカウントのフォローもよろしくお願いいたします！
最後まで読んでいただきありがとうございます！

# 参考文献
https://heytaco.com/

https://slack.com/intl/ja-jp/help/articles/360001537467-Slack-%E3%81%A7%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E4%BD%BF%E7%94%A8%E3%82%AC%E3%82%A4%E3%83%89

https://slack.com/intl/ja-jp/help/articles/360057554553-Slack-%e3%81%ae%e3%82%b7%e3%83%a7%e3%83%bc%e3%83%88%e3%82%ab%e3%83%83%e3%83%88%e3%81%a7%e3%82%a2%e3%82%af%e3%82%b7%e3%83%a7%e3%83%b3%e3%82%92%e3%81%99%e3%81%b0%e3%82%84%e3%81%8f%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b

https://www.newt.so/docs/tutorials/slack-notification-with-webhooks

https://api.slack.com/methods

https://api.slack.com/events

https://api.slack.com/scopes

https://app.slack.com/block-kit-builder

https://github.com/slackapi/bolt-js

https://github.com/slackapi/java-slack-sdk

https://github.com/slackapi/bolt-python

https://slack.dev/bolt-js/ja-jp/tutorial/getting-started