Pythonを使ってSlackへボタン付きメッセージを送る


#はじめに
社内で、ボタンのメッセージがslackで送れたらいいよね！
という話になりました。

#用意したもの
MacBook Air macOS Sierra 10.12.6
Python 3.6.5
requests 2.19.1 => 事前にインストールしておく。
SlackOAuthToken => 事前に確認／取得しておく。

#やってみます

```python:postMessage.py
# -*- coding: utf-8 -*-
import requests
import json

def postQuestionMsg():
    post_url = 'https://slack.com/api/chat.postMessage'
    token = 'xoxp-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX'
    channel = 'XXXXXXXXX'
    username = 'ボタンのテスト君'
    icon_emoji = ':robot_face:'
    callback_id = 'which_noodle'

    attachments = [{
        'text': 'そばとうどんどっちが好き？',
        'callback_id': callback_id,
        'color': '#EE2222',
        'attachment_type': 'default',
        'actions': [{
            'name': 'done',
            'text': 'そば',
            'type': 'button'
        },
        {
            'name': 'done',
            'text': 'うどん',
            'type': 'button'
        }]
    }]

    payload = {
        'token': token,
        'channel': channel,
        'username': username,
        'icon_emoji': icon_emoji,
        'attachments': json.dumps(attachments)
    }

    res = requests.post(post_url, data=payload)
    print(res.status_code)


if __name__ == '__main__':
    postQuestionMsg()

```

#解説
##序盤
まずはこの部分です。

```python:postMessage.py
def postQuestionMsg():
    post_url = 'https://slack.com/api/chat.postMessage'
    token = 'xoxp-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX'
    channel = 'XXXXXXXXX'
    username = 'ボタンのテスト君'
    icon_emoji = ':robot_face:'
    callback_id = 'which_noodle'    
```

`post_url`に代入されているのがslackAPIのURLになります。
たくさん種類がありますが、その中でもメッセージを送信する時に使う`https://slack.com/api/chat.postMessage`を代入しています。
他のものについてはこちら => [slackAPI](https://api.slack.com/methods)

`token`にはあらかじめ用意したものを代入します。
`channel`にはメッセージの送信先を英数字で指定します。
Chromeなどのブラウザからslackを開くとURLで確認できます。
送信先はchannelやユーザを指定できます。

`username`は送信元のユーザ名を文字列で代入します。
今回は`ボタンのテスト君`という名前をつけました。

`icon_emoji`は送信元のユーザアイコンを指定できます。
今回はロボットの顔のアイコンが表示されるように指定しています。
記法についてはアプリ、ブラウザどちらからでも確認できます。
`:`から`:`の部分ですね。

`callback_id`は今作成しているボタン付きメッセージを送信し、
ボタンを押下した後サーバ側で取得する際に必要になります。
ボタン付きメッセージを送信するだけでしたら、指定する必要はありません。

##中盤
次はここの部分ですね。

```python:postMessage.py
    attachments = [{
        'text': 'そばとうどんどっちが好き？',
        'color': '#EE2222',
        'attachment_type': 'default',
        'actions': [{
            'name': 'done',
            'text': 'そば',
            'type': 'button'
        },
        {
            'name': 'done',
            'text': 'うどん',
            'type': 'button'
        }]
    }]
```

slackでボタン付きのメッセージを送るには、`attachments`というものを使います。
メッセージを装飾するもので、中でもボタンは`Interactive Message`とか言ったりするみたいです。
先にどのようなメッセージなるか見てみます。

![スクリーンショット 2019-06-02 19.04.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152025/cdbc9ec7-d8f2-df34-a383-0be80457de4e.png "スクリーンショット 2019-06-02 19.04.18.png")

ユーザ名とユーザアイコンがちゃんと反映されていますね。
さて、今回はそのまま`attachments`という変数に代入しています。
大まかにすると以下のような感じです。

-`text` 文章になります。
-`color` 色を装飾することができます。赤い縦線の部分ですね。カラーコードなどが利用できます。
-`attachment_type` とりあえず`default`にしておきましょう。

`actions`について、ここがボタンとなる部分になります。
`name`は今回`done`にします。
（メッセージや`attachmets`部の内容を取得したりする時に別の値にするんだと思います。多分...）

`text`はボタン上に表示させる文章を代入します。
今回だと`そば`と`うどん`です。
`type`はボタンを使いたいのでもちろん、`button`を指定します。

今回のメッセージでは`そば`と`うどん`という複数の選択肢をボタンで表現します。
そのため、`actions`には配列が指定されています。`[`から`]`の部分ですね。
配列の要素には`そば`と`うどん`の2つを辞書型で指定しています。`{`から`}`の部分ですね。
なんとなく見やすくすると、`[{そば},{うどん}]`という感じです。

これで`attacchments`ができました。

##終盤
最後はこの部分です。

```python:postMessage.py
    payload = {
        'token': token,
        'channel': channel,
        'username': username,
        'icon_emoji': icon_emoji,
        'attachments': json.dumps(attachments)
    }

    res = requests.post(post_url, data=payload)
    print(res.status_code)


if __name__ == '__main__':
    postQuestionMsg()

```
`res = requsts.post(post_url, data=payload)`を使ってメッセージを送信します。
`print(res.status_code)`はメッセージ送信が成功しているか確認できます。
実行後、ターミナルなどに`200`が表示されていれば成功しています。

`res = requsts.post(post_url, data=payload)`について、
まず`post_url`は序盤で解説したslackAPIのURLが指定されています。
次に`data=payload`ですが、すぐ上に`payload`を記述していますね。
`token`から`icon_emoji`は序盤で解説した通りです。

では`attachments`ですが`json.bumps(attachments)`となっています。
これは中盤で記述した変数`attachments`をJSON形式で文字列化しているのですが、
メッセージを送るために変換していると一旦は考えていただければと思います。

最後の`if ~ `はこのプログラムが実行されたら、
関数`postQuestMsg`を実行しますよーと記述しています。

#さいごに
これでボタン付きのメッセージが送れるようになりました。
ユーザが送信したメッセージに合わせてボタンの文章を変えたりとか、
色々いじっていこうと思います。
ただ、この段階ではボタンを押してもエラーが発生してしまうので、
やりとりが成立するようにしていきます。