はじめに
IoT機器のボタンを押すことでSlackの投稿に対して「リアクション」させる処理をMicropythonで実装しました。そのときの実装ポイントの備忘録となります。
TL;DR
- PythonにはSlask SDKを使って簡単にSlack APIを叩くことができるがMicropythonにはないのでurequestsを使ってHTTPリクエストを行う
- ユーザー自身の「リアクション」としたいときはユーザー自身のユーザートークンが必要
- ユーザートークンはBearer Tokenとしてヘッダーで指定
- 「リアクション」には
reactions.add
のAPIを使いパラメータには対象記事のタイムスタンプとアイコン名を指定する
前提
「リアクション」の対象となるSlackのチャンネルの投稿に対して以下の情報がすでにわかっているものとします。
- リアクションの対象となるSlackチャンネルのID
- ユーザー自身のユーザートークンとアクセス権限(SlackアプリのScopeでいうところの
reactions:write
) - リアクション対象の投稿のタイムスタンプ
- リアクション時に使うアイコンの名前
以下のリンクにはユーザー自身のユーザートークンを取得するのに必要な手順が書かれていますので参照ください。
使用するSlack API
Slackの投稿に対して「リアクション」するために以下のreactions.add
APIを使用します。
- token
- ユーザートークンを指定。Authorizationヘッダーとして渡すかパラメターとして渡す。
- channel
- リアクション対象のSlackチャンネルIDを指定。
- name
- リアクションに使うアイコン名を指定。
- timestamp
- 対象の投稿のタイムスタンプを指定。
このreactions.add
APIの引数はすべて必須となっています。
PythonではSlack SDKがありSlack APIにパラメータを指定するのも比較的容易に実装できますが、今回使うのはMicropythonということもありSlack SDKは使用できないので、Micropythonのurequestsモジュールを使ってSlack APIを実行することにしました。
Slackの投稿にリアクションするコード
以下はMicropythonでurequestsを使ってSlackの投稿にリアクションするコードです。
import urequests
import ujson
def reaction():
# リアクションするためのURL
history_url = 'https://slack.com/api/conversations.history'
# ユーザートークン
token = 'xoxp-xxxxxxxxxxxxx.xxxxxxxxxxxxx'
# リアクション対象のSlackチャンネル
channel = 'Cxxxxxxxx'
# リアクションに使うアイコン名
emoji = 'hei'
# ヘッダーの作成
header = {}
header['Content-Type'] = 'application/json; charset=utf-8'
header['Authorization'] = 'Bearer ' + token
# リアクション時のパラメータを設定
data = {}
data['channel'] = channel
data['timestamp'] = latesttime # 対象となる投稿のタイムスタンプ
data['name'] = emoji
res = urequests.post(
url = reaction_url,
data = ujson.dumps(data),
headers = header
)
resjson = res.json()
if resjson['ok']:
print('Reaction success!')
else:
print('Reaction failed!')
data['timestamp']
には12345678.123456
形式のタイムスタンプの文字列を指定します。
上記コードではlatesttime
を指定していますが、latesttime
には事前に取得した投稿のタイムスタンプの文字列が入っています。
data['name']
にはアイコンの名前を指定します。例えば、でリアクションするときは'thumbsup'を指定します。
補足
Slack APIのリファレンスによると、tokenは「Authorizationヘッダーとして渡すかパラメターとして渡す」となっていますが、下記のように通常のパラメータとして渡すとレスポンスはOKになりませんでした。
# ヘッダーの作成
header = {}
header['Content-Type'] = 'application/json; charset=utf-8'
# リアクション時のパラメータを設定
body = {}
body['token'] = token # tokenをbodyの方で指定
body['channel'] = channel
body['timestamp'] = latesttime # 対象となる投稿のタイムスタンプ
body['name'] = emoji
res = urequests.post(
url = reaction_url,
data = ujson.dumps(data),
headers = header
)
詳しくは調べていませんが、使ったユーザー独自のユーザートークンだからと勝手に予想。
最後に
今更ながらPythonの辞書式とJSON型の違いを言葉で説明する難しさを知りました。
そんな中、もともととある企画で作りたかったものが完成したので良しとしたいと思います。
もし、ご興味あれば以下のリンクをご覧ください。