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

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

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

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

Google Apps Script

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

1241閲覧

【LINE BOT】のコードがわかりません!「ボタン」「image」について教えてください。

sugi58

総合スコア1

LINE Messaging API

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

Google Apps Script

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2022/03/08 07:31

編集2022/03/08 23:18

GASを使い、LINEbotで色々な応答をするbotを製作中です。
色々な方のコードを参考に以下のコードを作りましたが、ボタンのコードをプラスしても反応してくれません。また「indexOf」を使用したところ「image」が今まで反応していたのに、反応してくれなくなりました。
プログラミングは全くの無知で初心者になります。

質問内容として
・「ボタン」などの機能をプラスする場合どうすればいいのか。
・「画像」に反応させるにはどうすればいいのか。

どこがどうだめなのか、どうすればいいのか、どうかご教授お願いいたします。

var

1 2var spreadsheet_id = "XXX" 3 4var tak_spreadsheet_id = "XXX" 5 6 7 8 9 10 11 12 13function doPost(e) { 14 var contents = e.postData.contents; 15 var obj = JSON.parse(contents); 16 var events = obj["events"]; 17 for (var i = 0; i < events.length; i++) { 18 if (events[i].type == "message") { 19 reply_message(events[i]); 20 } else if (events[i].type == "postback") { 21 post_back(events[i]); 22 } 23 } 24} 25 26 27function reply(data){ 28 var url = "https://api.line.me/v2/bot/message/reply"; 29 var headers = { 30 "Content-Type" : "application/json; charset=UTF-8", 31 'Authorization': 'Bearer ' + access_token, 32 } 33 34 var text = ""; 35 36 if (data.events[0].message.text.indexOf("あ") > -1) { 37 var tak = SpreadsheetApp.openById(tak_spreadsheet_id).getSheetByName("あ"); 38 var takData = tak.getRange(1, 1, tak.getLastRow()); 39 var intRandomNum = Math.round(Math.random()*tak.getLastRow()); 40 41 text = takData.getValues()[intRandomNum][0]; 42 } 43 44 if (data.events[0].message.text === "い") { 45 var tak = SpreadsheetApp.openById(tak_spreadsheet_id).getSheetByName("い"); 46 var takData = tak.getRange(1, 1, tak.getLastRow()); 47 var intRandomNum = Math.round(Math.random()*tak.getLastRow()); 48 49 text = takData.getValues()[intRandomNum][0]; 50 } 51 52 if (data.events[0].message.type === "image") { 53 var tak = SpreadsheetApp.openById(tak_spreadsheet_id).getSheetByName("画像"); 54 var takData = tak.getRange(1, 1, tak.getLastRow()); 55 var intRandomNum = Math.round(Math.random()*tak.getLastRow()); 56 57 text = takData.getValues()[intRandomNum][0]; 58 } 59 60 61function reply_message(e) { 62 var input_text = e.message.text; 63 if (input_text == "ボタン") { 64 var postData = { 65 "replyToken": e.replyToken, 66 "messages": [{ 67 "type": "template", 68 "altText": "select", 69 "template": { 70 "type": "buttons", 71 "thumbnailImageUrl": "https://~.png", 72 "title": "Menu", 73 "text": "Please select", 74 "actions": [{ 75 "type": "postback", 76 "label": "postback", 77 "data": "postback selected" 78 }, 79 { 80 "type": "message", 81 "label": "message", 82 "text": "text:message" 83 }, 84 { 85 "type": "uri", 86 "label": "uri", 87 "uri": "https://linecorp.com" 88 }, 89 { 90 "type": "datetimepicker", 91 "label": "datetimepicker", 92 "data": "datetimepicker selected", 93 "mode": "datetime", 94 "initial": "2017-10-25T00:00", 95 "max":   "2017-12-31T23:59", 96 "min": "2017-01-01T00:00" 97 } 98 ] 99 } 100 }] 101 }; 102 } 103 fetch_data(postData); 104} 105 106function post_back(e) { 107 var data = e.postback.data; 108 var replay_text = ""; 109 if (data == "postback selected") { 110 replay_text = data; 111 } else if (data == "datetimepicker selected") { 112 replay_text = data + "\n" + e.postback.params['datetime']; 113 } 114 115 var postData = { 116 "replyToken": e.replyToken, 117 "messages": [{ 118 "type": "text", 119 "text": replay_text + "\n" + JSON.stringify(e.postback) 120 }] 121 }; 122 fetch_data(postData); 123} 124 125function fetch_data(postData) { 126 var options = { 127 "method": "post", 128 "headers": { 129 "Content-Type": "application/json", 130 "Authorization": "Bearer " + access_token 131 }, 132 "payload": JSON.stringify(postData) 133 }; 134 UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options); 135} 136 137 138 var postData = { 139 "replyToken" : data.events[0].replyToken, 140 "messages" : [ 141 { 142 'type':'text', 143 'text':text, 144 } 145 ] 146 }; 147 148 var options = { 149 "method" : "post", 150 "headers" : headers, 151 "payload" : JSON.stringify(postData) 152 }; 153 154 155 return UrlFetchApp.fetch(url, options); 156} 157 158 159function doPost(e) { 160 var json = JSON.parse(e.postData.contents); 161 var data = SpreadsheetApp.openById(spreadsheet_id).getSheetByName('log').getRange(1, 1).setValue(json.events); 162 163 reply(json); 164}

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問文のコードは、ボタンの表示や画像データの受け取り('image'タイプ)に関するそれぞれの部分的なコードのレベルでは、特に問題ありません。

しかし、それらの機能をつなぐ制御構造や全体的な関数の配置、呼び出し方に問題があります。

具体的には、下記が原因で期待通りの動作になっていないと思われます。

・同名の「doPost関数」が複数存在する。
・reply関数がどこからも呼ばれていない。
・reply_message関数、post_back関数、fetch_data関数が、reply関数の中に含まれてしまっている。

また、下記は直接のエラーにつながるものではないですが、改善した方がよい項目です。
・LINE botへのpostは全部fetch_data関数内で行えば済みます。したがって、fetch_data関数の下にある、postData オブジェクトやoptions オブジェクト、UrlFetchApp.fetch~は不要です。

・data.events[0].message.text等 によってデータ読み取り元(’あ'/’い'/'画像'シート)を切り替えている部分は、シート名の指定以外は同じ動作なので、重複する処理を1つの関数にまとめた方がすっきりするでしょう

・シートが存在しない等想定しない状況の場合、現状だと何もメッセージが返されませんが、状況に応じてエラーメッセージを返してあげた方が親切です。

以上を踏まえて修正したコードは下記になります。

js

1var spreadsheet_id = "XXX" 2var tak_spreadsheet_id = "XXX" 3 4function doPost(e) { 5 var contents = e.postData.contents; 6 var obj = JSON.parse(contents); 7 var events = obj["events"]; 8 for (var i = 0; i < events.length; i++) { 9 if (events[i].type == "message") { 10 reply_message(events[i]); 11 } else if (events[i].type == "postback") { 12 post_back(events[i]); 13 } 14 } 15} 16 17function getPostDataFromSheet(sheetName, replyToken) { 18 var text = ""; 19 var ss = SpreadsheetApp.openById(tak_spreadsheet_id) 20 if (ss == null) text = "エラー:スプレッドシートのopenに失敗しました。指定したスプレッドシートIDが存在しないか、読み取り権限がない可能性があります。" 21 else { 22 var tak = ss.getSheetByName(sheetName); 23 if (tak == null) text = `エラー:シート「${sheetName}」がスプレッドシート上に存在しません。` 24 else { 25 var lastrow = tak.getLastRow(); 26 if (lastrow === 0) text = `シート「${sheetName}」にデータが1行もありません。` 27 else { 28 var takData = tak.getRange(1, 1, tak.getLastRow()); 29 var intRandomNum = Math.round(Math.random() * tak.getLastRow()); 30 text = takData.getValues()[intRandomNum][0]; 31 } 32 } 33 } 34 35 var postData = { 36 "replyToken": replyToken, 37 "messages": [ 38 { 39 "type": "text", 40 "text": text 41 }, 42 ] 43 }; 44 return postData; 45} 46 47function reply_message(e) { 48 var postData = {}; 49 50 if (e.message.type === "text") { 51 var input_text = e.message.text; 52 53 if (input_text.indexOf("あ") > -1) { 54 postData = getPostDataFromSheet("あ", e.replyToken); 55 56 } else if (input_text === "い") { 57 postData = getPostDataFromSheet("い", e.replyToken); 58 59 } else if (input_text == "ボタン") { 60 postData = { 61 "replyToken": e.replyToken, 62 "messages": [{ 63 "type": "template", 64 "altText": "select", 65 "template": { 66 "type": "buttons", 67 "thumbnailImageUrl": "https://~.png", 68 "title": "Menu", 69 "text": "Please select", 70 "actions": [ 71 { 72 "type": "postback", 73 "label": "postback", 74 "data": "postback selected" 75 }, 76 { 77 "type": "message", 78 "label": "message", 79 "text": "text:message" 80 }, 81 { 82 "type": "uri", 83 "label": "uri", 84 "uri": "https://linecorp.com" 85 }, 86 { 87 "type": "datetimepicker", 88 "label": "datetimepicker", 89 "data": "datetimepicker selected", 90 "mode": "datetime", 91 "initial": "2017-10-25T00:00", 92 "max": "2017-12-31T23:59", 93 "min": "2017-01-01T00:00" 94 } 95 ] 96 } 97 }] 98 }; 99 } 100 } else if (e.message.type === "image") { 101 postData = getPostDataFromSheet("画像", e.replyToken) 102 } else { 103 postData = { 104 "replyToken": replyToken, 105 "messages": [ 106 { 107 "type": "text", 108 "text": "エラー:対応するメッセージタイプが見つかりません。:" + e.message.type 109 }, 110 ] 111 }; 112 } 113 114 fetch_data(postData); 115} 116 117function post_back(e) { 118 var data = e.postback.data; 119 var replay_text = ""; 120 if (data == "postback selected") { 121 replay_text = data; 122 } else if (data == "datetimepicker selected") { 123 replay_text = data + "\n" + e.postback.params["datetime"]; 124 } 125 126 var postData = { 127 "replyToken": e.replyToken, 128 "messages": [{ 129 "type": "text", 130 "text": replay_text + "\n" + JSON.stringify(e.postback) 131 }] 132 }; 133 fetch_data(postData); 134} 135 136function fetch_data(postData) { 137 var options = { 138 "method": "post", 139 "headers": { 140 "Content-Type": "application/json;",// charset=UTF-8", 141 "Authorization": "Bearer " + access_token 142 }, 143 "payload": JSON.stringify(postData) 144 }; 145 UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options); 146} 147

投稿2022/03/09 13:56

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

sugi58

2022/03/10 23:40

qnoir様 返信が遅くなり申し訳ありません。 ご回答いただきましたコードにて試したところ、動作することが確認できました! 丁寧にわかりやすくご指導いただきありがとうございます。 まだまだ勉強しなくてはなりません。 また、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問