LoginSignup
7
9

More than 3 years have passed since last update.

Railsからスプレッドシートを定時で書き換える

Posted at

はじめに

サービスのKPIなどをスプレッドシートで管理することが多いとは思いますが、毎回データ取ってスプレッドシートに書き込んで、、をやってるとまあまあ時間の無駄なのでRailsアプリから直接スプレッドシートシートに書き込むようにしました。
加えてKPIの計測なので毎朝データを更新できるようにバッチも組むようにしました。

今回には以下を使っています。

  • Rails 5.2
  • gem 'google_drive'

実装

作るもの

Railsのデータベースから当月に会員登録したユーザーの数を日別で取得するようにします。
ユーザーは User モデルとします。

認証情報の取得

API経由でスプレッドシートを編集するために認証情報が必要なので Google Developers Console で情報を取得します。

プロジェクトの作成

ますはプロジェクトを作成します。
スクリーンショット 2019-07-07 11.54.03.png
スクリーンショット 2019-07-07 11.56.49.png

APIの有効化

続いてスプレッドシートのAPIの利用を有効化するためにライブラリからスプレッドシートを検索して有効化します。
スクリーンショット 2019-07-07 11.57.16.png
スクリーンショット 2019-07-07 12.01.27.png

認証情報の作成

まずはOAuth同意画面で操作します。アプリケーション等を埋めて保存します。
スクリーンショット 2019-07-07 12.07.03.png

つづいてOAuthクライアントを作成していきます。
スクリーンショット 2019-07-07 12.08.39.png
スクリーンショット 2019-07-07 12.09.17.png

作成したクライアントのリストから名前をクリックするとクライアントIDとクライアントシークレットを確認できます。
スクリーンショット 2019-07-07 12.10.00.png

リフレッシュトークンの取得

つづいて先程作成したクライアントの情報をもとにリフレッシュトークンを取得します。
書くの面倒くさくなってしまったのでこちらのやり方はこの記事を参考にしてみてください。

Rails側の実装

今回はもろもろの処理をジョブの中に書いていきます。

Google API を今回の処理以外でも使う可能性を加味して ApplicationJob に API の認証の処理を書き、他のジョブでも呼び出せるようにしました。(使う可能性を加味してというか、私の場合は複数使っているため)

app/jobs/application_job.rb
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列目になります。

app/jobs/export_kpi_job.rb
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自体の使い方はこちらを参考にしてください。

まずはタスクの作成

lib/tasks/rails_sample.rake
namespace :rails_sample do
  desc 'KPIをスプレッドシートに吐き出す'
  task :export_kpi => :environment do
    ExportKpiJob.perform_now
  end
end

今回は毎朝4時にタスクが走るようにします。

config/schedule.rb
every 1.day, at: '4:00 am', role: [:app] do
  rake 'rails_sample:export_kpi'
end

まとめ

以上でRailsからスプレッドシートを定時で書き換えるようにできました。
こういう小さな自動化を含めて、自分はもちろん他の人の仕事の効率を上げてあげることがエンジニアのできる貢献の1つかと思うので今後も続けたい所存。

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9