LoginSignup
0
0

[Micropython]IoT機器からSlackの投稿にリアクション

Last updated at Posted at 2024-04-16

はじめに

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.addAPIを使用します。

token
ユーザートークンを指定。Authorizationヘッダーとして渡すかパラメターとして渡す。
channel
リアクション対象のSlackチャンネルIDを指定。
name
リアクションに使うアイコン名を指定。
timestamp
対象の投稿のタイムスタンプを指定。

このreactions.addAPIの引数はすべて必須となっています。

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:でリアクションするときは'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型の違いを言葉で説明する難しさを知りました。
そんな中、もともととある企画で作りたかったものが完成したので良しとしたいと思います。
もし、ご興味あれば以下のリンクをご覧ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0