はじめに
サービスのKPIなどをスプレッドシートで管理することが多いとは思いますが、毎回データ取ってスプレッドシートに書き込んで、、をやってるとまあまあ時間の無駄なのでRailsアプリから直接スプレッドシートシートに書き込むようにしました。
加えてKPIの計測なので毎朝データを更新できるようにバッチも組むようにしました。
今回には以下を使っています。
- Rails 5.2
- gem 'google_drive'
実装
作るもの
Railsのデータベースから当月に会員登録したユーザーの数を日別で取得するようにします。
ユーザーは User モデルとします。
認証情報の取得
API経由でスプレッドシートを編集するために認証情報が必要なので Google Developers Console で情報を取得します。
プロジェクトの作成
APIの有効化
続いてスプレッドシートのAPIの利用を有効化するためにライブラリからスプレッドシートを検索して有効化します。
認証情報の作成
まずはOAuth同意画面で操作します。アプリケーション等を埋めて保存します。
作成したクライアントのリストから名前をクリックするとクライアントIDとクライアントシークレットを確認できます。
リフレッシュトークンの取得
つづいて先程作成したクライアントの情報をもとにリフレッシュトークンを取得します。
書くの面倒くさくなってしまったのでこちらのやり方はこの記事を参考にしてみてください。
Rails側の実装
今回はもろもろの処理をジョブの中に書いていきます。
Google API を今回の処理以外でも使う可能性を加味して ApplicationJob
に API の認証の処理を書き、他のジョブでも呼び出せるようにしました。(使う可能性を加味してというか、私の場合は複数使っているため)
class ApplicationJob < ActiveJob::Base
def google_drive
credentials = Google::Auth::UserRefreshCredentials.new(
client_id: ENV['KPI_SHEET_CLIENT_ID'],
client_secret: ENV['KPI_SHEET_CLIENT_SECRET'],
scope: %w(https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds/),
redirect_uri: 'http://storys.jp'
)
credentials.refresh_token = ENV['KPI_SHEET_REFRESH_TOKEN']
credentials.fetch_access_token!
GoogleDrive::Session.from_credentials(credentials)
end
end
実際にスプレッドシートに書き込む処理は以下です。
ws[1, 1]
はシートの1行目の1列目、ws[1, 2]
は1行目の2列目です。
同じようにws[2, 1]
は2行目の1列目になります。
class ExportKpiJob < ApplicationJob
def perform
spreadsheet = google_drive.spreadsheet_by_key('スプレッドシートのキー')
ws = spreadsheet.worksheet_by_title('該当のシートの名前')
ws[1, 1] = ''
ws[1, 2] = '新規登録ユーザー数'
current_date = Date.current
beginning_day_of_month = current_date.beginning_of_month
end_day_of_month = current_date.end_of_month
(beginning_day_of_month..end_day_of_month).each.with_index(2) do |date|
ws[index, 1] = date
ws[index, 2] = Users.where(created_at: date.beginning_of_day..date.end_of_month)
end
ws.save
end
end
定時処理の設定
定時処理には gem 'whenever'
を使います。
whenever自体の使い方はこちらを参考にしてください。
まずはタスクの作成
namespace :rails_sample do
desc 'KPIをスプレッドシートに吐き出す'
task :export_kpi => :environment do
ExportKpiJob.perform_now
end
end
今回は毎朝4時にタスクが走るようにします。
every 1.day, at: '4:00 am', role: [:app] do
rake 'rails_sample:export_kpi'
end
まとめ
以上でRailsからスプレッドシートを定時で書き換えるようにできました。
こういう小さな自動化を含めて、自分はもちろん他の人の仕事の効率を上げてあげることがエンジニアのできる貢献の1つかと思うので今後も続けたい所存。