箱のプログラミング日記。

渋谷の自社開発企業でRails書いてます。

RailsでChatworkAPIを使用する

f:id:y_hakoiri:20191120232646j:plain

RailsアプリケーションでChatworkAPIを使用してチャットを投げる方法について。

Chatworkとは

ここから説明する必要もないする気がするのだけど

go.chatwork.com

チャットツール。

Slackよりもエンジニア色が少し弱い印象。

アプリケーションの中で例外が発生した時や何かしらのタイミングで、Slackやこういったチャットツールに通知したいという場面はそれなりによくあるはず。

やること

  1. グループチャットを作る

  2. APIキーを発行する

  3. APIキーとroomのIDを環境変数に設置

  4. 実装

順番に見ていく。

グループチャットを作る

既存のグループを使用する場合はこの工程は不要。

今回は新しく通知専用のグループを作るため

f:id:y_hakoiri:20200311074558p:plain

左上のこの部分から。

+マークを押してチャット名を入力し、メンバーの招待を行います。

グループが出来上がったら、URLのridの部分

https://www.chatwork.com/#!rid*******

ridとはroomIDのことで、その後ろに続く9桁の数字はルーム(グループ)ごとに異なる一意のid。

このあとAPIを使って実装していく過程で使用します。

APIキーを発行する

やり方はこちらに載っています。

APIトークンを発行する – サポート | Chatwork

ちなみに企業アカウントの場合は管理者の承認が必要だったりする。

あと、実際にチャットにポストするアカウントから申請をしないと意味がないので、

自分ではなく通知専用アカウントにポストさせたい場合は、そちらにログインし直してから申請を。

APIキーとroomのIDを環境変数に設置

Railsアプリケーション内に環境変数を設置します。

dotenv-rails(gem)を使うとアプリケーション内部に.envファイルを作ってくれて、環境変数を設置することができる。

詳しい使い方はこちらがわかりやすいです。

[Ruby on Rails]環境変数の設定方法(.bash_profile、Dotenv-rails) - Qiita

公式:https://github.com/bkeepers/dotenv

.env↓

CHATWORK_ROOM_ID = "*********"
CHATWORK_API_TOKEN = "**********************************"

ridに続くルームIDと、先ほど取得したトークンを設置。

もちろんこれはGitHubへのプッシュ対象外にするべきなので、ローカル環境で動かすチームメンバーが複数いる場合は各々が各自設置する感じ。

今後実装が完了したら、stagingやproductionのサーバーに入って都度.envに書き込んでいく必要があります。

実装

公式ドキュメントはこちら。

Chatwork APIドキュメント

今回は特定のルームにPOSTリクエストを投げるのが目的だけど、それ以外にもできることはたくさんある。

(チャットワークに限らず、APIドキュメントっていろんなところに条件がちりばめられたりしていて、全体像を把握するのに時間がかかるのは私だけだろうか。)

ということで、ルームにPOSTリクエストを投げるために必要な情報だけを大まかにまとめると

  • httpsでの接続必須
  • リクエストを投げる先のパスは/rooms/{room_id}/messages
  • リクエストヘッダにX-ChatWorkTokenのキーでAPIトークンを含める必要がある
  • リクエストボディはContent-Type: application/x-www-form-urlencodedである必要がある
  • レスポンスはJSON形式

httpsでの接続必須

Railsでhttps通信を実現する方法は以前の記事でまとめてあるので、こちらをご覧ください

Railsでhttps通信を使ってjsonでPOSTする - 箱のプログラミング日記。

リクエストを投げる

HTTPリクエストは「どこに向けて」「なんの(HTTP)メソッドリクエストを投げるか」を決める必要がある。

今回はルームに新しいメッセージをPOSTしたいので、「/rooms/{room_id}/messagesに」「POSTリクエストを投げる」ことになります。

chatwork_room_id = ENV['CHATWORK_ROOM_ID']

uri = URI.parse("https://api.chatwork.com/v2/rooms/#{chatwork_room_id}/messages")

こうなる。

環境変数は扱いやすいようにchatwork_room_idに代入。

リクエストヘッダ

chatwork_api_token = ENV['CHATWORK_API_TOKEN']

req = Net::HTTP::Post.new(uri.path)
req['X-ChatWorkToken'] = chatwork_api_token

リクエストヘッダは「キー:バリュー」の形で指定する。

ここではX-ChatWorkTokenがキーにあたり、バリューがAPIトークン。

リクエストボディ

「リクエストボディはContent-Type: application/x-www-form-urlencodedである必要がある」

これがちょっとつまづいた。

ただそんなに難しく考える必要はなくて、

req.set_form_data(body: "hoge")

これで問題なし。

これに関しても以前書いたこちらの記事で解説しているので気になる方はそちらご覧ください。

ちなみにこれだけだと肝心なメッセージが「hoge」になってしまうので

message = "[toall]アプリケーションからの通知です"
req.set_form_data(body: message)

こうしておこう。

[toall]はチャットワーク独自のタグで、これがあるとルームメンバー全員に対して通知してくれる。Slackでいう@channnelのような。

他にもメッセージ全体を枠で囲むタグやタイトルをつけるタグもあるけど、今回は特に解説しません。

完成形

module Chatwork
  require 'net/https'
  require 'uri'
  require 'json'

  def push_chatwork_message
    chatwork_room_id = ENV['CHATWORK_ROOM_ID']
    chatwork_api_token = ENV['CHATWORK_API_TOKEN']

    uri = URI.parse("https://api.chatwork.com/v2/rooms/#{chatwork_room_id}/messages")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE

    message = "[toall]アプリケーションからの通知です"

    http.start do
      req = Net::HTTP::Post.new(uri.path)
      req['X-ChatWorkToken'] = chatwork_api_token
      req.set_form_data(body: message)
      http.request(req)
    end
  end
end

こんな感じ。

この処理は今後いろんなところから呼び出すと思うので、moduleに切り分けておいた。

必要なモデルでextend Chatworkした上でpush_chatwork_messageを呼び出せばOK

参考

APIトークンを発行する – サポート | Chatwork

Chatwork APIドキュメント

Ruby on Rails 5 で問い合わせフォーム作成 (問い合わせ内容をメールで送信 + ChatWorkで通知する) - Qiita