T-CREATOR

Ruby で業務自動化:スプレッドシート連携・メール配信・定期バッチの実例

Ruby で業務自動化:スプレッドシート連携・メール配信・定期バッチの実例

日々の業務で「この作業、毎日繰り返しているな」と感じることはありませんか。スプレッドシートからデータを取得して集計したり、定期的にメールを送信したり、同じ処理を決まった時間に実行したり。そんな繰り返し作業を Ruby で自動化すれば、作業時間を大幅に削減できるんです。

本記事では、Ruby を使った業務自動化の実例として、Google スプレッドシートとの連携、メール配信、そして定期バッチ処理の実装方法を丁寧に解説します。実際のコードを交えながら、すぐに使える形でお伝えしますので、ぜひ最後までご覧ください。

背景

業務自動化が必要とされる理由

ビジネスの現場では、データの集計やレポート作成、定期的な通知メールの送信など、同じパターンの作業が繰り返し発生します。これらの作業は人の手で行うと時間がかかり、ミスも発生しやすいものです。

自動化することで得られるメリットは以下の通りです。

#メリット詳細
1時間削減手作業で 30 分かかる作業が数秒で完了
2ミス防止プログラムによる正確な処理で人的ミスを削減
3生産性向上単純作業から解放され、創造的な業務に集中可能
4定期実行深夜や早朝でも自動で処理を実行
5記録管理ログを残すことで処理履歴を追跡可能

Ruby が業務自動化に適している理由

Ruby は読みやすく書きやすい文法を持ち、豊富な Gem(ライブラリ)が揃っているため、業務自動化に最適な言語です。Google API との連携や、メール送信、スケジューリングなど、必要な機能がすべて Gem として提供されています。

以下の図は、Ruby を使った業務自動化の基本的なフローを示しています。

mermaidflowchart TB
    user["業務担当者"] -->|データ入力| sheet["Google スプレッドシート"]
    sheet -->|API 経由でデータ取得| ruby["Ruby スクリプト"]
    ruby -->|データ処理・集計| process["自動処理"]
    process -->|結果をメール送信| mail["メール配信"]
    process -->|処理結果を記録| log["ログファイル"]
    scheduler["定期実行<br/>(cron/whenever)"] -->|指定時刻に起動| ruby

この図から、スプレッドシートのデータを Ruby で取得し、処理した結果をメールで配信する一連の流れが理解できるでしょう。

課題

手作業による業務の問題点

業務自動化を検討する際、以下のような課題に直面することが多いです。

データ連携の煩雑さ

Excel や Google スプレッドシートに保存されたデータを毎回手動でダウンロードし、加工して、別のシステムに入力する作業は非効率です。API を使えば直接データを取得できるのですが、認証方法や API の使い方がわからず、諦めてしまうケースも少なくありません。

メール送信の手間

顧客リストや社内メンバーに定期的にメールを送る際、手動で宛先を設定し、本文をコピー&ペーストするのは時間がかかります。さらに、送信漏れや誤送信のリスクも伴いますね。

定期実行の管理

毎朝 9 時にレポートを作成する、毎週月曜日に集計結果を送信するなど、決まった時間に処理を実行したい場合、人が手動で行うのは現実的ではありません。

以下の図は、これらの課題がどのように関連しているかを示しています。

mermaidflowchart LR
    manual["手作業による<br/>業務処理"] -->|時間がかかる| time["作業時間<br/>の増加"]
    manual -->|ミスが発生| error["人的ミス<br/>の発生"]
    manual -->|定期実行が困難| schedule["スケジュール<br/>管理の負担"]
    time --> stress["業務負荷<br/>の増大"]
    error --> stress
    schedule --> stress

これらの課題を解決するために、Ruby による自動化が有効なのです。

解決策

Ruby による業務自動化の全体像

Ruby を使えば、スプレッドシート連携、メール配信、定期バッチ処理のすべてを統合的に自動化できます。必要な Gem をインストールし、認証情報を設定すれば、わずかなコードで実現可能です。

以下の図は、今回実装する自動化システムの全体構成を示しています。

mermaidflowchart TD
    subgraph setup["環境構築"]
        gems["必要な Gem<br/>のインストール"]
        auth["認証情報<br/>の設定"]
    end

    subgraph automation["自動化処理"]
        sheet_api["Google Sheets API<br/>でデータ取得"]
        process_data["データの加工<br/>・集計"]
        send_mail["メール配信<br/>(SMTP)"]
    end

    subgraph schedule["定期実行"]
        whenever["whenever Gem<br/>で cron 設定"]
        batch["バッチ処理<br/>の実行"]
    end

    setup --> automation
    automation --> schedule

必要な Gem のインストール

まず、必要な Gem をインストールします。以下のコマンドを実行してください。

bash# Google Sheets API 用
gem install google-api-client

# メール送信用
gem install mail

# 定期実行用
gem install whenever

または、Gemfile に以下を追加して bundle install を実行します。

ruby# Gemfile
source 'https://rubygems.org'

# Google Sheets API
gem 'google-api-client', '~> 0.53'

# メール送信
gem 'mail', '~> 2.8'

# 定期実行
gem 'whenever', require: false

これで、スプレッドシート連携、メール配信、定期実行に必要なライブラリが揃いました。

具体例

Google スプレッドシート連携の実装

ステップ 1:Google Cloud プロジェクトの設定

Google Sheets API を利用するには、Google Cloud Console でプロジェクトを作成し、サービスアカウントを発行する必要があります。

設定手順

#ステップ作業内容
1プロジェクト作成Google Cloud Console でプロジェクトを新規作成
2API 有効化Google Sheets API を有効化
3サービスアカウント作成認証用のサービスアカウントを作成
4JSON キー取得サービスアカウントの JSON キーをダウンロード
5スプレッドシート共有サービスアカウントのメールアドレスに編集権限を付与

JSON キーは credentials.json として保存し、プロジェクトのルートディレクトリに配置してください。

ステップ 2:スプレッドシートからデータを取得

Google Sheets API を使ってスプレッドシートのデータを取得するコードを実装します。

まず、必要なライブラリを読み込みます。

ruby# スプレッドシート連携用のライブラリをロード
require 'google/apis/sheets_v4'
require 'googleauth'
require 'fileutils'

次に、認証情報を設定し、API クライアントを初期化します。

ruby# Google Sheets API の初期化
def initialize_sheets_api
  # 認証スコープの設定
  scope = Google::Apis::SheetsV4::AUTH_SPREADSHEETS_READONLY

  # サービスアカウントの認証情報を読み込み
  authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
    json_key_io: File.open('credentials.json'),
    scope: scope
  )

  # API サービスの作成
  service = Google::Apis::SheetsV4::SheetsService.new
  service.authorization = authorizer

  service
end

スプレッドシートからデータを取得する関数を作成します。

ruby# スプレッドシートのデータを取得
def get_spreadsheet_data(spreadsheet_id, range)
  service = initialize_sheets_api

  # データの取得
  response = service.get_spreadsheet_values(spreadsheet_id, range)
  values = response.values

  if values.nil? || values.empty?
    puts 'データが見つかりませんでした。'
    return []
  end

  values
end

実際にデータを取得して処理する例です。

ruby# 使用例
SPREADSHEET_ID = 'your_spreadsheet_id_here'
RANGE = 'シート1!A1:D100'

# データの取得
data = get_spreadsheet_data(SPREADSHEET_ID, RANGE)

# データの表示
data.each_with_index do |row, index|
  # 1行目はヘッダーとして扱う
  if index.zero?
    puts "ヘッダー: #{row.join(', ')}"
  else
    puts "データ#{index}: #{row.join(', ')}"
  end
end

このコードで、スプレッドシートのデータを配列として取得できます。取得したデータを加工して、さまざまな処理に活用できますね。

ステップ 3:データの集計と加工

取得したデータを集計する例を見ていきましょう。ここでは、売上データを集計するケースを想定します。

ruby# 売上データの集計
def aggregate_sales_data(data)
  # ヘッダーを除外
  headers = data.first
  rows = data[1..]

  # 集計結果を格納するハッシュ
  summary = Hash.new(0)

  rows.each do |row|
    # 商品名と売上金額を取得(列インデックスは適宜調整)
    product_name = row[0]
    amount = row[2].to_i

    # 商品ごとに売上を集計
    summary[product_name] += amount
  end

  summary
end

集計結果を見やすく表示する関数も追加します。

ruby# 集計結果の表示
def display_summary(summary)
  puts "\n===== 売上集計結果 ====="

  # 売上の多い順にソート
  sorted = summary.sort_by { |_product, amount| -amount }

  sorted.each_with_index do |(product, amount), index|
    puts "#{index + 1}. #{product}: #{amount.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse}円"
  end

  # 合計金額の計算
  total = summary.values.sum
  puts "\n合計売上: #{total.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse}円"
end

実際に集計を実行する例です。

ruby# 使用例
data = get_spreadsheet_data(SPREADSHEET_ID, RANGE)
summary = aggregate_sales_data(data)
display_summary(summary)

これで、スプレッドシートから取得したデータを自動で集計し、見やすく表示できます。

メール配信の実装

ステップ 1:SMTP 設定

メール送信には mail Gem を使用します。まず、SMTP サーバーの設定を行います。

ruby# メール送信の設定
require 'mail'

# SMTP サーバーの設定(Gmail の例)
Mail.defaults do
  delivery_method :smtp, {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'your-domain.com',
    user_name: 'your-email@gmail.com',
    password: 'your-app-password',  # アプリパスワードを使用
    authentication: 'plain',
    enable_starttls_auto: true
  }
end

Gmail を使用する場合は、2 段階認証を有効にして、アプリパスワードを発行してください。通常のパスワードではセキュリティ上の理由でエラーになります。

ステップ 2:メール送信関数の作成

集計結果をメール本文に含めて送信する関数を作成します。

ruby# メール送信関数
def send_report_email(to_address, subject, summary)
  # メール本文の作成
  body = create_email_body(summary)

  # メールの作成
  mail = Mail.new do
    from     'your-email@gmail.com'
    to       to_address
    subject  subject
    body     body
  end

  # メールの送信
  begin
    mail.deliver!
    puts "メールを送信しました: #{to_address}"
  rescue StandardError => e
    puts "メール送信エラー: #{e.message}"
  end
end

メール本文を生成する関数を作成します。

ruby# メール本文の生成
def create_email_body(summary)
  body = "日々の売上集計結果をお知らせいたします。\n\n"
  body += "===== 売上集計結果 =====\n\n"

  # 売上の多い順にソート
  sorted = summary.sort_by { |_product, amount| -amount }

  sorted.each_with_index do |(product, amount), index|
    formatted_amount = amount.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
    body += "#{index + 1}. #{product}: #{formatted_amount}円\n"
  end

  # 合計金額
  total = summary.values.sum
  formatted_total = total.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
  body += "\n合計売上: #{formatted_total}円\n\n"
  body += "※ このメールは自動送信されています。\n"

  body
end

実際にメールを送信する例です。

ruby# 使用例
data = get_spreadsheet_data(SPREADSHEET_ID, RANGE)
summary = aggregate_sales_data(data)

# メール送信
send_report_email(
  'recipient@example.com',
  '【自動送信】売上集計レポート',
  summary
)

ステップ 3:複数宛先への一括送信

複数の宛先にメールを送信する場合は、以下のように実装します。

ruby# 複数宛先へのメール送信
def send_bulk_emails(recipients, subject, summary)
  recipients.each do |email|
    send_report_email(email, subject, summary)

    # サーバー負荷を考慮して少し待機
    sleep 1
  end

  puts "\n全#{recipients.size}件のメール送信が完了しました。"
end

使用例を見てみましょう。

ruby# 送信先リスト
recipients = [
  'manager@example.com',
  'sales-team@example.com',
  'director@example.com'
]

# 一括送信
send_bulk_emails(recipients, '【自動送信】売上集計レポート', summary)

これで、複数の担当者に自動でレポートメールを送信できるようになりました。

定期バッチ処理の実装

ステップ 1:メインスクリプトの作成

これまで作成した機能を統合し、1 つのスクリプトにまとめます。

ruby#!/usr/bin/env ruby
# daily_sales_report.rb - 日次売上レポート自動送信

require 'google/apis/sheets_v4'
require 'googleauth'
require 'mail'
require 'logger'

# ログ設定
LOGGER = Logger.new('logs/sales_report.log', 'daily')
LOGGER.level = Logger::INFO

設定情報を定数として定義します。

ruby# 設定情報
SPREADSHEET_ID = ENV['SPREADSHEET_ID'] || 'your_spreadsheet_id'
RANGE = '売上データ!A1:D1000'
RECIPIENTS = [
  'manager@example.com',
  'sales-team@example.com'
]

メイン処理を実行する関数を作成します。

ruby# メイン処理
def main
  LOGGER.info('===== 売上レポート作成開始 =====')

  begin
    # 1. スプレッドシートからデータ取得
    LOGGER.info('データ取得中...')
    data = get_spreadsheet_data(SPREADSHEET_ID, RANGE)
    LOGGER.info("取得データ件数: #{data.size - 1}件")

    # 2. データ集計
    LOGGER.info('データ集計中...')
    summary = aggregate_sales_data(data)

    # 3. メール送信
    LOGGER.info('メール送信中...')
    send_bulk_emails(RECIPIENTS, '【自動送信】売上集計レポート', summary)

    LOGGER.info('===== 売上レポート作成完了 =====')
  rescue StandardError => e
    LOGGER.error("エラーが発生しました: #{e.message}")
    LOGGER.error(e.backtrace.join("\n"))
  end
end

スクリプトを実行する部分です。

ruby# スクリプトが直接実行された場合のみ main を実行
if __FILE__ == $0
  main
end

これで、スクリプトを実行するだけで、データ取得から集計、メール送信までの一連の処理が自動で実行されます。

ステップ 2:whenever による定期実行設定

whenever Gem を使って、cron で定期実行する設定を行います。まず、設定ファイルを生成します。

bash# whenever の初期化
wheneverize .

生成された config​/​schedule.rb を編集します。

ruby# config/schedule.rb
# Ruby の実行環境を設定
set :output, 'logs/cron.log'
set :environment, 'production'

# 毎日午前9時に実行
every 1.day, at: '9:00 am' do
  command 'cd /path/to/your/project && ruby daily_sales_report.rb'
end

平日のみ実行する設定例です。

ruby# 平日の午前9時に実行
every :weekday, at: '9:00 am' do
  command 'cd /path/to/your/project && ruby daily_sales_report.rb'
end

毎週月曜日に実行する設定例です。

ruby# 毎週月曜日の午前10時に実行
every :monday, at: '10:00 am' do
  command 'cd /path/to/your/project && ruby weekly_sales_report.rb'
end

設定を cron に反映します。

bash# cron に設定を反映
whenever --update-crontab

現在の cron 設定を確認する場合は、以下のコマンドを使用します。

bash# cron 設定の確認
whenever --list

# または
crontab -l

ステップ 3:エラーハンドリングとログ管理

本番運用では、エラーハンドリングとログ管理が重要です。より堅牢なエラー処理を追加しましょう。

ruby# エラー通知付きのメイン処理
def main_with_notification
  LOGGER.info('===== 売上レポート作成開始 =====')

  begin
    # 処理の実行
    data = get_spreadsheet_data(SPREADSHEET_ID, RANGE)
    summary = aggregate_sales_data(data)
    send_bulk_emails(RECIPIENTS, '【自動送信】売上集計レポート', summary)

    LOGGER.info('===== 売上レポート作成完了 =====')
  rescue Google::Apis::Error => e
    # Google API 関連のエラー
    error_message = "Google API エラー: #{e.message}"
    LOGGER.error(error_message)
    send_error_notification(error_message)
  rescue Net::SMTPError => e
    # メール送信エラー
    error_message = "メール送信エラー: #{e.message}"
    LOGGER.error(error_message)
    send_error_notification(error_message)
  rescue StandardError => e
    # その他のエラー
    error_message = "予期しないエラー: #{e.message}"
    LOGGER.error(error_message)
    LOGGER.error(e.backtrace.join("\n"))
    send_error_notification(error_message)
  end
end

エラー通知を送信する関数を追加します。

ruby# エラー通知メールの送信
def send_error_notification(error_message)
  admin_email = 'admin@example.com'

  mail = Mail.new do
    from     'your-email@gmail.com'
    to       admin_email
    subject  '【エラー通知】売上レポート自動処理でエラーが発生しました'
    body     "以下のエラーが発生しました。\n\n#{error_message}\n\n確認をお願いいたします。"
  end

  begin
    mail.deliver!
  rescue StandardError => e
    # エラー通知自体が失敗した場合はログに記録
    LOGGER.error("エラー通知の送信に失敗: #{e.message}")
  end
end

ログローテーションの設定例です。

ruby# ログローテーション付きのロガー
def create_logger
  FileUtils.mkdir_p('logs')

  logger = Logger.new(
    'logs/sales_report.log',
    10,              # 保持するログファイル数
    1024 * 1024 * 5  # 各ファイルの最大サイズ(5MB)
  )

  logger.level = Logger::INFO
  logger.formatter = proc do |severity, datetime, _progname, msg|
    "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity}: #{msg}\n"
  end

  logger
end

以下の図は、エラーハンドリングのフローを示しています。

mermaidflowchart TD
    start["処理開始"] --> try["処理実行"]
    try --> check{"エラー<br/>発生?"}
    check -->|正常| success["処理完了<br/>ログ記録"]
    check -->|API エラー| api_error["Google API<br/>エラー処理"]
    check -->|SMTP エラー| smtp_error["メール送信<br/>エラー処理"]
    check -->|その他| other_error["その他<br/>エラー処理"]
    api_error --> notify["エラー通知<br/>メール送信"]
    smtp_error --> notify
    other_error --> notify
    notify --> log_error["エラーログ<br/>記録"]
    success --> task_end["終了"]
    log_error --> task_end

この図から、エラーの種類に応じた適切な処理が行われることが理解できるでしょう。

実行環境の構築

ディレクトリ構成

プロジェクトのディレクトリ構成は以下のようになります。

plaintextproject/
├── Gemfile                      # Gem の依存関係
├── Gemfile.lock                 # Gem のバージョン固定
├── credentials.json             # Google API の認証情報
├── daily_sales_report.rb        # メインスクリプト
├── config/
│   └── schedule.rb              # whenever の設定
├── logs/
│   ├── sales_report.log         # 処理ログ
│   └── cron.log                 # cron 実行ログ
└── lib/
    ├── spreadsheet_client.rb    # スプレッドシート処理
    ├── mail_sender.rb           # メール送信処理
    └── data_processor.rb        # データ集計処理

環境変数の設定

機密情報は環境変数として管理します。.env ファイルを作成しましょう。

bash# .env
SPREADSHEET_ID=your_spreadsheet_id_here
GMAIL_USER=your-email@gmail.com
GMAIL_PASSWORD=your-app-password
ADMIN_EMAIL=admin@example.com

環境変数を読み込むために dotenv Gem を追加します。

ruby# Gemfile に追加
gem 'dotenv'

スクリプトの先頭で環境変数を読み込みます。

rubyrequire 'dotenv/load'

SPREADSHEET_ID = ENV['SPREADSHEET_ID']
GMAIL_USER = ENV['GMAIL_USER']
GMAIL_PASSWORD = ENV['GMAIL_PASSWORD']

実践的な活用例

使用例 1:在庫管理アラート

在庫数が一定以下になったら自動で発注担当者にメールを送信する例です。

ruby# 在庫チェックと通知
def check_inventory_and_notify
  data = get_spreadsheet_data(SPREADSHEET_ID, '在庫!A1:C100')
  low_stock_items = []

  data[1..].each do |row|
    product_name = row[0]
    stock_count = row[1].to_i
    threshold = row[2].to_i

    # 在庫が閾値以下の商品を抽出
    if stock_count <= threshold
      low_stock_items << { name: product_name, count: stock_count }
    end
  end

  # 在庫不足商品がある場合は通知
  unless low_stock_items.empty?
    send_inventory_alert(low_stock_items)
  end
end

使用例 2:売上目標達成率レポート

月次の売上目標達成率を自動で計算してレポートする例です。

ruby# 売上目標達成率の計算
def calculate_achievement_rate
  data = get_spreadsheet_data(SPREADSHEET_ID, '月次売上!A1:C50')

  results = []
  data[1..].each do |row|
    name = row[0]
    target = row[1].to_f
    actual = row[2].to_f
    rate = (actual / target * 100).round(1)

    results << {
      name: name,
      target: target,
      actual: actual,
      rate: rate
    }
  end

  results
end

これらの例から、さまざまな業務シーンで Ruby の自動化を活用できることがわかりますね。

まとめ

Ruby を使った業務自動化について、スプレッドシート連携、メール配信、定期バッチ処理の実装方法を詳しく解説しました。

本記事で学んだポイントを振り返ります。

#ポイント内容
1スプレッドシート連携Google Sheets API で直接データを取得・更新できる
2メール配信mail Gem を使って簡単に自動メール送信が可能
3定期実行whenever Gem で直感的に cron 設定ができる
4エラーハンドリングログ管理とエラー通知で安定運用を実現
5環境変数管理機密情報を安全に管理できる

Ruby の豊富な Gem を活用することで、複雑な業務処理も短いコードで実装できます。手作業で時間を費やしていた業務を自動化すれば、より創造的な仕事に集中できるようになるでしょう。

まずは小さな自動化から始めて、徐々に範囲を広げていくことをおすすめします。本記事のコードをベースに、ぜひ皆さんの業務に合わせてカスタマイズしてみてください。

関連リンク