Ruby, MechanizeでPOSTリクエストを送信して,Slackにメッセージを投稿してみた


何をしたか

今回は,最近勉強しているRubyのMechanizeというライブラリを使って, Slackにメッセージの投稿をしてみました.

Mechanizeといえば,スクレイピングの際にフォーム入力とsubmitをコード上で行えることが魅力の1つだと思います.スクレイピングを勉強したての自分には遊ぶのがめちゃくちゃ面白いライブラリです.
そんなMechanizeですが,実はフォームがなくても,postメソッドなるメソッドを用いればPOSTリクエストを送信することができるそうです.
これとSlackが提供している Incoming WebHooks という機能を使うとこんなことができてしまいます.

スクリーンショット 2019-06-04 22.54.39.png

これは自分で打ってるんじゃありませんよ?Rubyのプログラムを利用してSlackに投稿してるんです!
しかもこの機能たったの5行で書けちゃいます.
ちなみに対話機能は今はないので,1人で会話してることになりますが,何かしら別の機能をつければ,Todoリストやら天気やら自分に通知できるはずです! がんばれば対話もできるのではないでしょうか.
では以下やり方です.

やり方

環境

-Mac Mojave version10.14.4
-ruby 2.4.3
-Mechanize 2.7.6

手順

  1. slack Incoming WebHooksで webhook urlを取得する
  2. MechanizeのpostメソッドでSlackに投稿する

以上です!

手順1 Slack Incoming WebHooksで webhook urlを取得する

詳しくは別記事を書くので,もしよくわからなかったらそっちを読んでください

まず,以下のurlのxxxを自分のslackのurlに変えてアクセスしてください.slackのページ内のリンクからも辿れるでしょうがこちらの方が早いので.
https://xxx.slack.com/apps

  1. 上のページのアプリ検索フォームで,Incoming WebHooks と検索し,アプリのページに飛ぶ
  2. Add Configuration を押す
  3. Incoming WebHooksを追加したい Channel を選択して Add Incoming WebHooks Integration を押す
  4. 最後のページで, WebHook URLが記載されてるのでコピーして使ってください

利用する際は対象のURLに以下のようなJSONをリクエストボディとしてPOSTリクエストを送信すればいいそうです.
payload={"text": "This is a line of text in a channel.\nAnd this is another line of text."}

手順2 MechanizeのpostメソッドでSlackに投稿する

※遭遇したエラー対処法は後ほど別記事で紹介

postメソッドの仕様
https://www.rubydoc.info/gems/mechanize/Mechanize#post-instance_method
post(uri, query = {}, headers = {})⇒ Object
第一引数に,リクエストを送信するurl
第二引数に,リクエストボディ
第三引数に,リクエストヘッダー
をいれればいいみたいです.
第二引数と,第三引数は上の式からもわかるように, 空の場合は空のハッシュが入ります.
ここは私は勘違いしてはまってしまいました..
わかってる人は普通にわかると思うんですが,空の時にハッシュが入るだけで,ハッシュである必要はないんです!!

今回各引数は以下のようになります

第一引数→ WebHook URL
第二引数→ JSON
第三引数→ 

ここで第三引数が空でいい理由は実はよくわかってません..HTTPリクエストの構造的にヘッダーは必要かと思われるのですが,いらないみたいです.(なくても通ります.)どなたかわかる方がいれば教えていただきたいです.

コードと出力結果

コード

xxxxxの部分は自分のものに書きかえてください

require 'mechanize'

agent = Mechanize.new
webhook_url = 'https://hooks.slack.com/services/xxxxx'
payload = '{"text" : "できました!"}'
agent.post(webhook_url,payload)

出力結果

送るJSONに
"username":"好きな名前"

"icon_emoji":"アイコンのid"
を指定することもできます
※アイコンのidはWebHook URL が載っていたページで調べることができます.

次のJSONを送った場合は
payload = '{"username": "JARVIS","icon_emoji":":ghost:","text" : "完成!"}'

このような出力になります

終わりに

これでmechanizeの使用の幅を広げて,かつSlackで遊ぶことができるようになりました!
何か定期的にリマインドしてくれるbotか,ゆくゆくは対話できるものを作ってみたいと思います

ちなみにslackに投稿する場合は,今回の方法以外に slack-notifierというgem(ライブラリ)を使う方法もあります.その場合,コードはさらに短くなります.笑. もしアイコンや名前の指定がincoming webhooksでしかできないのであれば今回の記事は役にたつかなと思います.ではまた.

slack-notifierを用いた時のコード

require 'slack-notifier'
notifier = Slack::Notifier.new(webhook_url) #事前準備で取得したWebhook URL
notifier.ping('Hello')