LINEで使えるアラームbotに関する質問
解決したいこと
LINEbotの作成に際して様々な資料を自分で読みながら自分で進めていたのですが、
行き詰ったところがあり、他の方の意見を聞いてみたいと思いました。
どういうbotなのかを簡単に言うと、
・LINEからコマンドメッセージを受け取る。
・そのコマンドから送り主が指定した「年月月日時分、メッセージ」情報を抜き出して、
その時間にそのメッセージを送るという処理が実行されるトリガーを作成する。
というものです。
例として、
「$2022$05$14$17$30$会議」というコマンドメッセージを受け取ると、
「2022年の5月14日17時30分に『会議』というメッセージをコマンドメッセージが送られたトークに送る」というトリガーを設定してくれるということです。
※実際のコマンドでは「$」は半角ですが、Qiitaに書き込む都合上全角にしてます。
発生している問題・エラー
コード自体は試行錯誤を重ねながら大体書き終わったのですが、実際にLINEからメッセージを送っても何も反応がないという状況です。
全体ソースコード
//LINEからメッセージを取得時に実行
function doPost(e) {
const LINE_TOKEN = '--------------';
const LINE_URL = 'https://api.line.me/v2/bot/message/reply';
//LINEからのメッセージ、送信元のトークンを取得
var json = JSON.parse(e.postData.contents);
var reply_token = json.events[0].reply_token;
if (typeof reply_token === 'undefined') {
return;
}
var alarm_usermessage = json.events[0].message.text;
var body = 'アラーム設定が完了しました。';
//年月日時、用件情報を各変数に格納(コマンドは”$”で区切る)
for(var i = 0 ; i < 4 ; i++){
switch(i){
//「年」の格納
case 0:
if(alarm_usermessage.match(/^\$\d/)){
var alarm_year = alarm_usermessage.substr(1, 4);
alarm_usermessage = alarm_usermessage.substr(5);
}else{
body = 'コマンド形式が正しくありません。';
}
break;
//「月」の格納
case 1:
if(alarm_usermessage.match(/^\$\d/)){
var alarm_month = alarm_usermessage.substr(1 ,2)
alarm_usermessage = alarm_usermessage.substr(3);
}else{
body = 'コマンド形式が正しくありません。';
}
break;
//「日」の格納
case 2:
if(alarm_usermessage.match(/^\$\d/)){
var alarm_day = alarm_usermessage.substr(1 ,2)
alarm_usermessage = alarm_usermessage.substr(3);
}else{
body = 'コマンド形式が正しくありません。';
}
break;
//「時」の格納
case 3:
if(alarm_usermessage.match(/^\$\d/)){
var alarm_hours = alarm_usermessage.substr(1 ,2)
alarm_usermessage = alarm_usermessage.substr(3);
}else{
body = 'コマンド形式が正しくありません。';
}
break;
//「分」の格納
case 4:
if(alarm_usermessage.match(/^\$\d/)){
var alarm_minutes = alarm_usermessage.substr(1 ,2)
alarm_usermessage = alarm_usermessage.substr(4);
}else{
body = 'コマンド形式が正しくありません。';
}
break;
}
}
//確認メッセージの送信
sendmessage(reply_token, body);
//トリガーセット時に使う「at(○○)」部分
var alarm_time = new Date();
alarm_time.setFullYear(alarm_year);
alarm_time.setMonth(alarm_month - 1);
alarm_time.setDate(alarm_day);
alarm_time.setHours(alarm_hours);
alarm_time.setMinutes(alarm_minutes);
//トリガーセット
if(body === 'アラーム設定が完了しました。'){
ScriptApp.newTrigger('sendmessage(reply_token, alarm_usermessage)').timeBased().at(alarm_time).create();
}else{
return;
}
}
//メッセージ送信関数
function sendmessage(token, message) {
//メッセージを返信
UrlFetchApp.fetch(LINE_URL, {
'headers':{
'Content-Type':'application/json; charset=UTF-8',
'Authorization':'Bearer '+ LINE_TOKEN,
},
'method':'post',
'payload':JSON.stringify({
'replyToken':token,
'messages':[{
'type':'text',
'text':message,
}],
}),
});
return ContentService.createTextOutput(JSON.stringify({'content':'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
処理の流れ
・LINEからメッセージを取得すると、「doPost」関数が実行される。
・定数にbotのチャネルアクセストークンとLINEURLを各々格納する。
・変数に取得したメッセージを格納する。
・for文とswitch文とif文を使って、時間関連の各変数にコマンドからの情報を格納していく。
※この時コマンド形式がおかしかったのなら適宜処理を行う。
・for文の処理が終わったら、アラーム設定が完了したかもしくはコマンドエラーが発生したかどうかの確認メッセージを送信する。
→定義しておいた「sendmessage」関数に、「宛先を指定する引数」と「メッセージ内容を指定する引数」を渡して実行する。確認メッセージではfor文の途中でエラーが発生しない限りは「アラーム設定が完了しました。」となっていて、エラーが発生していた場合は「コマンド形式が正しくありません。」に置き換わっている。
・トリガーをセットする際に「at(○○)」の部分に使う変数を「new Date();」で定義して、先のfor×switch×ifで手に入った時間関連情報を各々セットしていく。
・if文で「もしエラーが発生していないのなら」という条件で、trueの場合にトリガーをセットするというようにする。
確信が持てていない点
・トリガーをセットする「ScriptApp.newTrigger...」の際に、参考にしていたサイトなどではここまで引数を使用していなかったためnewTriggerの後の()の中にコードのような感じに引数も含めて書いていいのか。
・参考にしたサイトの中に「関数として定義したsetTriggerを、トリガーに組み込みたい処理を書く関数(私のコードで言うならsendmessage関数)の一番上の部分に書いておく」と記述されたものがあったので、もしかしたらそれが出来ない原因?と思いつつも、その場合引数の渡しが複雑になりそうだからどうなのかな。
最後に
コード自体のエラーはないと思(って)います。
ただこんないろんなことを詰め込んだものは探しても出てこなかったり、LINEbotの記事自体が古いものが多かったりと色んな資料を読み漁っているもののわからないことだらけという状況です。
周りにこんな細かいことを聞けるような人もおらず、この場に投げかけてみました。
ここまで読んでくださった方は、長文なのにも関わらず読んでいただきありがとうございました。
何か知っていること、気になったこと、間違っていることなどありましたらコメントよろしくお願いします。