質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

3951閲覧

GAS エラーは出ていないが実行されない

SN____R

総合スコア8

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/05/26 04:55

初心者です。
先日、沢山の方に手助けしていただいて、Line上で動作する通知を送信するメモ帳botを作成しました。
作成日には問題なく動作をしていたのですが、何らかの理由で
登録していたトリガーがエラーは発生していないのに通知を送信されない
独自でコードを変えようとすると、デプロイした後に通知の内容が記載されているのにも関わらず、予定がありませんと表示される
という問題点が見つかりました。
予定を記述しているスプレッドシート(E列のセルはuserIdが入りますが隠しております)
userIdを登録しているスプレッドシート
通知の内容を登録するフォーム
トリガー
トリガーの詳細

Javascript

1var ACCESS_TOKEN = "XXXXXXXXXX="; 2var PUSH = "https://api.line.me/v2/bot/message/push"; 3var REPLY = "https://api.line.me/v2/bot/message/reply"; 4 5function getSchedTime(date, time) { 6 return new Date( 7 Utilities.formatDate(new Date(date), "JST", "yyyy-MM-dd") + 8 " " + Utilities.formatDate(new Date(time), "JST", "HH:mm") + "+09:00" 9 ); 10} 11 12function doPost(e) { 13 var events = JSON.parse(e.postData.contents).events; 14 events.forEach(function(event) { 15 if(event.type == "message") { 16 reply(event); 17 } else if(event.type == "follow") { 18 follow(event); 19 } else if(event.type == "unfollow") { 20 unFollow(event); 21 } 22 }); 23} 24 25function push() { 26 var spreadsheet = SpreadsheetApp.openById("XXXXXXXXXX"); 27 var sheet = spreadsheet.getActiveSheet(); 28 29 var start = 2; 30 var end = sheet.getLastRow(); 31 32 var today = new Date();   33 var formattedDate = Utilities.formatDate(today, "JST", "yyyy/MM/dd"); 34 35 var spsh = SpreadsheetApp.openById("XXXXXXXXXX"); 36 var sht = spsh.getActiveSheet(); 37 var data = sht.getDataRange().getValues(); 38 var userlist = []; 39 for(var n = 0; n < data.length; n++){ 40 userlist.push(data[n][0]); 41 } 42 43 // ユーザーリストから取得したユーザーID毎にループする。 44 for (var u = 0; u < userlist.length; u++) { 45 var value = []; 46 for (var i = start; i <= end; i++) { 47 // i行目のユーザーIDの取得 48 var sell_D = "D" + i; 49 var user = sheet.getRange(sell_D).getValue(); 50 // ユーザーIDがユーザーリストのu番目のユーザーと一致する場合 51 if (user == userlist[u]) { 52 var sell_C = "C" + i; 53 var day_C = sheet.getRange(sell_C).getValue(); 54 // 日付列が空欄だとエラーになるのでcontinueする。 55 if (day_C == '') continue; 56 day_C = Utilities.formatDate(day_C, "JST", "yyyy/MM/dd"); 57 if (formattedDate !== day_C) continue; 58 var sell_G = "G" + i; 59 time_G = Utilities.formatDate(new Date(sheet.getRange(sell_G).getValue()), "JST", "HH:mm"); 60 var sell_B = "B" + i; 61 value.push("・" + sheet.getRange(sell_B).getValue() + "(" + time_G + ")" + "\n\n"); 62 } 63 } 64 if (value.length > 0) { 65 var postData = { 66 // 個別のユーザーIDを指定 67 to: userlist[u], 68 messages: [ 69 { 70 type: "text", 71 text: 72 "【本日の予定】\n\n" + value.join("") + "今日も一日がんばってね!", 73 }, 74 ], 75 }; 76 77 var headers = { 78 "Content-Type": "application/json; charset=UTF-8", 79 Authorization: "Bearer " + ACCESS_TOKEN, 80 }; 81 82 var options = { 83 method: "POST", 84 headers: headers, 85 payload: JSON.stringify(postData), 86 }; 87 UrlFetchApp.fetch(PUSH, options); 88 } 89 } 90} 91 92function reply(data) { 93 var postMsg = data.message.text; 94 var replyToken = data.replyToken; 95 var replyText = ""; 96 var userId = data.source.userId; 97 98 if (postMsg == "登録") { 99 // entry.zzzzzzはユーザーIDのフォームフィールドの番号。 100 replyText = 101 "予定の登録はこちら!\n" + 102 "https://docs.google.com/forms/d/e/XXXXXXXXXX=" +userId; 103 } else if (postMsg == "今後の予定") { 104 var spreadsheet = SpreadsheetApp.openById("XXXXXXXXXX"); 105 var sheet = spreadsheet.getActiveSheet(); 106 107 var today =new Date(Utilities.formatDate(new Date(), "JST", "yyyy-MM-dd 00:00:00+09:00")) 108 // スプレッドシートのデータを一括取得 (時刻データがある7列目まで取得するように修正) 109 var allRecords = sheet.getRange(2, 1, sheet.getLastRow()-1, 7).getValues(); 110 // ユーザID が一致しかつ当日以降のものだけ抽出し、日付順に並び替え。 111 var records = allRecords 112 .filter(e => e[3] == userId && e[2] >= today) 113 .sort((a, b) => getSchedTime(a[2], a[6]) - getSchedTime(b[2], b[6])); 114 115 // 日付をフォーマットし、予定と一緒に配列化。 116 var value = records.map(e => { 117 var date = Utilities.formatDate(new Date(e[2]), "JST", "yyyy/MM/dd"); 118 var time = Utilities.formatDate(new Date(e[6]), "JST", "HH:mm"); 119 return `${e[1]} (${date} ${time})\n\n` 120 }); 121 if (value.length > 0) replyText = value.join("") + "忘れないようにしましょう!"; 122 else replyText = "予定がありません。"; 123 } 124 125 if(replyText == ""){ 126 return; 127 } else { 128 var postData = { 129 "replyToken" : replyToken, 130 "messages" : [ 131 { 132 "type" : "text", 133 "text" : replyText 134 } 135 ] 136 }; 137 138 var headers = { 139 "Content-Type" : "application/json; charset=UTF-8", 140 "Authorization" : "Bearer " + ACCESS_TOKEN 141 }; 142 143 var options = { 144 "method" : "POST", 145 "headers" : headers, 146 "payload" : JSON.stringify(postData) 147 }; 148 149 return UrlFetchApp.fetch(REPLY, options); 150 } 151} 152 153function follow(e) { 154 var spsh = SpreadsheetApp.openById("XXXXXXXXXX"); 155 var sht = spsh.getActiveSheet(); 156 sht.appendRow([e.source.userId]); 157} 158 159function unFollow(e){ 160 var spsh = SpreadsheetApp.openById("XXXXXXXXXX"); 161 var sht = spsh.getActiveSheet(); 162 var result = findRow(sht, e.source.userId, 1); 163 if(result > 0){ 164 sht.deleteRows(result); 165 } 166} 167 168function findRow(sht,val,col){ 169 var data = sht.getDataRange().getValues(); 170 for(var i = 0; i < data.length; i++){ 171 if(data[i][col-1] === val){ 172 return i+1; 173 } 174 } 175 return 0; 176}

ご指導のほどよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tatsunosuke

2021/05/26 05:07

何らかの理由を探さないことには、なんともできないので、 APIが呼び出された箇所から値を返すところまの間に色々とconsole.logを仕込んで、 どこでエラーが出ているか調べてみてください! こちらで実際の内容に触れないため、現状だとなんともいません。。。
SN____R

2021/05/26 05:27

APIが呼び出された箇所から値を返すところまでの間に ↑具体的にはどのあたりでしょうか...初歩的な質問で申し訳ありません。
Tatsunosuke

2021/05/26 05:40

このプログラムですが、細かな、プログラムの動きはわからないとしても、どの関数から始まって、どの関数が呼び出されて、どの関数で終わっているのか、どのような流れで動いているか理解できていますか?
Tatsunosuke

2021/05/26 05:42

関数に引数が正常に渡っているか、それぞれの関数が呼び出されたタイミングで確認してみてください。
SN____R

2021/05/26 08:25

完全には理解できていませんが、なんとなくは理解できたような...という形でした。 結果、push()関数内のコードがスプレッドシートと合っていないのが原因だったみたいです。 お手数お掛けしました。
Tatsunosuke

2021/05/26 10:39

解決したようで良かったです。 プログラムが思ったとおりに動かないが、原因もわからないというのは良く発生します。 なので、処理の所々にlogを吐くように設定しておき、どこでエラーが発生しているか追えるようにしておくと、今後の開発もスムーズに進むと思いますよ!
guest

回答1

0

ベストアンサー

確認なのですが、質問文のpush()関数内のコードがスプレッドシートと合っていないように見えます。
(昨日修正したはずと思ったのですが、コードが修正前の状態になっていませんか?保存できていなかった可能性?)

【確認していただきたいこと】
回答を集計するスプレッドシートの並びが、掲載の画像の通り
・タイムスタンプ A列
・通知の内容:B列
・通知の日付:C列
・通知の時刻:D列
・ユーザID:E列
となっているならば、コードは下記のように修正するべきと思います。
(違っている場合は、現状のスプレッドシートの画像をアップロードしなおしてください)

それでもうまく行かない場合は、
・コードに記載されている各スプレッドシートのidが正しいか。
・フォームに紐づいているスプレッドシートは意図したシートになっているか
・スクリプトエディタ上で修正したら都度「新しいデプロイ」を行って、デプロイの管理から、最新バージョンに紐付けているか
・LINE Develop内に設定されているwebhookのURL等は正しいか

を確認してください。

diff

1var ACCESS_TOKEN = "XXXXXXXXXX="; 2var PUSH = "https://api.line.me/v2/bot/message/push"; 3var REPLY = "https://api.line.me/v2/bot/message/reply"; 4 5function getSchedTime(date, time) { 6 return new Date( 7 Utilities.formatDate(new Date(date), "JST", "yyyy-MM-dd") + 8 " " + Utilities.formatDate(new Date(time), "JST", "HH:mm") + "+09:00" 9 ); 10} 11 12function doPost(e) { 13 var events = JSON.parse(e.postData.contents).events; 14 events.forEach(function(event) { 15 if(event.type == "message") { 16 reply(event); 17 } else if(event.type == "follow") { 18 follow(event); 19 } else if(event.type == "unfollow") { 20 unFollow(event); 21 } 22 }); 23} 24 25function push() { 26 var spreadsheet = SpreadsheetApp.openById("XXXXXXXXXX"); 27 var sheet = spreadsheet.getActiveSheet(); 28 29 var start = 2; 30 var end = sheet.getLastRow(); 31 32 var today = new Date();   33 var formattedDate = Utilities.formatDate(today, "JST", "yyyy/MM/dd"); 34 35 var spsh = SpreadsheetApp.openById("XXXXXXXXXX"); 36 var sht = spsh.getActiveSheet(); 37 var data = sht.getDataRange().getValues(); 38 var userlist = []; 39 for(var n = 0; n < data.length; n++){ 40 userlist.push(data[n][0]); 41 } 42 43 // ユーザーリストから取得したユーザーID毎にループする。 44 for (var u = 0; u < userlist.length; u++) { 45 var value = []; 46 for (var i = start; i <= end; i++) { 47 // i行目のユーザーIDの取得 48- var sell_D = "D" + i; 49- var user = sheet.getRange(sell_D).getValue(); 50+ var sell_E = "E" + i; 51+ var user = sheet.getRange(sell_E).getValue(); 52 // ユーザーIDがユーザーリストのu番目のユーザーと一致する場合 53 if (user == userlist[u]) { 54 var sell_C = "C" + i; 55 var day_C = sheet.getRange(sell_C).getValue(); 56 // 日付列が空欄だとエラーになるのでcontinueする。 57 if (day_C == '') continue; 58 day_C = Utilities.formatDate(day_C, "JST", "yyyy/MM/dd"); 59 if (formattedDate !== day_C) continue; 60- var sell_G = "G" + i; 61- time_G = Utilities.formatDate(new Date(sheet.getRange(sell_G).getValue()), "JST", "HH:mm"); 62+ var sell_D = "D" + i; 63+ time_D = Utilities.formatDate(new Date(sheet.getRange(sell_D).getValue()), "JST", "HH:mm"); 64 65 var sell_B = "B" + i; 66- value.push("・" + sheet.getRange(sell_B).getValue() + "(" + time_G + ")" + "\n\n"); 67+ value.push("・" + sheet.getRange(sell_B).getValue() + "(" + time_D + ")" + "\n\n"); 68 69 } 70 } 71 if (value.length > 0) { 72 var postData = { 73 // 個別のユーザーIDを指定 74 to: userlist[u], 75 messages: [ 76 { 77 type: "text", 78 text: 79 "【本日の予定】\n\n" + value.join("") + "今日も一日がんばってね!", 80 }, 81 ], 82 }; 83 84 var headers = { 85 "Content-Type": "application/json; charset=UTF-8", 86 Authorization: "Bearer " + ACCESS_TOKEN, 87 }; 88 89 var options = { 90 method: "POST", 91 headers: headers, 92 payload: JSON.stringify(postData), 93 }; 94 UrlFetchApp.fetch(PUSH, options); 95 } 96 } 97} 98 99function reply(data) { 100 var postMsg = data.message.text; 101 var replyToken = data.replyToken; 102 var replyText = ""; 103 var userId = data.source.userId; 104 105 if (postMsg == "登録") { 106 // entry.zzzzzzはユーザーIDのフォームフィールドの番号。 107 replyText = 108 "予定の登録はこちら!\n" + 109 "https://docs.google.com/forms/d/e/XXXXXXXXXX=" +userId; 110 } else if (postMsg == "今後の予定") { 111 var spreadsheet = SpreadsheetApp.openById("XXXXXXXXXX"); 112 var sheet = spreadsheet.getActiveSheet(); 113 114 var today =new Date(Utilities.formatDate(new Date(), "JST", "yyyy-MM-dd 00:00:00+09:00")) 115 // スプレッドシートのデータを一括取得 116 var allRecords = sheet.getRange(2, 1, sheet.getLastRow()-1, 7).getValues(); 117 // ユーザID が一致しかつ当日以降のものだけ抽出し、日付順に並び替え。 118 var records = allRecords 119- .filter(e => e[3] == userId && e[2] >= today) 120- .sort((a, b) => getSchedTime(a[2], a[6]) - getSchedTime(b[2], b[6])); 121+ .filter(e => e[4] == userId && e[2] >= today) 122+ .sort((a, b) => getSchedTime(a[2], a[3]) - getSchedTime(b[2], b[3])); 123 124 125 // 日付をフォーマットし、予定と一緒に配列化。 126 var value = records.map(e => { 127 var date = Utilities.formatDate(new Date(e[2]), "JST", "yyyy/MM/dd"); 128- var time = Utilities.formatDate(new Date(e[6]), "JST", "HH:mm"); 129+ var time = Utilities.formatDate(new Date(e[3]), "JST", "HH:mm"); 130 131 return `・${e[1]} (${date} ${time})\n\n` 132 }); 133 if (value.length > 0) replyText = value.join("") + "忘れないようにしましょう!"; 134 else replyText = "予定がありません。"; 135 } 136 137 if(replyText == ""){ 138 return; 139 } else { 140 var postData = { 141 "replyToken" : replyToken, 142 "messages" : [ 143 { 144 "type" : "text", 145 "text" : replyText 146 } 147 ] 148 }; 149 150 var headers = { 151 "Content-Type" : "application/json; charset=UTF-8", 152 "Authorization" : "Bearer " + ACCESS_TOKEN 153 }; 154 155 var options = { 156 "method" : "POST", 157 "headers" : headers, 158 "payload" : JSON.stringify(postData) 159 }; 160 161 return UrlFetchApp.fetch(REPLY, options); 162 } 163} 164 165function follow(e) { 166167} 168 169function unFollow(e){ 170171} 172 173function findRow(sht,val,col){ 174175 } 176 return 0; 177}

投稿2021/05/26 06:28

編集2021/05/26 06:30
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SN____R

2021/05/26 08:23

保存できてなかった可能性が大きいかもしれないです... 新たに掲載して頂いたコードを元に、書き換えたところ正常に動作するようになりました! 昨日お世話になったばかりなのにすみませんでした...
退会済みユーザー

退会済みユーザー

2021/05/26 08:26

解決してよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問