どんな予約完了メールでも自動でGoogleカレンダーへ登録する方法
はじめに
こんにちは。株式会社TERASSでコーポレートエンジニアをしているHayashiです。
Gmailに届いた予約完了メールを自動でGoogleカレンダーに登録できたら楽ですよね?
しかし標準機能だけだと上手く連携ができない・・そんな時のお話です。
標準機能で実現出来ないの?
実は下記のような予約メールは、標準で自動連携できるようになっています。
・フライト、列車、バスの予約
・ホテルやレストランの予約
・映画やコンサートなど、チケットが必要なイベント
しかし弊社は下記のような要件でして、標準機能では実現不可でした。
- オフィスにゲストが来る際に、外部サイトを通じて来訪予約いただいている。
- 予約メールは届くが、Googleカレンダーで確認できるようにしたい。
登録までの流れ
- Gmailに予約完了メールが届く
- Zapierを通して、Google Apps Scriptを呼び出す
- Googleカレンダーに予定が登録される
1.予約完了メールが届く
下記のようなメールが届くとします。
件名: 来訪登録のご案内
▼本文
○○オフィスへの来訪登録が完了しました。
<登録内容の詳細>
入館予約番号: A12345
ご来訪者: 株式会社○○ 山田 太郎 様
ご来訪日時:2023/09/01 14:30
2.Zapierを通して、Google Apps Scriptを呼び出す
さて、メールを受信したタイミングで、カレンダー登録処理を実行させる必要がありますが...
ここで使うのがZapierという自動化ツールです。
Zapierでは一つの自動化ワークフローを作るにあたり、TriggerとActionを定義します。
- Trigger:何をきっかけとして処理を開始するか
- Action:何をするか
ここでは下記のように定義します。
- Trigger:件名が「○○オフィスへの来訪登録が完了しました。」というメールが届いたら
- Action:Webhookであらかじめ作成したGASアプリケーションを実行する
3. Googleカレンダーに予定が登録される
GASアプリケーションの中でカレンダーの登録処理が走るわけですが、
参考までにGASの中身を紹介します。
カレンダー登録処理
今回、カレンダー登録を終えた予約完了メールは既読としてマークします。
そのためまず対象メールを「特定の件名」「未読」で絞り込みます。
const threads = GmailApp.search('{subject:○○オフィスへの来訪登録が完了しました。} is:unread');
しかしここで厄介なのが、Gmailはスレッドという仕組みを採用していることです。
一つのスレッドの中に、複数件のメッセージ(メール)が格納されています。
参考:https://blog.synnex.co.jp/google/gmail-gas/
上記のGmailApp.search()ではスレッドの配列が返却されるので、for文を使って各スレッドからメッセージを順に取り出して、カレンダーへ登録していきます。
const props = PropertiesService.getScriptProperties().getProperties();
const calendarID = props.calendarID;
const calendar = CalendarApp.getCalendarById(calendarID);
for (let i = 0; i < threads.length; i++) {
const messages = threads[i].getMessages();
for (let j = 0; j < messages.length; j++) {
const message = messages[j];
if (message.isUnread()) {
const body = message.getPlainBody();
// メール本文からゲスト情報を取得する
const name = body.match(/ご来訪者:(.*)様/)[0].slice(5).trim();
const date = body.match(/ご来訪日時:(.*)/)[0].slice(6).trim();
const reservationNum = body.match(/入館予約番号:(.*)/)[0].slice(7).trim();
// 予定登録に必要な情報を作成する
const title = `${name}_${reservationNum}`;
const startTime = new Date(date);
let endTime = new Date(date);
endTime.setHours(endTime.getHours() + 1);
// カレンダーに予定を追加
calendar.createEvent(title, startTime , endTime);
// 既読としてマーク
message.markRead();
}
}
}
Zapierから呼び出せるように
ZapierからのPOSTを受け取るため、doPost()を定義します。
function doPost(e) {
let jsonString = e.postData.getDataAsString();
let data = JSON.parse(jsonString);
(省略)
addEventFromEmail(); //カレンダー登録処理
return ContentService.createTextOutput('Success');
}
また最後に、Webアプリケーションとして公開します。
参考:https://auto-worker.com/blog/?p=3565
無事処理が成功すると
指定したGoogleカレンダーに予定が登録されます。
最後に
今回は処理のトリガーとしてZapierを利用しましたが、GAS単体で5~10分刻みで定期実行しても良いと思います。
またカレンダーの予定タイトルを「ゲスト名_予約番号」のようにすることで、予約変更メールや予約キャンセルメールにも対応できます。
例えば
- 「ゲスト名_予約番号」でGoogleカレンダー内を検索
- ヒットした予定を削除する
- (予約変更の場合) 新規日程で再登録する
気になった方はぜひ試してみてください。
Discussion