もふもふ技術部

IT技術系mofmofメディア

RailsプロジェクトでSlack通知を実装する

プロジェクトの開発中・リリース直後は想定外のエラーが多発するため、異常はすぐに検知出来た方が開発スピードが上がりますね。
今回はそういったケースでライトにSlackへの通知が出来る、slack-notifierのご紹介です。

gemインストール

Gemfileにslack-notifierを追加し、bundle install

#Gemfile
gem 'slack-notifier'

Slack側準備

Slack側でアプリケーションの通知を受け取れるよう設定します。
1. まずは下記URLにアクセスします。
https://slack.com/services/new/incoming-webhook 2. 通知先ワークスペースを選択します。ここではmofmofの社内Slackであるj-caw 3. 通知先チャンネルを選択します。ここでは#times_miwa 4. Incoming Webhook インテグレーションの追加をクリック slackスクリーンショット2

  1. Webhook URLをコピペして保存! slackスクリーンショット3

Slackでメッセージを送信する

では、準備が出来たのでアプリからメッセージを送ってみましょう。
下記の様なコードを書けば、メッセージが送信されます。

WEBHOOK_URL = 'https://hooks.slack.com/services/〇〇...〇〇'
Slack::Notifier.new(WEBHOOK_URL).ping('メッセージ')

もしくは、ワークスペースのchannelとメッセージ送信者名をRails側で指定することも出来ます。

WEBHOOK_URL = 'https://hooks.slack.com/services/〇〇...〇〇'
channel = "#times_miwa"
username = "mofmof"

Slack::Notifier.new(WEBHOOK_URL, channel: channel, username: username).ping('メッセージ')

ただ、毎回この書き方だと複数箇所でSlack通知を実装するには冗長になってしまいます。
なので、Railsの中であればSlack::Notifierオブジェクトをどこからでも簡単に呼び出せるようにしましょう。

SlackNotifierクラスの作成

app/models配下に下記ファイルを作成します。

# app/models/slack_notifier

class SlackNotifier
  attr_reader :client

  # 環境SLACK_WEBHOOK_URLにwebhook urlを格納
  WEBHOOK_URL = ENV['SLACK_WEBHOOK_URL']
  CHANNEL = "#times_miwa"
  USER_NAME = "mofmof"

  def initialize
    @client = Slack::Notifier.new(webhook_url, channel: CHANNEL, username: USER_NAME)
  end

  def send(message)
    Slack::Notifier.new(WEBHOOK_URL, channel: CHANNEL, username: USER_NAME).ping('message')
  end
end

上記の様に書けば、プロジェクトのどこからでも下記の様にワンライナーでSlack通知を呼び出せます。

SlackNotifier.new.send('Hello')
SlackNotifier.new.send('こんにちは')
SlackNotifier.new.send('你好')

ただ、メッセージがこれだけだとエラー内容も通知に含めたい場合などは少々使いづらいです。
エラーの場合はエラーだと一目でわかるようにメッセージを装飾したい、という場面もあります。

エラー通知

その場合、Slackのattachmentsを使用すれば良いでしょう。
attachmentsとはSlackのメッセージを装飾するものです。
これを使えば、Slackのメッセージ色などを変えることが出来ます。
そしてattachmentで装飾されたメッセージを送信する場合、Slack::Notifier#postメソッドを使用します。
SlackNotifierクラスを書き変えてみましょう。

# app/models/slack_notifier

class SlackNotifier
  attr_reader :client

  # 環境SLACK_WEBHOOK_URLにwebhook urlを格納
  WEBHOOK_URL = ENV['SLACK_WEBHOOK_URL']
  CHANNEL = "#times_miwa"
  USER_NAME = "mofmof"

  def initialize
    @client = Slack::Notifier.new(webhook_url, channel: CHANNEL, username: USER_NAME)
  end

  def send(title, message)
    payload = {
      fallback: "Application raise error",
      text: message,
      color: "bad"
    }
    client.post text: title, attachments: [payload]
  end
end

SlackNotifierクラスを利用してメッセージを送信します。

SlackNotifier.new.send('エラー', 'エラーが発生しました。')

以下の様なメッセージが送信されます。
こうしておくと、一目でエラー発生していることが分かりますね。 slackスクリーンショット4

まとめ

いかがでしたでしょうか?Slack通知が案外簡単に作成出来る事をお分り頂けたかと思います。
attachmentは他にもたくさんあるので、是非色々調べて分りやすい通知が出来る様にしてください。