PythonでSlack Appをサクッと作るメモ

最近slack appの作り方を覚えたので、今回は推しの情報収集のためのBotを作りながらメモを残します。
今回は、指定したキーワードを含むツイートを100件集めてwordcoud作成し、Botを通してSlack上に表示します。
言語処理が必要なので、言語はPythonを使います。
なお、wordcloudを生成する部分の実装についての詳細は割愛し、Botの作成 ~ Botを通して通知を送ったり、通知の見た目を整える方法を書きます。
また、複雑なことはしないのでslack appを作成するためのライブラリ等は使用していません。

## 手順
### slack appを作成してtokenを取得する
[slack api](https://api.slack.com/apps)のページで、`Create New App`をクリックし、slack appを作成します。
基本的に`From scratch`を選べば問題ないです。
![image_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533290/ab20e9d3-82f5-caae-3823-37c7c7c14a8f.png)


Slack appが作成できたら、左側のメニューの`OAuth & Permissions`をクリックし、
![image_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533290/4d59f708-513e-3917-8d41-66621327947d.png)


`Scopes`まで下の方にスクロールし、OAuth Scopeを追加します。これは用途によって異なりますが、一方的に通知するだけのBotの場合は`chat:write`だけ追加します。
![image_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533290/8fa970a4-7966-6a79-9641-d3e43cadf761.png)

必要なOAuth Scopeは公式ドキュメントから調べることができます。例えば今回使う`chat.postMessage`なら[こちら](https://api.slack.com/methods/chat.postMessage)から調べることができました。

必要なOAuth Scopeが追加できたら、左側のメニューの`Install App`をクリックして、workspaceにアプリをインストールします。（このスクリーンショットではReinstallと表示されてしまっていますがInstallだと思ってください...🙇‍♀️）
インストールができたら`xoxb~`から始まるトークンをコピーし、通知を実装する際に使用します。
![image_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533290/a976776c-cb2b-5b11-9325-bfb2348ba9f9.png)


ここでBotを導入したいチャンネルが決まっている場合はチャンネルの方にもアプリのインストールをしておくといいかと思います。

### 通知のUIからjsonを構築する
今回はWordcloudの表示（OGPでいいのでリンクを置くだけ）と、Twitterに飛ばすボタンの設置をすることを目指します。
![image_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533290/5f74a7a5-4dde-6753-f2a0-cdd7201c2a71.png)


通知のUIを満たすjsonは[Block Kit Builder](https://app.slack.com/block-kit-builder/)を使うことでインタラクティブに作成することができます。
左側のメニューにあるコンポーネントのようなものをぽちぽちするだけで、UIとjsonに追加したコンポーネントが反映されるので、簡単にjsonを組み立てることができます。
左上にある`Send to Slack`から送信のテストをすることもできます。
![image_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533290/b62c3727-c238-49bb-fb71-80dcf141a91d.png)


### 1で取得したトークンと2で組み立てたjsonを使って、Botから通知を送る
通知を送るリクエストについても公式ドキュメントが参考になります。（`chat.postMessage`なら[こちら](https://api.slack.com/methods/chat.postMessage)）
今回は、トークンをHTTP Authorization ヘッダとして渡し、通知先のチャンネルIDと組み立てたjsonをpostパラメータとして渡します。
以下は`send_message`にwordcloudの画像のパスを渡して通知を送る例です。

```python
import json
from dotenv import load_dotenv
import os
import requests
import datetime

load_dotenv('.env')

class SlackDriver:
  def __init__(self):
    self.token = os.environ['SLACK_TOKEN']
    self.channel = os.environ['SLACK_CHANNEL']
    self.api_endpint = os.environ['SLACK_API_ENDPOINT']
    self.headers = {"Authorization": "Bearer " + self.token, "Content-Type": "application/json; charset=UTF-8"}
    self.twitter_url = os.environ['TWITTER_SEARCH_URL']

  def send_message(self, image_path):
    now_str = now_datetime_str()
    payload = self.build_payload(now_str, image_path)
    data = {
      "channel": self.channel,
      "blocks": payload
    }

    r = requests.post(
      self.api_endpint,
      headers=self.headers,
      data=json.dumps(data)
    )

    r.raise_for_status()
    return

  def build_payload(self, datetime_str, image_path):
    return [
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": ":star:*{}のHwangInYoupの最新情報*:star:\n<{}>".format(datetime_str, image_path)
        }
      },
      {
        "type": "actions",
        "elements": [
          {
            "type": "button",
            "text": {
              "type": "plain_text",
              "text": "Open Twitter",
              "emoji": True
            },
            "url": self.twitter_url,
          }
        ]
      }
    ]

def now_datetime_str():
  t_delta = datetime.timedelta(hours=9)
  JST = datetime.timezone(t_delta, 'JST')
  now = datetime.datetime.now(JST)
  return now.strftime('%Y年%m月%d日%H時')

```
あとは上記を実行すればいいです。
私の場合は関数をGoogle Cloud Fuctionにデプロイし、Google Cloud Schedulerで定期的に関数を叩くようにしました。

## おわり
今回のようなシンプルなBotだと、一回覚えれば本当に簡単に作れるので楽しいです。公式ドキュメントも充実しています。
Slack Appはまだまだ色々な機能があるので、使いこなして生産性を高めていきたいです。

## 参考
- https://zenn.dev/nyancat/articles/20211219-create-slack-app
- https://app.slack.com/block-kit-builder/
- https://api.slack.com/methods/chat.postMessage
- https://qiita.com/stu345/items/24790710abc571aae3ea