Slack Python SDK で Incoming Webhooks を使おう

## slack-sdk を使おう

「[Python で Slack API や Webhook を扱うなら公式 SDK（slack-sdk/slack-bolt）を使おう](https://qiita.com/seratch/items/8f93fd0bf815b0b1d557)」シリーズの記事です。公式 SDK についての概要、他にも記事がリンクされていますので、[こちらのエントリーページ](https://qiita.com/seratch/items/8f93fd0bf815b0b1d557)にもアクセスしてみてください。

この記事では [`slack-sdk` PyPI パッケージ](https://pypi.org/project/slack-sdk/)を使って Slack の [Incoming Webhooks](https://api.slack.com/messaging/webhooks) を利用したコーディングについて解説していきます。

## Incoming Webhooks でメッセージを投稿

まずはじめに Incoming Webhooks を使うための新しい Slack アプリ設定をつくりましょう。早速、[こちらのリンク](https://api.slack.com/apps?new_app=1&manifest_yaml=_metadata%3A%0A++major_version%3A+1%0A++minor_version%3A+1%0Adisplay_information%3A%0A++name%3A+My+Incoming+Webhooks+App%0Afeatures%3A%0A++bot_user%3A%0A++++display_name%3A+My+Incoming+Webhooks%0Aoauth_config%3A%0A++scopes%3A%0A++++bot%3A%0A++++++-+incoming-webhook%0A)から作成してみてください。

なお、ここで使用する App Manifest は以下の通りです。

```yaml
_metadata:
  major_version: 1
  minor_version: 1
display_information:
  name: My Incoming Webhooks App
features:
  bot_user:
    display_name: My Incoming Webhooks
oauth_config:
  scopes:
    bot:
      - incoming-webhook
```

アプリが作成されたら、そのまま「Install to Workspace」ボタンを押してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/86b26cdb-830d-e4e4-5d02-05f093b213a1.png" width=500 />
インストール画面でチャンネルを指定されるように促されますので、どれか一つ選択してから「Allow」ボタンをクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/cbadd1c5-eb11-466b-7bb2-b02904d652e9.png" width=500 />
インストールが完了したら **Features** > **Incoming Webhooks** へ移動し、スクロールすると発行された Incoming Webhooks の URL にアクセスすることができます（ここに映り込んでいる URL はすでに無効化しているのでご心配なく！）。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/c4e57bed-5507-b2bf-aabd-069f33762103.gif" width=500 />

この URL を `SLACK_WEBHOOK_URL` という環境変数に設定しましょう。

```bash
export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T11111/B11111/xxxxx
```

それではいよいよ Python のコードを試していきましょう。この記事のコードは Python 3.6 以上で動作します。`python3 --version` でバージョンを確認してください。`pip3 install skack-sdk` か [Poetry](https://python-poetry.org/) で `poetry add slack-sdk` を実行して、依存ライブラリをインストールしてください。

Incoming Webhooks のメッセージ送信は以下のようなコードで実行できます。非常にシンプルですね。

```python
import logging, os

# デバッグレベルのログを出力します
logging.basicConfig(level=logging.DEBUG)

# Web API クライアントを初期化します
from slack_sdk import WebhookClient
client = WebhookClient(os.environ["SLACK_WEBHOOK_URL"])

# メッセージを送信します
response = client.send(text=":wave: こんにちは！")
```

`webhook.py` として保存して実行します。

```bash
(.venv) bash-3.2$ python webhook.py
DEBUG:slack_sdk.webhook.client:Sending a request - url: https://hooks.slack.com/services/T11111/B11111/xxxxx, body: {"text": ":wave: \u3053\u3093\u306b\u3061\u306f\uff01"}, headers: {'Content-Type': 'application/json;charset=utf-8', 'User-Agent': 'Python/3.9.1 slackclient/3.5.1 Darwin/20.4.0'}
DEBUG:slack_sdk.webhook.client:Received the following response - status: 200, headers: { ... }, body: ok
```

こんな感じでメッセージが投稿されたでしょうか？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/434cd375-c071-640d-de56-90c02080dad5.png" width=500 />
もちろん、[ブロックキット（Block Kit）](https://api.slack.com/block-kit)も使えます。ブロックキットについて日本語で知りたい人は、[こちらのチュートリアル](https://api.slack.com/lang/ja-jp/slash-block-kit)や、[私が書いた別の Qiita 記事の説明](https://qiita.com/seratch/items/93714b5cf3974c2f5327#text--blocks--attachments-%E3%81%AE%E9%81%95%E3%81%84)を参考にしてみてください。

```python
# メッセージを送信します
response = client.send(
    text="今日の予定\n*マーケティングチーム 朝食 MTG*\n8:30 — 9:30 | 本社 9F Kagayaki (8)\n*コーヒーチャット w/ 採用内定者*\n10:30 — 11:00 | 本社 16F カフェテリア",
    blocks=[
        {"type": "context", "elements": [{"type": "mrkdwn", "text": "今日の予定"}]},
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": "*マーケティングチーム 朝食 MTG*\n8:30 — 9:30 | 本社 9F Kagayaki (8)",
            },
        },
        {"type": "divider"},
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": "*コーヒーチャット w/ 採用内定者*\n10:30 — 11:00 | 本社 16F カフェテリア",
            },
        },
    ],
)
```

このメッセージは以下のように表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/f8b4acd2-0ac6-e356-6006-cc56ccc56b64.png" width=500 />

### カスタムインテグレーションの Incoming Webhooks について

なお、App Directory を検索すると出てくる[カスタムインテグレーションの Incoming Webhooks](https://my.slack.com/apps/A0F7XDUAZ-incoming-webhooks) に関しては、

>Please note, this is a legacy custom integration - an outdated way for teams to integrate with Slack. These integrations lack newer features and they will be deprecated and possibly removed in the future. We do not recommend their use. Instead, we suggest that you check out their replacement: Slack apps.

と英語で注意書きがあるように、これからの新規での利用は推奨しておりません。上記で説明した Slack アプリを作ってチャンネルを指定した URL を発行するか `chat.postMessage` を使用するようにしてください。

カスタムインテグレーションのときに可能だった見た目の調整は Slack アプリ内の Incoming Webhook ではできませんが、`chat.postMessage` API を使えば可能です。これを利用するには、[`chat:write.customize`](https://api.slack.com/scopes/chat:write.customize) スコープを設定して、ボットトークンを使った `chat.postMessage` API コールのパラメーターの `username`、`icon_url`、`icon_emoji` をカスタマイズしてみてください。

それでは :wave: