業務自動化

ネイルサロンの顧客カルテ管理をGASで自動化、リマインド送信で予約率アップ

美容 の業務自動化レシピ
業種美容
ツールGoogle Apps Script
難易度★★☆ 中
設定時間約 120 分

ネイルサロンの顧客カルテと次回予約の案内を、Google Apps Script(GAS)で整理・自動化する方法を紹介します。スプレッドシートに顧客情報と施術履歴をまとめ、条件に合う顧客へリマインドメールを送信します。無料枠で小さく始め、作業時間と予約状況を確認しながら導入できます。

読了時間: 約18分

この記事のポイント

編集長の見解: リマインドの自動化は、予約率の改善とスタッフの負担軽減を同時に検討できる施策です。予約率10〜20%向上という数値は、編集部の試算であり、すべてのサロンに当てはまるものではありません。顧客数や来店周期を記録し、1か月程度のテストで自店の効果を確認しましょう。


ネイルサロンの顧客管理で抱える3つの課題

ネイルサロンでは、顧客情報や施術履歴の管理が接客品質に影響します。特に、紙カルテと複数のファイルを併用すると、必要な情報を探す時間が増えます。

課題1: 紙のカルテや表計算ファイルによる情報散在

顧客情報が、紙のカルテや表計算ファイル、スタッフ個人のメモに分かれていると、確認に時間がかかります。

前回のジェルの色味や施術内容を確認できないと、「前回と同じデザイン」という要望にも対応しにくくなります。

課題2: 次回予約のリマインド漏れによる予約機会の減少

リマインドを手作業で行うと、次のような問題が起きます。

施術後に推奨日を記録していても、その日に合わせて連絡する作業は、スタッフの記憶に頼りがちです。

課題3: 施術履歴の確認に時間がかかる

施術前のカルテ確認には、顧客1人あたり数分かかることがあります。1日に10人を担当する場合、1日あたり約30分〜50分のロスになる可能性があります。

確認時間を減らせれば、施術や顧客との会話に時間を振り向けられます。

⚠️ 放置するとどうなるか: 顧客管理の非効率は、予約機会の損失につながる可能性があります。編集部の試算では、リマインド漏れによる予約率低下が月間売上の10〜15%に相当するケースもあります。ただし、実際の影響は客単価や来店周期、既存の予約方法によって変わります。

次は、こうした課題を解決するGASの全体構成を確認します。


GASで作る顧客カルテ管理システムの全体像

Google Apps Script(GAS)は、Googleが提供するスクリプト実行環境です。スプレッドシートやGmailなどのサービスを連携できます。

スプレッドシートをデータベースとして使う構成

GASでは、特別なサーバーやデータベースを用意せず、スプレッドシートをデータ保管場所として使えます。

【システム構成図】

Googleスプレッドシート
├── 顧客マスターシート
├── 施術履歴シート
└── 予約管理シート

Google Apps Script
├── データ読み込み
├── リマインド対象の抽出
└── メール送信

Gmail
└── 顧客へのリマインドメール

主な利点は次のとおりです。

3シートの役割

シートを役割ごとに分けると、データを整理しやすくなります。

シート名役割主なデータ項目
顧客マスター顧客の基本情報を管理顧客ID、氏名、電話番号、メールアドレス、初回来店日
施術履歴施術内容を記録日付、施術メニュー、使用ジェル、料金、次回推奨日
予約管理予約と送信状況を管理予約日時、顧客ID、メニュー、ステータス、送信日

この構成なら、「誰が」「いつ」「どんな施術を受け」「次回はいつか」をまとめて確認できます。

GASとGmailが連携する流れ

GASは、シートからデータを読み込みます。その後、条件に合う顧客を抽出し、Gmailでメールを送信します。

function sendReminderEmails() {
  // 1. スプレッドシートを開く
  // 2. 次回推奨日が近い顧客を抽出
  // 3. 顧客マスターからメールアドレスを取得
  // 4. Gmailでメールを送信
  // 5. 送信記録を予約管理シートに追記
}

💡 ポイント: 最初はリマインドメールの送信だけを実装しましょう。運用に慣れてから、施術履歴の記録や予約状況の更新を追加すると、作業を分けて確認できます。

まずは3シートを作り、次に各項目を設定します。


スプレッドシートの設計と初期設定

GASを実装する前に、データを格納するシートを作ります。最初に項目を決めておくと、後の修正を減らせます。

顧客マスターシート

顧客マスターには、顧客の基本情報を登録します。

カラム名データ例説明
顧客IDC001顧客を識別するID
氏名山田 花子顧客名
電話番号090-1234-5678連絡先
メールアドレスhanako@example.com送信先
生年月日1985/5/15年齢層や誕生日施策に利用
初回来店日2025/3/10顧客歴の把握
アレルギー情報ジェルアレルギー施術時の注意点
備考左利き接客時の参考情報

顧客IDは、C001のように「C + 3桁の連番」にすると、他のシートと紐付けやすくなります。

施術履歴シート

施術履歴には、来店ごとの内容を記録します。

カラム名データ例説明
施術IDT001施術記録を識別するID
顧客IDC001顧客マスターとの紐付け
施術日2025/6/10施術を行った日
施術メニュージェルネイル(ワンカラー)施術内容
使用ジェルベージュ系使用した材料
料金¥6,000施術料金
次回推奨日2025/7/1次回の来店推奨日
施術メモ甘皮処理を丁寧にスタッフ向けメモ

施術履歴は、1回の来店につき1行を追加します。顧客IDをキーに、顧客マスターと紐付けます。

予約管理シート

予約管理には、予約情報とメールの送信状況を記録します。

カラム名データ例説明
予約IDR001予約を識別するID
顧客IDC001顧客マスターとの紐付け
予約日時2025/7/1 14:00予約日時
施術メニュージェルネイル(フレンチ)予約内容
ステータス確定 / 完了 / キャンセル予約状態
リマインド送信日2025/6/20送信した日
リマインド種別初回 / 再送送信区分

なお、元の項目名にあった「リマンド送信日」は、「リマインド送信日」に統一します。

プルダウンで入力ミスを減らす

スプレッドシートの「データ入力規則」を使うと、表記ゆれを抑えられます。

// スプレッドシートのメニューから
// 「データ」→「データ入力規則」を選択
// 条件に「プルダウン」を指定し、項目を登録

💡 時短テクニック: 項目を列全体に適用すると、新しい顧客を追加したときも入力形式をそろえやすくなります。設定後は、実際に入力して動作を確認してください。

次は、シートのデータを読み込むGASを実装します。


GASスクリプトの実装手順

スプレッドシートの「拡張機能」から「Apps Script」を開きます。まずは顧客情報を読み込む関数を作成します。

顧客データを読み込む関数

function getSpreadsheet() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const customerSheet = ss.getSheetByName('顧客マスター');
  const historySheet = ss.getSheetByName('施術履歴');
  const bookingSheet = ss.getSheetByName('予約管理');

  return { ss, customerSheet, historySheet, bookingSheet };
}

function getAllCustomers() {
  const { customerSheet } = getSpreadsheet();
  const lastRow = customerSheet.getLastRow();

  if (lastRow < 2) return [];

  const dataRange = customerSheet.getRange(2, 1, lastRow - 1, 8);
  const values = dataRange.getValues();

  return values.map(row => ({
    customerId: row[0],
    name: row[1],
    phone: row[2],
    email: row[3],
    birthDate: row[4],
    firstVisit: row[5],
    allergy: row[6],
    notes: row[7]
  }));
}

この関数と同じ考え方で、施術履歴や予約情報も読み込めます。

施術履歴を追記する関数

function addTreatmentRecord(
  customerId,
  treatmentDate,
  menu,
  gel,
  price,
  nextRecommendDate,
  memo
) {
  const { historySheet } = getSpreadsheet();
  const lastRow = historySheet.getLastRow();
  const newRow = lastRow + 1;

  const treatmentId = 'T' + String(newRow - 1).padStart(3, '0');

  historySheet.getRange(newRow, 1).setValue(treatmentId);
  historySheet.getRange(newRow, 2).setValue(customerId);
  historySheet.getRange(newRow, 3).setValue(treatmentDate);
  historySheet.getRange(newRow, 4).setValue(menu);
  historySheet.getRange(newRow, 5).setValue(gel);
  historySheet.getRange(newRow, 6).setValue(price);
  historySheet.getRange(newRow, 7).setValue(nextRecommendDate);
  historySheet.getRange(newRow, 8).setValue(memo);
}

手動実行のほか、フォーム入力と連携して記録する方法もあります。

リマインド対象を抽出する関数

次回推奨日が3日後から14日後までの顧客を対象にします。

function getReminderTargets() {
  const { historySheet } = getSpreadsheet();
  const lastRow = historySheet.getLastRow();

  if (lastRow < 2) return [];

  const dataRange = historySheet.getRange(2, 1, lastRow - 1, 8);
  const values = dataRange.getValues();
  const today = new Date();
  const targets = [];

  values.forEach(row => {
    const nextRecommendDate = new Date(row[6]);
    const diffDays = Math.ceil(
      (nextRecommendDate - today) / (1000 * 60 * 60 * 24)
    );

    if (diffDays >= 3 && diffDays <= 14) {
      const customerId = row[1];
      const customer = findCustomerById(customerId);

      if (customer && !hasBooking(customerId)) {
        targets.push({
          customer,
          treatment: row[3],
          nextRecommendDate,
          diffDays
        });
      }
    }
  });

  return targets;
}

function findCustomerById(customerId) {
  const customers = getAllCustomers();
  return customers.find(customer => customer.customerId === customerId);
}

function hasBooking(customerId) {
  const { bookingSheet } = getSpreadsheet();
  const lastRow = bookingSheet.getLastRow();

  if (lastRow < 2) return false;

  const dataRange = bookingSheet.getRange(2, 1, lastRow - 1, 6);
  const values = dataRange.getValues();

  return values.some(row => {
    return row[1] === customerId && row[4] === '確定';
  });
}

リマインドメールを送信する関数

抽出した顧客へ、Gmailでメールを送信します。

function sendReminderEmails() {
  const targets = getReminderTargets();
  const { bookingSheet } = getSpreadsheet();
  const today = new Date();
  let sentCount = 0;

  targets.forEach(target => {
    const customerName = target.customer.name;
    const email = target.customer.email;
    const treatment = target.treatment;
    const nextDate = Utilities.formatDate(
      target.nextRecommendDate,
      'Asia/Tokyo',
      'M月d日'
    );
    const salonName = 'あなたのサロン名';

    const subject = '【' + salonName + '】次回のご予約はいかがですか?';

    const body =
      customerName + ' 様\n\n' +
      'いつも' + salonName + 'をご利用いただきありがとうございます。\n\n' +
      '前回は「' + treatment + '」の施術をいたしました。\n' +
      '次回のご来店推奨日は ' + nextDate + ' となっています。\n\n' +
      'お手すきの際に、ご予約はいかがでしょうか?\n\n' +
      'ご予約は以下の方法で承っています。\n' +
      '・電話: 03-1234-5678\n' +
      '・ネット予約: https://example.com/\n\n' +
      '配信停止をご希望の場合は、このメールにご返信ください。\n\n' +
      'ご来店を心よりお待ちしております。\n\n' +
      salonName + ' スタッフ一同';

    try {
      GmailApp.sendEmail(email, subject, body);
      sentCount++;

      const lastRow = bookingSheet.getLastRow();
      const newRow = lastRow + 1;

      bookingSheet.getRange(newRow, 1)
        .setValue('R' + String(newRow - 1).padStart(3, '0'));
      bookingSheet.getRange(newRow, 2).setValue(target.customer.customerId);
      bookingSheet.getRange(newRow, 3).setValue('');
      bookingSheet.getRange(newRow, 4).setValue('');
      bookingSheet.getRange(newRow, 5).setValue('リマインド送信済');
      bookingSheet.getRange(newRow, 6).setValue(today);
      bookingSheet.getRange(newRow, 7).setValue('初回');
    } catch (e) {
      console.log(
        '送信エラー: ' +
        customerName +
        ' (' +
        email +
        ') - ' +
        e.message
      );
    }
  });

  console.log('リマインドメールを ' + sentCount + ' 件送信しました');
  return sentCount;
}

⚠️ テスト送信の重要性: 本番運用の前に、テスト用のメールアドレスで動作を確認してください。Gmailの送信上限は、無料アカウントで1日100件、Google Workspaceで1日1,500件が目安です。仕様変更の可能性があるため、利用前に公式情報を確認しましょう。

トリガーで毎日自動実行する

トリガーは、指定した時刻に関数を実行する仕組みです。次のコードを初回だけ実行します。

function setupTrigger() {
  const triggers = ScriptApp.getProjectTriggers();
  triggers.forEach(trigger => ScriptApp.deleteTrigger(trigger));

  ScriptApp.newTrigger('sendReminderEmails')
    .timeBased()
    .atHour(10)
    .everyDays(1)
    .inTimezone('Asia/Tokyo')
    .create();
}

この関数を実行すると、以降は毎日午前10時ごろにメールを送信します。実行時刻は一定の幅を持つため、厳密な時刻指定が必要な場合は仕様を確認してください。

💡 トリガーの確認: スプレッドシートのタイムゾーンと、GASの設定を日本時間にそろえます。設定後は、テスト用データで送信対象と送信記録を確認してください。

次は、予約につながりやすい文面と配信方法を確認します。


リマインドメールの文面設計

自動送信でも、顧客にとって分かりやすい内容でなければ予約につながりません。件名、本文、配信頻度を分けて考えます。

件名のパターン

パターン件名例特徴
予約案内型【サロン名】次回のご予約はいかがですか?目的が伝わりやすい
期間案内型【サロン名】7月のご予約受付中です時期を示せる
メンテナンス案内型【サロン名】ネイルのメンテナンス時期です顧客の予定に寄り添える
感謝型【サロン名】先月はご来店ありがとうございました関係性を意識できる

件名には、次の要素を入れます。

顧客名と施術内容を入れる

顧客名や前回の施術内容を入れると、内容を自分向けだと認識しやすくなります。編集部の調査では、個別化した文面は一括文面より開封されやすい傾向が見られました。ただし、効果は配信対象や件名、顧客との関係によって変わるため、自店のデータで確認しましょう。

本文には、次の情報を入れます。

予約方法を明記する

メールの最後には、顧客が次に取る行動を明記します。

予約システムがない場合は、Googleフォームを予約受付に使う方法もあります。個人情報を扱うため、フォームの公開範囲と回答データの権限を確認してください。

💡 予約リンクの作成: 予約システムのURLを使うのが基本です。Googleフォームを使う場合は、入力項目を必要最小限にし、回答データを閲覧できる人も限定しましょう。

配信頻度とタイミング

編集部が推奨する配信タイミングは、次の3段階です。

配信タイミング時期目的
初回リマインド施術後2週間次回予約を検討してもらう
再リマインド施術後3週間反応がない顧客へ再案内する
直前リマインド推奨日の1週間前予約を具体的に検討してもらう

配信しすぎると負担になるため、月2〜3回程度を目安にし、配信停止の希望には速やかに対応します。

次は、顧客情報を扱う際の法令と安全管理を確認します。


編集部の警告: 個人情報保護とセキュリティ対策

顧客の氏名、連絡先、施術履歴は個人情報に該当し得ます。実際の運用では、個人情報保護法や自店のプライバシーポリシーを確認してください。

個人情報保護法への対応

個人情報保護法では、個人情報を扱う事業者に一定の義務があります。

条文の適用関係は事業形態や情報の種類で変わるため、次の条文を確認し、必要に応じて専門家へ相談してください。

ネイルサロンでは、次のような運用を検討します。

対応項目具体的な対応
利用目的の明示顧客管理、施術履歴管理、リマインド連絡のためと説明
同意の取得リマインド配信に関する同意を確認
開示請求への対応問い合わせ窓口と対応手順を決める
保管期間目的を終えた情報を削除する基準を決める

共有設定とアクセス権限

スプレッドシートの共有範囲は、必要最小限にします。

// スプレッドシートの「共有」から設定
// 推奨: 特定のユーザーを追加し、必要な権限だけを付与

GASを共有するときの注意点

GASを他者と共有する場合は、スクリプトに顧客情報や認証情報が含まれていないか確認します。

function setProperties() {
  const props = PropertiesService.getScriptProperties();

  props.setProperty('SALON_NAME', 'あなたのサロン名');
  props.setProperty('CONTACT_PHONE', '03-1234-5678');
  props.setProperty('BOOKING_URL', 'https://example.com/');
}

function getProperty(key) {
  const props = PropertiesService.getScriptProperties();
  return props.getProperty(key);
}

⚠️ 重要な注意点: 顧客情報を含むスプレッドシートやスクリプトを一般公開しないでください。共有前に、個人情報や機密情報が残っていないか確認し、テスト用データで動作を検証します。

次は、導入時に起きやすい失敗と対策を見ていきます。


編集部の警告: 失敗しがちな導入パターン

GASの導入は比較的始めやすい一方、運用ルールが曖昧だと定着しません。代表的な失敗を3つ紹介します。

失敗パターン1: 既存データを移行せず二重管理になる

原因: 紙カルテや既存ファイルを残したまま、新しいシートを使い始める。

結果: どの情報が最新か分からず、新システムの利用が止まります。

回避策:

失敗パターン2: トリガー設定を忘れる

原因: スクリプトを作っただけで、自動実行の設定をしていない。

結果: リマインドメールが送信されず、手作業に戻ります。

回避策:

function checkTrigger() {
  const triggers = ScriptApp.getProjectTriggers();

  if (triggers.length === 0) {
    console.log(
      'トリガーが設定されていません。setupTrigger()を実行してください。'
    );
    return;
  }

  triggers.forEach(trigger => {
    console.log(
      'トリガー: ' +
      trigger.getHandlerFunction() +
      ' / 種類: ' +
      trigger.getTriggerSource()
    );
  });
}

失敗パターン3: 一方的な文面で負担をかける

原因: 「予約してください」と強く促す内容だけを送る。

結果: 顧客がメールを負担に感じ、配信停止や離反につながる可能性があります。

回避策:

編集長の見解: リマインドメールは、顧客が来店時期を思い出すための支援です。売上だけを目的にせず、顧客が負担なく予約方法を選べる文面にすることが、長期的な関係づくりにつながります。

次は、送信後の予約状況を測り、改善する方法を確認します。


導入効果の測定と改善サイクル

導入後は、送信数だけでなく予約につながったかを確認します。まずは1か月分のデータを集めると、改善点を考えやすくなります。

予約転換率を測定する

予約転換率は、次の式で計算します。

予約転換率 = 送信後2週間以内に予約が入った顧客数 ÷ 送信した顧客数 × 100

指標定義測定方法
予約転換率送信後に予約した顧客の割合送信記録と予約記録を照合
開封率メールを開いた割合利用中のメール配信サービスの機能で確認
クリック率予約リンクを押した割合予約システムや計測機能で確認
再来店率再来店した顧客の割合施術履歴から算出

個人向けGmailの通常送信では、開封率を正確に確認できない場合があります。レポート機能の有無は、利用中のサービスで確認してください。

改善サイクルを回す

効果が低い場合は、件名、本文、配信時期を一度に変えず、1項目ずつ試します。

段階行うこと
計画改善仮説を立てる件名に月を入れる
実行変更して送信する「7月の予約受付中」に変更
確認数値を比較する予約転換率を比較
改善良い方法を残す効果があれば次回も使う

編集長の見解: 大切なのは、メールを送った件数ではなく、顧客が予約しやすくなったかです。まず1か月記録し、予約転換率や配信停止数を確認してから、文面や時期を調整しましょう。

次は、顧客数や費用に関するよくある質問に答えます。


よくある質問

GASの無料枠で何人まで対応できるか

GASとGmailには、利用アカウントに応じた上限があります。

編集部の試算では、顧客500名程度で、1日10〜20件のリマインド送信なら運用を始めやすい規模です。ただし、実際の送信数や処理時間はデータ量と処理内容で変わります。

予約システムと併用できるか

併用できます。予約システムを受付に使い、GASを施術履歴やリマインドに使うなど、役割を分けます。

機能予約システムGAS構成
予約受付
顧客カルテ管理
リマインド送信
施術履歴

予約システムからCSVでデータを出力できる場合は、スプレッドシートに取り込む方法もあります。利用規約と個人情報の取り扱いを確認してください。

スマートフォンから操作できるか

Googleスプレッドシートのアプリで、データの閲覧や簡単な編集ができます。コードの作成やトリガー設定は、パソコンで行う方が安全です。

エラーが出た場合の対処法

エラー主な原因対処法
スクリプトがタイムアウトデータ量が多い処理を分割する
メール送信に失敗送信上限に達した送信数と上限を確認する
シートが見つからないシート名が異なるシート名をそろえる
権限がない初回認証が未完了権限を確認する

エラーが出たら、GASエディターの実行ログを確認します。テスト用データで再現し、原因を切り分けてください。

次は、公式情報と導入時に役立つ資料を紹介します。


参考情報と次のステップ

GASの仕様や送信上限は変更される可能性があります。実装前に公式情報を確認してください。

Google Apps Script

Googleスプレッドシート

Gmailの送信上限

最新の制限は、Google公式ヘルプで確認してください。

アカウント種別1日あたりの送信上限の目安備考
無料のGoogleアカウント100件個人利用向け
Google Workspace1,500件プランにより異なる

送信上限以外にも、次の点に注意します。

編集長の見解: この仕組みは、ネイルサロンが小さく始められる業務改善の土台です。まずはテスト用シートで動作を確認し、少人数の顧客を対象に運用します。効果と負担を確かめたうえで、対象顧客を段階的に広げていきましょう。


まとめ: GASでネイルサロンの予約管理を改善する

本記事では、GASで顧客カルテと施術履歴を管理し、リマインドメールを自動送信する方法を紹介しました。

手順内容所要時間の目安
13シートを作成30分
2項目とプルダウンを設定30分
3GASを実装60分
4トリガー設定とテスト送信30分
5既存データを移行状況による

既存データの移行を除けば、導入作業は合計2〜3時間が目安です。月額費用を抑えながら、次の改善を試せます。

編集部の試算では、1日30分の確認作業を20営業日削減できた場合、月約10時間の短縮になります。ただし、実際の効果はサロンの人数や運用方法によって変わります。

まずはテスト用のスプレッドシートで動かし、送信内容と個人情報の扱いを確認してください。問題がなければ、少人数の顧客から実運用へ移行しましょう。

Mira / AI経営ラボ 編集長