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

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

新規登録して質問してみよう
ただいま回答率
85.48%
LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Google スプレッドシート

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

Google Apps Script

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

Q&A

解決済

1回答

824閲覧

【GAS】突然LINE BOTからスプレッドシートの値が返信されなくなった(LINE Messaging API)

cardamon

総合スコア19

LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Google スプレッドシート

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

Google Apps Script

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

0グッド

0クリップ

投稿2022/11/08 04:08

編集2022/11/08 08:11

前提

LINEから特定のキーワードを送ると、スプシの内容を返信してくれたり、スプシに転記してくれるGASを組んでいました。

具体的には、

①LINEに特定ワードを送信→特定シート特定セルをLINEへ返信
②LINEに特定ワードを送信→特定シートに転記  です。

(以下、スプレッドシート、イメージ画像)

①LINEに"A"と送信→"あいうえお"をLINEへ返信
イメージ説明

②LINEに"start"と送信→特定シート特定セルに日時と"start"を転記
イメージ説明

発生している問題・エラーメッセージ

11/4(金)10:57までは、①②ともに正常に動いていたのですが、
11/8(火)10:15に気づいた時には、①のみ、動かなくなりました。

①の操作で、LINEから「A」や「B」など送信すると
LINEに既読はつきますが、LINEから返信がこない状態です。

②は正常に動いています。

該当のソースコード

GoogleAppsScript

1 2 3// 1-4で取得したLINE Messaging APIのチャネルアクセストークン 4var LINE_ACCESS_TOKEN ="●●"; 5 6// auto-replyに必要 7var replyUrl = "https://api.line.me/v2/bot/message/reply"; 8 9// スプレッドシートのID(2-2でメモしたもの、スプレッドシートのURL欄の「/d/」と「/edit」の間の部分) 10var spreadsheetId = "▼▼"; 11 12 13//★ここから、$を含んだら失注受取シートに転記 14 15function doPost(e) { 16 // 投稿されたメッセージとそのreplyTokenを取得 17 var userMessage = JSON.parse(e.postData.contents).events[0].message.text; 18 var replyToken = JSON.parse(e.postData.contents).events[0].replyToken; 19 20 if (userMessage.match(/^http/)) { 21 // httpから始まるメッセージの場合、資料追加を除いた文字列を代入 22 userMessage = userMessage.substr(1); 23 autoSave = true; 24 25 } else if (userMessage.match(/^\$/)) { 26 // $から始まるメッセージの場合、$を除いた文字列を代入 27 userMessage = userMessage.substr(1); 28 autoSave = true; 29 30 } else if (typeof e !== "undefined") { 31 // このelse ifの処理は自動返信用なので不要な場合削除してください 32 33 //JSON文字列をパースして変数jsonに格納 34 var json = JSON.parse(e.postData.contents); 35 36 //変数jsonを関数replyFromSheetに渡し、replyFromSheetを実行 37 replyFromSheet(json); 38 autoSave = false; 39 } else { 40 return; 41 } 42 43 44 if (autoSave === true) { 45 // -----スプレッドシートへ保存 ここから----- 46 var sheetName = "失注受取"; 47 var spreadsheet = SpreadsheetApp.openById(spreadsheetId); 48 var sheet = spreadsheet.getSheetByName(sheetName); 49 50 // 空白・タブ・改行で区切り配列に変換 51 var arr = userMessage.split(/\s/); 52 53 // 配列の先頭に日時を代入 54 arr.unshift(new Date()); 55 56 // セルの最下部に配列を転記 57 sheet.appendRow(arr); 58 // -----ここまで----- 59 60 resMessage = "記録したよ🐼"; //記録成功時に送信するメッセージ 61 } else { 62 return; 63 } 64 65 // ↓記録成功時メッセージを送信しない場合不要 66 UrlFetchApp.fetch(url, { 67 headers: { 68 "Content-Type": "application/json; charset=UTF-8", 69 Authorization: "Bearer " + LINE_ACCESS_TOKEN, 70 }, 71 method: "post", 72 payload: JSON.stringify({ 73 replyToken: replyToken, 74 messages: [ 75 { 76 type: "text", 77 text: resMessage, 78 }, 79 ], 80 }), 81 }); 82 return ContentService.createTextOutput(JSON.stringify({ content: "post ok" })).setMimeType( 83 ContentService.MimeType.JSON 84 ); 85} 86//失注受取ここまで 87 88 89 90 91//★ここから、特定のワードに特定の返信 92 93 94// 返信用の関数replyFromSheet dataには変数jsonが代入される 95 96function replyFromSheet(data) { 97 98 // Sheet 99 var sheet2Name = "LINE用"; 100 var spreadsheet = SpreadsheetApp.openById(spreadsheetId); 101 var autoReplySheet = spreadsheet.getSheetByName(sheet2Name); // 使用するシートの名称・デフォルトだとシート1とかの部分 102 103//シートの最終行を取得する 104 var lastRow = autoReplySheet.getLastRow(); 105 106 //シートのA~G列を二次元配列で取得する 107 var wordList = autoReplySheet.getRange(1,1,lastRow,7).getValues(); 108 109 //受信したメッセージ情報を変数に格納する 110 var reply_token = data.events[0].replyToken; //reply token 111 var text = data.events[0].message.text; //ユーザーが送信した語句 112 113 //返信メッセージのタイプを格納するための空配列を宣言する 114 var replyType = []; 115 116 //返信メッセージを格納するための空配列を宣言する 117 var replyList = []; 118 119 //LINEで受信した語句がシートの受信語句と同じ場合、 120 //返信メッセージのタイプをreplyTypeにpushし、 121 //さらにその行のA列~G列をreplyListにpushする 122 for(var i = 1; i < wordList.length; i++) { 123 if(wordList[i][0] == text) { 124 replyType.push(wordList[i][1]); 125 replyList.push(wordList[i]); //ポイント: 一次元配列をpushする 126 } 127 } 128 129 //LINEで受信した語句がシートの受信語句と一致しない場合、関数を終了する 130 if(replyType.length < 1) { 131 return; 132 133 //replyTypeのLengthが5より大きい場合、messageLengthを5にする 134 //※※一度に最大5つの吹き出ししか返信できないため※※ 135 } else if(replyType.length > 5) { 136 var messageLength = 5; 137 } else { 138 var messageLength = replyType.length; 139 } 140 141 //"messages"に渡す配列を格納するための空配列を宣言する 142 var messageArray = []; 143 144 //replyTypeに格納されている返信メッセージのタイプと 145 //replyListに格納されている返信メッセージを最大5つ、 146 //messageArrayにpushする 147 for(var j = 0; j < messageLength; j++) { 148 switch (replyType[j]) { 149 case "text": 150 messageArray.push({"type": replyType[j], "text": replyList[j][2]}); 151 break; 152 153 case "sticker": 154 messageArray.push({"type": replyType[j], "packageId": replyList[j][3], "stickerId": replyList[j][4]}); 155 break; 156 157 case "image": 158 messageArray.push({"type": replyType[j], "originalContentUrl": replyList[j][5], "previewImageUrl": replyList[j][6]}); 159 break; 160 161 case "video": 162 messageArray.push({"type": replyType[j], "originalContentUrl": replyList[j][5], "previewImageUrl": replyList[j][6]}); 163 break; 164 165 //replyList[j][2]はJSON.parseを使ってパースする必要がある 166 case "flex": 167 messageArray.push({"type": replyType[j], "altText": "this is a flex message", "contents": JSON.parse(replyList[j][2])}); 168 break; 169 } 170 } 171 172 var headers = { 173 "Content-Type": "application/json; charset=UTF-8", 174 "Authorization": "Bearer " + LINE_ACCESS_TOKEN, 175 }; 176 177 var postData = { 178 "replyToken": reply_token, 179 "messages": messageArray 180 }; 181 182 var options = { 183 "method" : "post", 184 "headers" : headers, 185 "payload" : JSON.stringify(postData) 186 }; 187 188 //LINE Messaging APIにデータを送信する 189 UrlFetchApp.fetch(replyUrl, options); 190 191} 192

試したこと

・スプシを正常に動いていた11/4(金) 10:57以前に復元(変化なし)

・②LINE→スプシに転記、の実行(問題なく動いています)

現状、LINEからスプシへの転記は問題なく動いているので、
webhookは問題なく、他の部分でのエラーかと考えていますが、
もし原因がおわかりの方おられましたら、ヒントを頂けると幸いです。

補足

もし、質問文に過不足がありましたら、その点もご教示いただければ幸いです。

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

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

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

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

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

YAmaGNZ

2022/11/08 08:17

実行時にエラーが出ていないか確認されたのでしょうか? また、シートなどにログを出力するようにしてみてどのように実行されているか、変数の中身はどうなっているかなど確認してみてはどうでしょうか。
guest

回答1

0

自己解決

コメントありがとうございます。取り急ぎご報告です。

コードは触っていないのですが、今朝、確認したところ、無事に動作しました。

また、ご指摘いただいた2点も確認しました。


1)実行時のエラー

TypeError: Cannot read property 'events' of undefined
replyFromSheet @ コード.gs:108

108行目の該当コード↓

GoogleAppsScript

1var reply_token = data.events[0].replyToken; //reply token

 
が出ていました。


2)シートにログ出力
以下のような作業イメージで合っていますでしょうか。

GASでログをスプレッドシートに書き出す
http://www.dtm-hirasan.com/gas-log/

長過ぎるログを出力する方法3つ
https://munakata-engineer.com/spreadsheet/gas/confirm-long-log/#i-4

シートのログ出力はやったことがないため、また症状が出たら、参考にさせていただきます。

拙い質問にも関わらず、具体的なアドバイス、重ねてありがとうございます。

投稿2022/11/09 01:43

cardamon

総合スコア19

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問