Ruby on Rails で Slack API を使って通知機能を実装する手順
はじめに
アプリ開発において、エラー発生時にすぐに通知を受け取れるようにすることは非常に重要です。Slack は多くの開発チームが利用している報連相ツールであり、Ruby on Rails から Slack へ通知を送る機能を実装することで、早く問題やエラーなどを発見して対応することが可能です。
この記事では、その方法について解説します。
Slack アプリの作成
今回は社内の既存のワークスペースに通知したいので、このステップはスキップします。もし新規の場合は、まずは通知したい Slack のワークスペースとチャンネルを作成しておきましょう。
Slack アプリの作成と Webhook URL の取得
-
下記の URL にアクセスして、右の「Create New App」ボタンを押してください。
https://api.slack.com/apps
-
作成したアプリの詳細画面で「Incoming Webhooks」をクリックして、「Activate Incoming Webhooks」をオンにします。
-
同じページの一番下にスクロールして、「Webhook URL」をコピーしてRailsアプリの
.env
ファイルに環境変数として設定してください。
# .env
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/.../.../...
Rails アプリでの実装
Gem のインストール
まず、Gemfile に slack-notifier
を追加します。
# Gemfile
gem "slack-notifier"
その後、bundle install を実行してください。
bundle install
通知用のモデル作成
下記の SlackNotifier クラスを作成します。必要に応じてコードを調整してください。
# app/models/slack_notifier.rb
class SlackNotifier
attr_reader :client
def initialize
@client = Slack::Notifier.new(ENV['SLACK_WEBHOOK_URL'])
end
def self.slack(message)
@slack ||= new
@slack.send(message)
Rails.logger.info message
end
def self.slack_with_mention(message)
@slack ||= new
@slack.send_with_mention(message)
Rails.logger.error message
end
def send(message)
client.ping(message)
rescue Slack::Notifier::APIError => e
Rails.logger.error('APIError')
Rails.logger.error(e.message)
rescue => e
Rails.logger.error('SlackNotifierError')
Rails.logger.error(e.message)
end
def mention(message)
"<!channel>\n#{message}"
end
def send_with_mention(message)
send(mention(message))
end
end
エラーハンドリングの実装
ご参考までに、必要に応じてコードを調整してください。
# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
include DeviseTokenAuth::Concerns::SetUserByToken
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
rescue_from ActiveRecord::RecordInvalid, with: :record_invalid
rescue_from StandardError, with: :handle_standard_error
private
def record_not_found(exception)
SlackNotifier.slack_with_mention(exception.message)
render json: { message: "レコードが見つかりません" }, status: :not_found
end
def record_invalid(exception)
SlackNotifier.slack_with_mention(exception.message)
render json: { message: exception.message }, status: :unprocessable_entity
end
def handle_standard_error(exception)
log_and_notify_error("Standard error", exception)
render json: { message: "Internal Server Error: #{exception.message}" }, status: :internal_server_error
end
def log_and_notify_error(error_type, exception)
error_message = [
"#{error_type}が発生しました:",
"エラーメッセージ: #{exception.message}",
"バックトレース:",
exception.backtrace&.first(3)&.join("\n")
].join("\n")
SlackNotifier.slack_with_mention(error_message)
end
end
動作確認
そのために、以下のコードをコンソールに実行して、テストできます。
# コンソールを開く
rails c
# 環境変数のセットアップ確認
puts "SLACK_WEBHOOK_URL: #{ENV['SLACK_WEBHOOK_URL'].present? ? '設定済み' : '未設定'}"
# 通常メッセージの送信テスト
SlackNotifier.slack("これはテストメッセージです。")
# メンション付きメッセージの送信テスト
SlackNotifier.slack_with_mention("これは@channelメンションつけのテストメッセージです。")
# エラー発生時のテスト (例: 存在しないレコードを検索)
begin
User.find(-1) # 存在しないIDを指定
rescue => e
SlackNotifier.slack_with_mention("(テスト)エラーが発生しました: #{e.message}")
end
アプリを実行してテストし、Slack チャンネルにメッセージが届くかどうかを確認しましょう。