Anycaって何
DeNA SOMPO Mobilityが運営している個人間で車をシェアするカーシェアサービスです。
https://anyca.net/
興味のある人は下の招待URLから登録してくれると嬉しい。
https://anyca.net/invite?uid=103674&cpn_id=13&code=s660share
誰に宛てた記事か
こんな風に思っているオーナーさんに向けた記事です。
「予約状況を確認する時、アプリでしか確認出来ないのがめんどくさい」
「どうせならGoogleカレンダーで他のスケジュールと一緒に管理したい」
使用前提条件
Excelが使える人ならそんなに難しくはないです。
- Anycaからのお知らせをGmailで受け取っている
- Googleスプレッドシートの使い方を知ってるor調べられる
- GoogleスプレッドシートにGoogle Apps Scriptを埋め込む方法を知ってるor調べられる
- GoogleカレンダーのIDを知ってるor調べらえる
Anycaのシェア予約の仕組み
CtoCのサービスなので、ユーザーとしてはオーナーとドライバーが存在します。
予約の流れとして、まずドライバー側がAnycaアプリ上でオーナーに対し予約リクエストをします。
するとオーナー側にはアプリでの通知とメールでお知らせが届きます。
今回はこのメールを自動で拾い上げる事で予約情報を取得し、Googleカレンダーに登録していくようにします。
GmailでAnycaから予約通知メールを受信
↓
スプレッドシートに仕込んだスクリプトで自動検出
↓
スプレッドシートに予約情報書き出し
↓
書き出された情報を基にGoogleカレンダーに追加
って感じです。
#スプレッドシートの下準備
一行目に下記の通りラベル付けをしておきます。※しなくても動きます
メール受信日時 | タイトル | ドライバー名 | 車名 | 予約開始 | 予約終了 | カレンダー追加 |
---|---|---|---|---|---|---|
コードをドン
Anycaオーナーさんの役に立てば良いな、という記事なので詳しい解説は気が向いた時に加えるとして、コピペで使えるコードをさっさと貼ります。
コードはGmailから予約通知メールを抽出する関数と、スプレッドシートに記録されたデータからGoogleカレンダーに登録する関数の2つに分かれます。
// ----- ここから書き換え -----
から// ----- ここまで書き換え -----
までの部分は、各環境に合わせて書き換えて下さい。
function mailToSheet () {
// ----- ここから書き換え -----
// メールから取得した情報を書き出すスプレッドシートのURL
var sheet_url = 'https://docs.google.com/spreadsheets/d/hogeeeeeeeeeeeeeee/edit';
// 書き込むシート名
var sheet_name = 'シート1';
// Gmailの抽出条件
var mail_query = 'subject:【Anyca】予約リクエストが届きました';
// 存在チェック(既にシートに書き込み済のメールは処理しない(日付、件名の一致で判定))
var existence_check = true;
// ----- ここまで書き換え -----
var ss = SpreadsheetApp.openByUrl(sheet_url);
var sheet = ss.getSheetByName(sheet_name);
var existence_keys = fetchExistenceKeys();
var mail_data = fetchMailData();
for (var i = 0; item = mail_data[i]; i++) {
// 重複チェック 既存データと合致したらループ抜ける
if (existence_check && existsData(item)) {
continue;
}
// 重複なければ最終行に値を追加
sheet.appendRow(itemToRow(item));
}
function fetchExistenceKeys () {
var existence_keys = {};
var sheet_data = sheet.getDataRange().getValues();
for (var i = 0; row = sheet_data[i]; i++) {
existence_keys[generateKey(rowToItem(row))] = true;
}
return existence_keys;
}
function existsData (item) {
if (existence_keys[generateKey(item)]) {
return true;
}
return false;
}
function generateKey (item) {
var key = item['date'] + '_' + item['subject'];
// Logger.log(key);
return key;
}
function rowToItem (row) {
var item = {};
item['date'] = row[0];
item['subject'] = row[1];
item['driver'] = row[2];
item['car'] = row[3];
item['start'] = row[4];
item['end'] = row[5];
return item;
}
function itemToRow (item) {
var row = [];
row[0] = item['date'];
row[1] = item['subject'];
row[2] = item['driver'];
row[3] = item['car'];
row[4] = item['start'];
row[5] = item['end'];
return row;
}
function fetchMailData () {
var result = [];
var threads = GmailApp.search(mail_query);
for (var i = 0; it = threads[i]; i++) {
var messages = it.getMessages();
for (var j = 0; message = messages[j]; j++) {
var item = {};
item['date'] = message.getDate();
item['subject'] = message.getSubject();
var body = message.getPlainBody();
// 必要な行から余計な文字列を消去
var bodys= body.replace('ドライバーニックネーム:','').replace('カーシェア期間:','').replace('に予約リクエストが届きました。','');
// 改行を使って配列化する
var ary = bodys.split("\n");
// ドライバーの行を取得し文字を抽出
item['driver'] = ary[5].substring(0).replace('\r','').replace('<br>','');
// 車種の行を取得し文字を抽出
ary[1] = ary[1].slice(ary[1].indexOf("さんのクルマ、")+7);
item['car'] = ary[1].substring(0).replace('\r','').replace('<br>','');
// 予約時間の行を取得し開始時間/終了時間に分けて配列として格納
var reservation = ary[6].substring(0).replace('\r','').replace('<br>','').split("〜");
// 日時の書式変換をして格納
item['start'] = convertDateFormat(reservation[0]);
item['end'] = convertDateFormat(reservation[1]);
result.push(item);
}
}
return result;
}
function convertDateFormat (date) {
// 2018年08月11日(土)09:00 → 2018/08/11/09:00に書式変換して返すメソッド
// "年月日"を"/"に置換
date = date.replace("年","/").replace("月","/").replace("日","/");
// 曜日の括弧書き部分だけ除いて結合(前半11文字と後半5文字を合体)
var convertedDate = date.slice(0,11)+date.slice(-5);
return convertedDate;
}
}
function createEventFromSheet() {
// ----- ここから書き換え -----
var calendarId = "hugaaaaaaaaaaaaaaaa@group.calendar.google.com"
// ----- ここまで書き換え -----
var sheet, i, myevent, mystart, myend, added, driver, car;
sheet = SpreadsheetApp.getActiveSheet();
for(i = 1; i <= sheet.getLastRow(); i++) {
car = sheet.getRange(i, 4).getValue();
driver = sheet.getRange(i, 3).getValue();
myevent = "シェア予約"+"("+car+"/"+driver+")";
mystart = sheet.getRange(i, 5)
.getValue();
myend = sheet.getRange(i, 6)
.getValue();
added = sheet.getRange(i, 7).getValue();
if(added == "") {
thisevent = CalendarApp.getCalendarById(calendarId).createEvent(myevent, new Date(mystart), new Date(myend));
sheet.getRange(i, 7).setValue("追加済み");
}
}
}
#関数のトリガー
関数のトリガーは時間ベースで15分間隔とかで設定してください。
mailToSheet
とcreateEventFromSheet
の2種類の関数があるので、忘れずどちらもトリガー設定しましょう。
注意点
- メールの内容に変更があるとちゃんと動きません。(特にタイトル)
- 変更があった際はアップデートし、たい、と思ってる。(するとは言ってない)
- 変更しないようAnycaさんの方に向かって祈りましょう。
2022/5/13追記
Anycaからのメールを転送していて、転送先でこのスクリプトを使おうとすると動きません。
原因は転送されたメールは各項目(ドライバー名や日時)の書かれている位置(行)がズレるためです。
どうしても転送先で動かしたい時は良い感じにコードを書き換えて下さい…。
更にもう一工夫
私はIFTTTを使ってGoogleカレンダーに新規イベントが追加されると、LINE Notifyで家族のグループLINEに通知されるようにしています。
これだと毎回家族に「この日シェアあるから!」って言わなくて済むので楽ちんです。
ちなみにIFTTTを経由しなくても、GASで直接LINE Notifyで通知させる事も出来るみたいです。その辺はお好みで。
⇒Google Apps ScriptからLINE NotifyでLINEにメッセージを送る
あとは、Anycaと同じように予約情報はメールで来るけど、Googleカレンダーに自動登録したいよ~~~!!みたいなのがある場合、このスクリプトをベースに弄れば実現出来ます。
私の場合、同じ仕組みでオンライン英会話の予約管理もやってますね。
色々工夫して使ってみて下さい。Let's Anyca!!
参考記事
Gmailのメールをスプレッドシートに書き出すコードは下記記事を参考にさせて頂きました。
⇒スプレッドシートにGmailの内容を自動で書き込む