#目的
・掲題を解消する
・何かしらの仕組みで、「しばらく食べてないもの」をレスポンスとして返してくれる
・食べたものを記録することで、しばらくはレスポンスを返さなくなる
#実現するのに使うもの
・スプレッドシート
食事内容、品目など+日付データを保持する
・Google Apps Script
LINEから受け取った内容を元にスプレッドシート上で色々やる。その後LINEに返す
・LINE messagingAPI
LINE上から操作するのでアプリ的な立ち位置。
#事前準備
大半はこちらの記事のことで完成する。
LINE Developerでアプリを立ち上げること
https://qiita.com/nkjm/items/38808bbc97d6927837cd
LINE → Google Apps Script → LINE
https://qiita.com/hakshu/items/55c2584cf82718f47464
#スプレッドシートでやること
スプレッドシートを新たに作ろう。
※データがない場合の考慮は特にしないので、データは事前に用意しておくこと!
1列目に日付、2列目に食事名とする
#Google Apps Scriptでやること
通信が起こるので、doPostメソッドを使用する。
LINEから入力を受け取ったとき、文字列を判断して下記2つのどちらを実行するか判断できるようにする。
・何かしらの仕組みで、「しばらく食べてないもの」をレスポンスとして返してくれる
ここでは「めし」という文字列を受け取ったときに動作するとする
・食べたものを記録することで、しばらくはレスポンスを返さなくなる
「めし」以外の文字列を受け取ったとき。
#より詳細に実現したいこと
・何かしらの仕組みで、「しばらく食べてないもの」をレスポンスとして返してくれる
「しばらく食べてないもの」は日付データを参考に古いものを持ってくるが、
最古のもの一つだけを取るだけではループが発生する。(=食事パターンのルーチン化)
なので若干のランダム要素をつけることにした。
○日付データが古い三つのデータを取り出し、その中から一つランダムで選ぶことにする。
○「未知の食事」は「まだ食べたことがないものを食べる」ためのレスポンスとする。
・食べたものを記録することで、しばらくはレスポンスを返さなくなる
新しく食べたものは追加、過去に食べたことがあるなら日付の更新をするだけ。
#コーディング
var LINE_TOKEN = "トークンID";
var sheetID = SpreadsheetApp.openById("ID").getSheetByName(シート名);
function doPost(e) {
var replyToken = JSON.parse(e.postData.contents).events[0].replyToken;
var inputText = JSON.parse(e.postData.contents).events[0].message.text;
var responseText = "";
var syokujiSheet = sheetID;
var syokujiLogRange = syokujiSheet.getDataRange();
var syokujiValues = syokujiLogRange.getValues();
if(inputText == "めし"){
//食事ログから最後に食べたのが古いものを3つ取得し、
//そこからランダムに一つテキストを返す
syokujiValues.sort(function(a,b){
var maeDate = new Date(a[0]);
var atoDate = new Date(b[0]);
return maeDate.getTime() - atoDate.getTime();
});
var responseKouho = [];
responseKouho.push(syokujiValues[0][1]);
responseKouho.push(syokujiValues[1][1]);
responseKouho.push(syokujiValues[2][1]);
responseText = responseKouho[Math.floor(Math.random() * responseKouho.length)];
}else{
//今日食べたものを追加、あるいは日付を更新する
//存在しないものだったら追加
//すでにあるやつなら日付更新だけ
var registSyokujiLength = syokujiValues.length;
var isRegistered = false;
var toDayClass = new Date();
var year = toDayClass.getYear();
var month = toDayClass.getMonth() + 1;
var date = toDayClass.getDate();
var today = year + "/" + month + "/" + date;
for(var i = 0; i < registSyokujiLength; i++){
if(syokujiValues[i][1] == inputText){
isRegistered = true;
syokujiValues[i][0] = today;
break;
}
}
if(!isRegistered){
syokujiValues.push([today, inputText]);
registSyokujiLength++;
responseText = inputText + "を追加したよ";
}else{
responseText = inputText + "を変更したよ";
}
var syokujiNewRange = syokujiSheet.getRange("A1:B" + registSyokujiLength);
syokujiNewRange.setValues(syokujiValues);
}
var url = "https://api.line.me/v2/bot/message/reply";
var opt = {
"headers" : {
"Content-Type" : "application/json; charset=UTF-8",
"Authorization" : "Bearer " + LINE_TOKEN
},
"method" : "post",
"payload" : JSON.stringify({
"replyToken" : replyToken,
"messages" : [{"type" : "text", "text" : responseText}]
})
};
UrlFetchApp.fetch(url, opt);
}
#テスト結果
・何かしらの仕組みで、「しばらく食べてないもの」をレスポンスとして返してくれる
「未知の食事」「こってりラーメン」「博多ラーメン」が古いので、ここから一つ返す。何回も実行すれば三つ分出てくる。
(ここでは偶々三つそろってるけど)
・食べたものを記録することで、しばらくはレスポンスを返さなくなる
追加の場合
「ハンバーグ」を追加
更新の場合
「博多ラーメン」を食べたので更新。その後「めし」でレスポンスを求めると、
今まで出てこなかった「さいころステーキ」が返ってくるようになった
#終わりに
私は一人暮らしなので、毎日の昼食、夕食を何にするかも自力で決めないといけない。
一応平日の昼飯ルーチンはあるんだが、気がついたら飽きてた。
小中学校のように献立がわかるか、記録があればなぁなんて思ったところから構想を得て自作することにした。
これで食事のレパートリーが増えたり、食事することに飽きたりしないような未来が来たらいいな~。
こういうこともちょっと思ってたりした。
昼飯晩飯何にするか考えるのめんどくさい。世の主婦(夫)の方々はどうやって毎日決めてるんだ
— 便利屋わたりさん (@watarimaycry2) July 2, 2020