約5万名の実態調査データを、企業向け・個人向けレポートと予約獲得までつなぐ仕組みに
従業員の仕事と介護の両立を支援するサービスを提供している企業さまの、事業開発とAI実装の事例です。
サービス導入企業の従業員への実態調査から、企業向け・個人向けレポートの作成、専門員への相談予約まで、一連の業務を担当者に依存せず運用できる仕組みを整えました。
クライアント課題
仕事と介護の両立を支援するサービスを導入する企業が増えるにつれ、調査データの分析、数千件規模のレポート作成、相談予約を後押しする案内メールの配信、各社の進行管理といった業務が積み上がっていました。こうした業務を自動化し、導入企業が増えても対応できる運用にしたい、というのがご相談の内容です。
課題1|業務の進め方とデータがそろっていない
工程ごとの手順が担当者によって異なり、企業ごとに回答データの形式もばらばらでした。分析のたびに手作業で整える必要があり、複数の企業を同じ基準で比較・分析するのは難しい状態です。
課題2|レポートの作成が手作業だった
企業向けも従業員一人ひとりに返す個人向けも人が組み立てており、数千件の規模になると手が回りません。作成手順には人による差があり、送付前の確認方法や基準も統一されていない状況でした。
支援内容
課題1への支援|業務の進め方とデータをそろえる
01事業開発の伴走|業務フローの標準化とデータ分析基盤の構築
実態調査からレポート作成、相談予約までの業務フローを整理し、自動化する工程と人が判断する工程を切り分けました。導入企業が増えても同じ手順で運用できることを前提に、事業の進め方から設計しています。
データの面では、企業ごとに異なっていた回答データの整形・匿名化の手順を統一し、複数の企業を同じ基準で分析できる基盤を構築しました。従業員を介護の状況に応じて5つのセグメントに分類し、企業ごとの傾向を同じ基準で比較できる状態にしています。
02進行管理の効率化|41社分の工程を1画面に集約
01で整理した業務フローを日々の運用に落とし込むため、複数の資料に分散していた41社分の工程・タスク・担当状況を1つの画面に集約しています。
期限超過や担当者への偏りは自動で検知できるため、週次の進行確認も効率よく行えます。
課題2への支援|レポート作成を自動化し、相談予約までつなぐ
03企業向け・個人向けレポートの自動生成
01で整えた分析基盤をもとに、手作業で作成していた企業向けレポートをBIツール上で自動生成できるようにしました。調査データを読み込むと、グラフと本文を自動生成できる仕組みです。企業ごとに閲覧範囲を設定でき、報告会でもそのまま使用できる形で出力できます。
個人向けには、回答内容から介護のステージを判定し、一人ひとりに合わせたレポートを自動生成する仕組みを構築しました。検品は、数値をAIで自動チェックし、記述内容を人が確認する形に分けています。
04相談予約の促進|介護の状況に応じた案内メールの配信
支援はレポートの提供で終わらず、専門員への相談予約までを範囲に含めています。まず、専門員への相談内容80件をAIで分析し、17のカテゴリに整理しました。
その分析結果をもとに、介護の状況に応じた案内メールを作成し、5社へ配信しています。配信結果は企業別・状況別・時間帯別に振り返り、翌月の配信計画や文面の改善に反映する運用です。
成果
従業員一人ひとりに返す個人レポートは、1社分7,761件をエラー0件で生成しました。検品工程もあわせて標準化したため、他の導入企業にも同じ仕組みをそのまま展開できます。
実態調査では、10社・約5.1万名分の回答を同じ基準で分析できるようになり、企業間の比較や、支援が必要な層の抽出も行えるようになっています。
進行管理では、41社分の工程・タスク・担当状況を1画面に集約し、週次の確認を短時間で行えるようになりました。
使用技術:生成AI(Claude)、Python、BIツール、メール配信API、クラウド基盤
提供サービス:事業開発支援、業務設計、データ分析基盤構築、レポート自動生成、メール施策、進行管理ダッシュボード構築
【不動産RPA】マイソク図面作成の効率化を目的とした業務フロー再構築とプログラム開発(GAS,Spread Sheet等)
株式会社Giving Firstのコンサルティング事例を紹介します。
本プロジェクトでは、不動産仲介会社さまからのご依頼で、不動産物件の情報がひと目で分かるようにまとめられた図面資料(通称:マイソク)の作成業務に時間を要しており、どうにか効率化できないかとご相談がありました。
そこで、弊社にて現状の業務フローをヒアリングの上で可視化し、効率化できる箇所を特定し、プログラム開発による部分的自動化を実現したものです。
実施概要
不動産業界で広く使われている図面(マイソク)の作成を時短・効率化するショートプロジェクト。
もともとPower Pointで作成していた図面作成フローを、Google Spread Sheetに載せ替え。情報入力フォームを作成し、当該フォームとSpread SheetをGoogle App Scriptで連携し、効率化しました。
- 顧客:不動産仲介・売買会社
- メインシステム:Google Spread Sheet
- 関連・周辺システム:Google App Script(GAS)
- 担当領域
- 要件定義・基本設計・詳細設計・開発工程
- BPR(業務フローの分解と新規構築、活用する情報システムの提案・決定)
- システム開発(Java ScriptベースのGoogle App Script開発)
- RPA(最終的に出力される図面の自動出力)
プロジェクトのゴール
- 図面資料(通称:マイソク)の作成業務の効率化(時短)
- 作成した図面資料の一元管理
- 図面品質の統一・均一化
- 使いやすいシステムで実装し、複数のシステムをまたがないこと(→Spread Sheetで完結する仕組み)
本施策の効果
- 図面1枚あたりの作成時間:2時間→15分
- 出力ボタンを実行後、新規ファイルとして図面が出来上がり、Googleドライブに自動保存される
- テンプレート化により、マイソク図面の品質が統一され、大量作成も可能になった
支援内容
マイソク図面自動作成の入力フォーム
新規ファイルとして自動出力されたマイソク図面
- 業務フロー整理と再構築(BPR)
- 日頃使い慣れているGoogle Spread Sheetベースで完結する仕組み
- GASを使ったプログラム開発(ファイル出力、エラーハンドリング、全角数字→半角数字処理、フォントサイズ調整処理 etc)
不動産会社様で同じ悩みを抱えておられる場合は、弊社のお問合せフォームから実装したい旨をご相談ください。
\本件と同様のご相談も受け付けております/
【顧客管理RPA】formrun経由の顧客情報をSpread Sheetへ自動登録し、顧客ごとにユニークIDを自動採番するシステム構築
株式会社Giving Firstのコンサルティング事例を紹介します。
本プロジェクトでは、某有名YouTuberが運営するオンラインサロンの運営会社さまからのご依頼で、formrunおよびGoogle Spread Sheet上で管理しているものの、販促活動が盛況で、運用管理に苦難されていることから業務効率化支援として、Google Spread Sheetベースの自動化プログラムを構築し、ご支援させていただきました。
実施概要
formrunで申し込みがあった顧客を手動でSpread Sheet上で登録・管理しており、手作業による工数が肥大化。
formrunでの申込みをトリガーに、ユニークな顧客番号を自動採番したい、初回面談申し込み時のヌケモレを防ぐべく情報の記録を管理したい、流入経路を明示したい(どのLPからの流入なのか判別したい)等を課題に抱えておられました。
- 顧客:某有名YouTuberが運営するオンラインサロン運営会社
- メインシステム:formrun, Google App Script(GAS)
- 関連・周辺システム:Gmail
- 担当領域
- 基本設計・詳細設計・開発工程
- システム開発(Java ScriptベースのGoogle App Script開発による案件管理表への自動転記)
- RPA(Webhookを活用した社内Chatへの通知自動化)
プロジェクトのゴール
情報共有の円滑化と業務運営の効率化を目的に、社内ポータルサイトと周辺システムの構築、業務フローを定義することをゴールとして設定し、ご支援致しました。
- LPごと(=販促会社ごと)に分かれているフォームから登録される顧客をひとつのSpread Sheetに統一すること
- 販促会社が増えるたびに自動(もしくは半自動で)同じ仕組みで横展開できる運用体制を確立すること
- 顧客を判別できる仕組みを作ること(顧客IDを自動採番しSpread Sheetに登録する)
支援内容
- formrunからの通知メールをトリガーとしたGoogle Spread Sheetへの情報連携プログラム
- formrunでの設定変更(複数フォームをひとつの通知メールに設定)
- 顧客管理簿・案件管理(Google Spread Sheet)の構築
Google Spread Sheetへの自動反映プログラム
弊社で納品したプログラムをサンプルとしてご紹介します。
当該プログラムは、Google App Scriptで実装し、5分程度のポーリング間隔で実行します。
BtoC領域のサービスを展開されている企業様で同じようなお悩みを抱えておられる場合は、弊社のお問合せフォームからご相談ください。
プログラムの処理内容
- formrunからお問い合わせがあった際に受信する「通知メール」をトリガー
- 過去のメールを重複して処理しないように、メールIDをキーに重複排除
- 通知メールから取得した顧客情報を任意のGoogle Spread Sheetに自動転記する
- 初回面談の予約日時をJSTに変換し、Spread Sheet上で記録
- 問い合わせがあった顧客にユニークなIDを自動採番(100000を開始番号)
function extractAndWriteToSheet() {
// スプレッドシートとシートを指定
var spreadsheetId = 'XXXXX'; // スプレッドシートのIDを指定
var sheetName = 'Master'; // シート名を指定
var logSheetName = 'ProcessedEmails'; // 処理済みメールIDを記録するシート名
var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
var sheet = spreadsheet.getSheetByName(sheetName);
var logSheet = spreadsheet.getSheetByName(logSheetName);
// 処理済みメールIDシートが存在しない場合は作成
if (!logSheet) {
logSheet = spreadsheet.insertSheet(logSheetName);
logSheet.appendRow(['メールID']); // ヘッダー行
}
// 処理済みメールIDのリストを取得
var lastRow = logSheet.getLastRow();
var processedEmailIds = [];
if (lastRow > 1) { // ヘッダー行があるため、2行目以降にデータがあるかを確認
processedEmailIds = logSheet.getRange(2, 1, lastRow - 1, 1).getValues().flat();
}
// Gmailのフィルタリング条件
var threads = GmailApp.search('subject:トリガーとするメールタイトル');
// 各スレッド(メール)の処理
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var message = messages[j];
var messageId = message.getId();
// メールが既に処理されているかを確認
if (processedEmailIds.includes(messageId)) {
continue; // 既に処理されている場合はスキップ
}
var body = message.getPlainBody();
// 正規表現で特定の文字列を抽出
var teamName = body.match(/チーム名:(.+)/);
var formName = body.match(/フォーム名:(.+)/);
var receptionNumber = body.match(/受付番号:(.+)/);
var responseDate = body.match(/回答日時:(.+)/);
var email = body.match(/メールアドレス:(.+)/);
var name = body.match(/名前:(.+)/);
var phoneNumber = body.match(/電話番号:(.+)/);
var consultationQuestion = body.match(/個別相談会で特に聞きたいこと:(.+)/);
var reservationDate = body.match(/予約日程の選択:(.+)/);
var confirmationStatus = body.match(/日程調整の確定状況:(.+)/);
var startDate = body.match(/開始日時:(.+)/);
var endDate = body.match(/終了日時:(.+)/);
var timeZone = body.match(/タイムゾーン:(.+)/);
var applicationId = body.match(/申し込みID:(.+)/);
var reservationDetails = body.match(/予約詳細(※bookrunの管理画面に遷移します):(.+)/);
var coordinator = body.match(/担当者:(.+)/);
var meetingFormat = body.match(/受付完了時ミーティング形式を通知:(.+)/);
var location = body.match(/場所:(.+)/);
var offlineMeetingPlace = body.match(/オフラインミーティング場所名:(.+)/);
var offlineMeetingAddress = body.match(/オフラインミーティング住所:(.+)/);
var offlineMeetingNotes = body.match(/オフラインミーティング補足:(.+)/);
var videoMeetingUrl = body.match(/ビデオ会議URL:(.+)/);
var otherMeetingName = body.match(/その他ミーティング名:(.+)/);
var otherMeetingUrl = body.match(/その他ミーティングURL:(.+)/);
var otherMeetingNotes = body.match(/その他ミーティング補足:(.+)/);
var birthdate = body.match(/生年月日:(.+)/);
var inquiryPurpose = body.match(/お問い合わせ目的:(.+)/);
// 日時変換関数
function convertToJST(dateStr) {
if (!dateStr) return '';
var date = new Date(dateStr);
var jstDate = new Date(date.toLocaleString('en-US', { timeZone: 'Asia/Tokyo' }));
return Utilities.formatDate(jstDate, 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss');
}
var startDateJST = convertToJST(startDate ? startDate[1].trim() : '');
var endDateJST = convertToJST(endDate ? endDate[1].trim() : '');
// ユニークなIDを生成(既存の最後のID + 1)
var lastId = 100000;
if (sheet.getLastRow() > 1) { // シートが空でない場合
var lastIdRange = sheet.getRange("A2:A" + sheet.getLastRow()).getValues();
lastIdRange = lastIdRange.map(function(row) { return parseInt(row[0], 10); }).filter(function(id) { return !isNaN(id); });
if (lastIdRange.length > 0) {
lastId = Math.max(...lastIdRange);
}
}
var newId = lastId + 1;
// スプレッドシートに書き込む
var newRow = [
newId,
teamName ? teamName[1].trim() : '',
formName ? formName[1].trim() : '',
receptionNumber ? receptionNumber[1].trim() : '',
responseDate ? responseDate[1].trim() : '',
email ? email[1].trim() : '',
name ? name[1].trim() : '',
phoneNumber ? phoneNumber[1].trim() : '',
consultationQuestion ? consultationQuestion[1].trim() : '',
reservationDate ? reservationDate[1].trim() : '',
confirmationStatus ? confirmationStatus[1].trim() : '',
startDateJST,
endDateJST,
timeZone ? timeZone[1].trim() : '',
applicationId ? applicationId[1].trim() : '',
reservationDetails ? reservationDetails[1].trim() : '',
coordinator ? coordinator[1].trim() : '',
meetingFormat ? meetingFormat[1].trim() : '',
location ? location[1].trim() : '',
offlineMeetingPlace ? offlineMeetingPlace[1].trim() : '',
offlineMeetingAddress ? offlineMeetingAddress[1].trim() : '',
offlineMeetingNotes ? offlineMeetingNotes[1].trim() : '',
videoMeetingUrl ? videoMeetingUrl[1].trim() : '',
otherMeetingName ? otherMeetingName[1].trim() : '',
otherMeetingUrl ? otherMeetingUrl[1].trim() : '',
otherMeetingNotes ? otherMeetingNotes[1].trim() : '',
birthdate ? birthdate[1].trim() : '',
inquiryPurpose ? inquiryPurpose[1].trim() : ''
];
sheet.appendRow(newRow);
// 処理済みメールIDを記録
logSheet.appendRow([messageId]);
}
}
}
\本件と同様のご相談も受け付けております/
【不動産BPR/RPA】営業体制の構築と業務改善を目的とした顧客管理・自動記録通知プロセス構築(GAS,Spread Sheet等)
株式会社Giving Firstのコンサルティング事例を紹介します。
本プロジェクトでは、不動産仲介会社さまからのご依頼で、SUUMOやホームズといった不動産媒体系からのリードを一元管理し営業体制を強化・効率化することを目的に営業体制の組成とシステム構築をご支援させていただきました。
実施概要
不動産媒体サイトから流入するリードの顧客管理(ホットリード選別・追客・営業マンのステータス管理)の一元化・効率化を目的に、顧客管理を自動化する業務プロセスを構築しました。
- 顧客:不動産仲介・売買会社
- メインシステム:Google App Script(GAS)
- 関連・周辺システム:Google Spread Sheet、Gmail、Lark
- 担当領域
- 要求定義・要件定義・基本設計・詳細設計・開発工程
- BPR(業務フローの分解と新規構築、活用する情報システムの提案・決定、THE MODEL型の営業組織構築)
- システム開発(Java ScriptベースのGoogle App Script開発による案件管理表への自動転記)
- RPA(Webhookを活用した社内Chatへの通知自動化)
プロジェクトのゴール
情報共有の円滑化と業務運営の効率化を目的に、社内ポータルサイトと周辺システムの構築、業務フローを定義することをゴールとして設定し、ご支援致しました。
- リードの自動登録・管理(媒体サイト経由のリードを管理簿に自動登録する仕組み)
- リード発生時にタイムリーに対応できる仕組み(社内Chatへの即時通知)
- リード追客の営業体制構築(ISとしてのファーストコンタクト体制、内見フェーズのFSへのトスアップ体制etc)
支援内容
営業フロー図
ヒアリング工程後の課題/改善策一覧
KGI/KPI管理指標の分解
- 業務フロー整理と再構築(BPR)
- 経営課題・社内組織体制の課題抽出と改善策の提案
- 顧客管理簿・案件管理(Google Spread Sheet)の構築
- THE MODEL型の営業体制とシステムフローの構築(IS,FS,CS組成、組織体制に合わせたCRMシステム構築)
SUUMOリード獲得時のGoogle Spread Sheetへの自動反映プログラム
弊社で納品したプログラムをサンプルとしてご紹介します。
当該プログラムは、Google App Scriptで実装し、5分程度のポーリング間隔で実行します。
不動産会社様で同じ悩みを抱えておられる場合は、弊社のお問合せフォームから実装したい旨をご相談ください。
プログラムの処理内容
- SUUMOからお問い合わせがあった際に受信する「通知メール」をトリガー
- 通知メール内に記載されている顧客情報を取得
- 過去のメールを重複して処理しないように、メールIDをキーに重複排除
- 通知メールから取得した顧客情報を任意のGoogle Spread Sheetに自動転記する
function extractAndWriteToSheet() {
// スプレッドシートとシートを指定
var spreadsheetId = 'XXXXX'; // スプレッドシートのIDを指定
var sheetName = 'XXXXX'; // シート名を指定
var logSheetName = 'XXXXX'; // 処理済みメールIDを記録するシート名
var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
var sheet = spreadsheet.getSheetByName(sheetName);
var logSheet = spreadsheet.getSheetByName(logSheetName);
// 処理済みメールIDシートが存在しない場合は作成
if (!logSheet) {
logSheet = spreadsheet.insertSheet(logSheetName);
logSheet.appendRow(['メールID']); // ヘッダー行
}
// 処理済みメールIDのリストを取得
var lastRow = logSheet.getLastRow();
var processedEmailIds = [];
if (lastRow > 1) { // ヘッダー行があるため、2行目以降にデータがあるかを確認
processedEmailIds = logSheet.getRange(2, 1, lastRow - 1, 1).getValues().flat();
}
// Gmailのフィルタリング条件
var threads = GmailApp.search('subject:検索するメールの文字列');
// 各スレッド(メール)の処理
for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();
for (var j = 0; j < messages.length; j++) {
var message = messages[j];
var messageId = message.getId();
// メールが既に処理されているかを確認
if (processedEmailIds.includes(messageId)) {
continue; // 既に処理されている場合はスキップ
}
var body = message.getPlainBody();
// 正規表現で特定の文字列を抽出
var inquiryDate = body.match(/お問合せ日時:(.+)/);
var responseCode = body.match(/反響送付先コード:(.+)/);
var nameKanji = body.match(/名前(漢字):(.+)/);
var nameKana = body.match(/名前(カナ):(.+)/);
var email = body.match(/メールアドレス:(.+)/);
var tel = body.match(/TEL:(.+)/);
var fax = body.match(/FAX:(.+)/);
var contactMethod = body.match(/連絡方法:(.+)/);
var inquiryContent = body.match(/お問合せ内容:(.+)/);
var propertyType = body.match(/物件種別:(.+)/);
var propertyCode = body.match(/物件コード:(.+)/);
var propertyName = body.match(/物件名:(.+)/);
var companyPropertyCode = body.match(/貴社物件コード:(.+)/);
var nearestStation = body.match(/最寄り駅:(.+)/);
var busWalk = body.match(/バス/歩:(.+)/);
var location = body.match(/所在地:(.+)/);
var rent = body.match(/賃料:(.+)/);
var floorPlan = body.match(/間取り:(.+)/);
var area = body.match(/専有面積:(.+)/);
var propertyDetailLink = body.match(/物件詳細画面:(.+)/);
var inquiryComment = body.match(/お問合せ内容コメント:(.+)/);
// スプレッドシートに書き込む
var lastRow = sheet.getLastRow() + 1; // 新しい行に書き込む
sheet.getRange(lastRow, 1).setValue(inquiryDate ? inquiryDate[1].trim() : '');
sheet.getRange(lastRow, 2).setValue(responseCode ? responseCode[1].trim() : '');
sheet.getRange(lastRow, 3).setValue(nameKanji ? nameKanji[1].trim() : '');
sheet.getRange(lastRow, 4).setValue(nameKana ? nameKana[1].trim() : '');
sheet.getRange(lastRow, 5).setValue(email ? email[1].trim() : '');
sheet.getRange(lastRow, 6).setValue(tel ? tel[1].trim() : '');
sheet.getRange(lastRow, 7).setValue(fax ? fax[1].trim() : '');
sheet.getRange(lastRow, 8).setValue(contactMethod ? contactMethod[1].trim() : '');
sheet.getRange(lastRow, 9).setValue(inquiryContent ? inquiryContent[1].trim() : '');
sheet.getRange(lastRow, 10).setValue(propertyType ? propertyType[1].trim() : '');
sheet.getRange(lastRow, 11).setValue(propertyCode ? propertyCode[1].trim() : '');
sheet.getRange(lastRow, 12).setValue(propertyName ? propertyName[1].trim() : '');
sheet.getRange(lastRow, 13).setValue(companyPropertyCode ? companyPropertyCode[1].trim() : '');
sheet.getRange(lastRow, 14).setValue(nearestStation ? nearestStation[1].trim() : '');
sheet.getRange(lastRow, 15).setValue(busWalk ? busWalk[1].trim() : '');
sheet.getRange(lastRow, 16).setValue(location ? location[1].trim() : '');
sheet.getRange(lastRow, 17).setValue(rent ? rent[1].trim() : '');
sheet.getRange(lastRow, 18).setValue(floorPlan ? floorPlan[1].trim() : '');
sheet.getRange(lastRow, 19).setValue(area ? area[1].trim() : '');
sheet.getRange(lastRow, 20).setValue(propertyDetailLink ? propertyDetailLink[1].trim() : '');
sheet.getRange(lastRow, 21).setValue(inquiryComment ? inquiryComment[1].trim() : '');
// 処理済みメールIDを記録
logSheet.appendRow([messageId]);
}
}
}
\本件と同様のご相談も受け付けております/