お金をかけずに問い合わせフォームを構築する方法

お金をかけずに問い合わせフォームを構築する方法

Tech
Rails
作成: 2025年3月9日 更新: 2025年5月7日

問い合わせフォームなど、無料で設けることはできないか、考えてみた。

  • 基本的にお金はかけたくない
  • が、問い合わせが入ったときは通知がほしい(メールがベスト)
  • 問い合わせ内容など、管理画面も自分では作りたくない

Google APIの準備

まずはGoogle Drive APIとGoogle Sheets APIを使えるようにしましょう。

Google Cloudでプロジェクトを作成後、サイドメニューから「APIとサービス」>「有効なAPIとサービス」を選択します。

その後は「Google Drive API」と「Google Sheets API」を検索し、それぞれ「有効にする」を押しましょう。

以下はDrive APIの方。すでに有効にした後の画像です。

サービスアカウントを作成する

Google CloudのAPIを使用するためのサービスアカウントを作成します。このサービスアカウントの認証情報を使用して、自分が用意したプログラムはスプレッドシートへ書き込みをすることになります。

「IAMと管理」>「サービスアカウント」の画面から作成ボタンを押し、お好みのサービスアカウント名を設定します。終わったら「完了」を押しましょう。

作成したサービスアカウントの詳細画面を開き、「鍵」のタブを表示させたら「キーを追加」>「新しい鍵を作成」を選択します。

特に理由がない場合はJSONでよいと思います。「作成」を押しましょう。これでサービスアカウントの認証情報がローカルにダウンロードされたと思います。

このファイルは大事にとっておきましょう。

サービスアカウントへの権限付与

サービスアカウントがスプレッドシートを利用できるように権限を付与します。書き込みが必要な場合は「編集」権限を付与しておきましょう。

対象のスプレッドシートから「共有」ボタンを押し、サービスアカウントの名前を入力して権限を付与します。普通にユーザーへ権限付与するやり方と同じです。

これでAPIを利用する準備が整いました!

google_drive gemを追加する

ここからはrailsの調整になります。まずはgoogle_driveのgemを追加しましょう。

$ bundle add --optimistic google_drive

サービスアカウントの情報を設定する

環境変数として配置するなど、いくつか方法はあると思いますが今回はcredentialsを使おうと思います。

先ほど取得したサービスアカウントのファイルの中身のうち、private_keyの部分をbase64でエンコードしておいてください。貼り付けたり、環境変数に含めるのに都合がいいです。

それをcredentialsの中に設定しておきます。

$ cat {サービスアカウントのjson}
{
  "type": "service_account",
  "project_id": "aaa",
  "private_key_id": "bbb",
  "private_key": "-----BEGIN PRIVATE KEY-----\n.....\n-----END PRIVATE KEY-----\n", << この中身をファイルとして保存
  "client_email": "ccc",
  "client_id": "ddd",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "eee",
  "universe_domain": "googleapis.com"
}

$ base64 -i {private_keyの値を記載したファイル}
成功するとエンコードしたものが出力される。それをコピー

$ EDITOR=vim bin/rails credentials:edit

エディタが立ち上がったら、base64でデコードした中身を設定して保存おきましょう。

google_drive:
  client_email: {ここにサービスアカウント名}
  private_key: {ここにbase64エンコードした内容}

Google Driveを利用するmoduleの作成

google_drive_connectableという名前で汎用moduleを作りました。これをincludeすればgoogle_drive_sessionを介してどのクラスからでもスプレッドシートへアクセスすることができます。

require 'google_drive'

module GoogleDriveConnectable
  def google_drive_session
    @google_drive_session ||= create_drive_session
  end

  private 

  def create_drive_session
    sio = StringIO.new({ client_email:, private_key: }.to_json)
    GoogleDrive::Session.from_service_account_key(sio, 'https://www.googleapis.com/auth/drive')
  end

  def client_email
    Rails.application.credentials.dig(:google_drive, :client_email)
  end

  def private_key
    Base64.decode64(Rails.application.credentials.dig(:google_drive, :private_key)).gsub('\\n', "\n")
  end
end

呼び出す方も書いてみましょう。あくまで一例です。スプレッドシートのidも先ほどのcredentialsに格納するようにしています。あとはこのクラスを任意の場所から呼び出して実行すればスプレッドシートへ書き込みをすることができます。

module Contacts
  class SpreadsheetWriter
    include GoogleDriveConnectable

    class << self
      def call(contact)
        new(contact).call
      end
    end

    def initialize(contact)
      @contact = contact
    end

    def call
      next_row = client_ws.num_rows + 1

      client_ws[next_row, 1] = Time.current.strftime('%Y/%m/%d %H:%M:%S')
      client_ws[next_row, 2] = @contact['name']
      client_ws[next_row, 3] = @contact['email']

      client_ws.save
    end

    private

    def client_ws
      @client_ws ||= create_client_ws
    end

    def create_client_ws
      google_drive_session.spreadsheet_by_key(sheet_id).worksheet_by_title(sheet_name)
    end

    def sheet_name
      'シート1'
    end

    def sheet_id
      Rails.application.credentials.dig(:google_drive, :sheet_id)
    end
  end
end

スプレッドシートの更新通知を有効にする

最後に問い合わせが入った際の通知をメールで受け取れるようにしておきましょう。

スプレッドシートのメニューから「ツール」>「通知設定」>「編集通知」を選択します。

あとは、通知の頻度やトリガーを設定して完了です。

このやり方ならデータベースを用意しなくても気軽かつ無料でデータを保存でき、通知も受け取ることが可能となります。

問い合わせフォームくらいの規模であれば、これでOKなケースは結構ありそうです。

ただし、通知の宛先はスプレッドシートのオーナーに限られてしまう制約があります。

複数のメールアドレスに送信したい場合は別の方法を採用することになるでしょう。