とある話しの流れで、GASとLINE BOTを使ったGoogleカレンダー予約システムを作ることになった。
こちらの記事を参考にさせてもらい作れたのですが、複数人が同時にアクセスすると、キャッシュ管理が重なって、うまく動かないことがわかったので、直すことにしました。
今回紹介するLINE BOT+GASコードは、userIdごとにキャッシュを発行することに焦点を当てたコードになります。
userIdを渡したらuserIdごとにキャッシュを発行して、消去するクラスを作成します。
class EachCache {
constructor(userId) {
this.userId = userId;
this.keys = ["type", "tenki_today"];
// キャッシュを消去するときに使う
this.all_caches = this.keys.map((key, index, array) => {
return this.userId + key;
});
this.cache = CacheService.getScriptCache();
}
get(key) {
key = this.userId + key;
return this.cache.get(key);
}
put(key, value) {
key = this.userId + key;
this.cache.put(key, value);
}
cacheClear() {
this.cache.removeAll(this.all_caches);
}
// 確認ログ
log() {
return this.cache.getAll(this.all_caches);
}
}
LINEでの応答に使います。channelAccessTokenは、それぞれで発行したものを使ってください。
function reply(replyToken, message) {
var url = "https://api.line.me/v2/bot/message/reply";
UrlFetchApp.fetch(url, {
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + channelAccessToken, // <= それぞれ個別のトークン
},
"method": "post",
"payload": JSON.stringify({
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": message,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({ "content": "post ok" })).setMimeType(ContentService.MimeType.JSON);
}
ログをスプレッドシートに記録します。
function logToSheet(sheetName,text_1, text_2, text_3, text_4) {
// 対象のスプレッドシート を設定.
const sheet = SpreadsheetApp.openById('*************************'); // それぞれ個別のスプレッドシートID
const targetSheet = sheet.getSheetByName(sheetName);
var lastRow = targetSheet.getLastRow();
// 更新日時を取得
var time = Utilities.formatDate(
new Date(),
'Asia/Tokyo', 'yyyy/MM/dd H:mm'
);
SpreadsheetApp.flush(); // スプレッドシートの再描画
targetSheet.getRange(lastRow + 1, 1).setValue(time.toLocaleString());
targetSheet.getRange(lastRow + 1, 2).setValue(text_1);
targetSheet.getRange(lastRow + 1, 3).setValue(text_2);
targetSheet.getRange(lastRow + 1, 4).setValue(text_3);
targetSheet.getRange(lastRow + 1, 5).setValue(text_4);
SpreadsheetApp.flush(); // スプレッドシートの再描画
}
上記のfunctionを使い、doPost(e)します。
節目ごとにログをシートに記録します。 全ての処理が終わったら、それぞれのuserIdに紐づいたcacheのみを消去します。
function doPost(e) {
var data = JSON.parse(e.postData.contents);
var lineType = data.events[0].type;
var reply_token = data.events[0].replyToken;
var uid = data.events[0].source.userId;
var displayName = getDisplayName(uid);
var message = data.events[0].message.text;
if (typeof reply_token === undefined || lineType === 'follow' || lineType === 'unfollow') {
return;
}
var eachCache = new EachCache(uid);
logToSheet('log', message, 'eachCache.log()', eachCache.log());
var type = eachCache.get("type");
logToSheet('log', message, 'type == undefined', type == undefined);
if (type == undefined && message !== 'キャンセル') {
var text = displayName + 'さん、こんにちは\n今日の天気は?';
var type = eachCache.put("type", 0);
reply(reply_token, text);
logToSheet('log', message, 'eachCache.log()', eachCache.log());
} else {
if (message === 'キャンセル') {
var text = 'キャンセルしました';
eachCache.cacheClear();
reply(reply_token, text);
logToSheet('log', message, 'eachCache.log()', eachCache.log());
} else {
switch (type) {
case '0':
eachCache.put('type', '1');
eachCache.put('tenki_today', message);
var text = '『' + message + '』' + 'ですね、' + '今の気分は?';
reply(reply_token, text);
logToSheet('log', message, 'eachCache.log()', eachCache.log());
break;
case '1':
var tenki_today = eachCache.get('tenki_today');
var text = '今日の天気は『' + tenki_today + '』' + 'で、\n気分は' + '『' + message + '』' + 'ですね!';
text += '\nお疲れ様です!'
reply(reply_token, text);
eachCache.cacheClear(); // 処理が終了したので、userIdに紐づいたcacheを消去
logToSheet('log', message, 'eachCache.log()', eachCache.log());
break;
}
}
}
}
上記のコードを参考にすれば、googleカレンダーを共有して予約することのできるLINE BOTが作れると思います。
LINE BOTの作り方やMessagingAPIの利用の仕方など省略してしまいましたが、それぞれ検索してもらえればわかりやすいサイトがありますので、そちらを参考にしてください。
可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More