はじめに
先日slackAPIを使ってslack連携機能を実装しました。
まず、chat.postMessageを使って、slackにメッセージを送信したりそのメッセージのスレッドに返信する機能を実装し、その後、chat.updateを使って、既存のメッセージの編集を実装しました。
chat.updateもchat.postMessageと使い方はそんな変わらないと思い、chat.postMessageのコードをコピペしてちょちょっと変えてササッと実装しようとしたのですが、数個の小さなトラップに引っかかったので、メモ程度に残しておきます。
1. 引数「channel」について
chat.postMessageでメッセージを送るときも、chat.updateでメッセージを編集するときも、channelという引数が必要です。しかし、2つのメソッドで引数の仕様が少し異なるのです。
まず、chat.postMessageではchannelという引数にチャンネルIDかチャンネル名を指定できます。ちなみに、slackでは、ワークスペース内でチャンネル名がユニークなのでチャンネル名でもチャンネルIDでも一意のチャンネルを特定できるし、どっちでもいいかという思いで、私はチャンネル名で実装していました。
それに対し、chat.updateでは引数channelに、チャンネル名を設定できず、チャンネルIDを設定しなければいけません。
chat.updateはchat.postMessageと同じ使い勝手でいけるんじゃない?と思って、chat.postMessageのコードをコピペしてちょちょっと変えただけの私はつまづきました。
2. 引数のslackのタイムスタンプはtsである。
次はタイムスタンプを渡す引数にトラップがありました。
chat.postMessageでは引数に、返信したいスレッドのタイムスタンプを設定する(キーワード引数で渡す)ことで、スレッドに返信することが出来ます。
そして、chat.updateでは引数に編集したいメッセージのタイムスタンプを設定する(キーワード引数で渡す)ことでメッセージを編集することが出来ます。
どちらもタイムスタンプを渡せばいいんだね!と思ったのですが、前者は「thread_ts」という名前の引数で、後者は「ts」という名前の引数でした。
言われてみれば、chat.postMessageの方は「ts」よりも「thread_ts」の方が正確な命名のように聞こえますが、「ts」でいいやんと思ってしまいました(小声)。
chat.updateメソッドの中身を読んで、ようやくtsやん...と気づきました。
3. ブロックの内容を上書くときは、ブロックで上書く
私がやろうとしていたことは、chat.postMessageでブロックを引数として投稿したメッセージの内容をchat.updateで上書くということです。更新後のメッセージは単なるテキストだったので、シンプルにchat.updateでtextを引数で渡していました。が、中身更新されない。
確かによく考えればそうかもしれないです。既存のを上書くには同じ構造で上書かないといけないです。
chat.postMessageを用いてブロックで組み立てた内容を送信したメッセージを、テキストで上書こうとした結果、chat.updateのリスポンスとして以下のようなものが返ってきました。これを見てみると、response[:text]
には変更後のメッセージがちゃんと入っているのですが、response[:message][:block]
には変更前の内容が残っているのが分かります。このように、ブロックで組み立てた内容をテキストで上書くとうまくいきません。ブロックはブロックで上書きましょう。
{"ok"=>true,
"channel"=>"xxx",
"ts"=>"xxx",
"text"=>"変更後のメッセージ",
"message"=>
{"bot_id"=>"xxx",
"type"=>"message",
"text"=>"変更後のメッセージ",
"user"=>"xxx",
"app_id"=>"xxx",
"blocks"=> [変更前のブロック内容],
"team"=>"xxx",
"bot_profile"=> {...},
"edited"=>{"user"=>"xxx", "ts"=>"xxx"},
"thread_ts"=>"xxx",
"reply_count"=>1,
"reply_users_count"=>1,
"latest_reply"=>"xxx",
"reply_users"=>["xxx"],
"is_locked"=>false,
"subscribed"=>false}}
{"ok"=>true,
"channel"=>"xxx",
"ts"=>"xxx",
"text"=>"変更後のテキスト内容",
"message"=>
{"bot_id"=>"xxx",
"type"=>"message",
"text"=>"変更後のテキスト内容",
"user"=>"xxx",
"app_id"=>"xxx",
"blocks"=>
[{"type"=>"section",
"block_id"=>"bst",
"text"=>
{"type"=>"mrkdwn",
"text"=>"変更後のテキスト内容",
"verbatim"=>false}}],
"team"=>"xxx",
"bot_profile"=> {...},
"edited"=>{"user"=>"xxx", "ts"=>"xxx"},
"thread_ts"=>"xxx",
"reply_count"=>1,
"reply_users_count"=>1,
"latest_reply"=>"xxx",
"reply_users"=>["xxx"],
"is_locked"=>false,
"subscribed"=>false}}
最後に
今回はslackのchat.updateを使ってスッと行かなかったところをメモしました。結局公式を読むのが正義ですね。