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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Google Apps Script

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1323閲覧

【linebot】言われた回数を記憶したい。【GAS】

siranui

総合スコア54

Google Apps Script

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2021/10/02 08:15

###GASを使って、linebotを作ろうとしています。特定のワードが何回言われたのかを記憶したいです。
特定のワードは、ここでは仮に「test」とします

普段なら

gs

1let count = 0; 2 3if(userMessage == "test") { 4 let count = count+1; 5} 6

とやってカウントしていきますが、今回はlinebotなので、何か言われるたびに
let count = 0;
を走ってしまうためカウントができません。

やってみたこと

HTMLを使って、情報をdiv書き換え、読み込みをすることで記憶しようとしました。

gs

1function doGet() { 2 return HtmlService.createHtmlOutputFromFile('index'); 3} 4 5 var ACCESS_TOKEN = "";//実際は入力しています。 6 7function doPost(e) { 8 // WebHookで受信した応答用Token 9 var replyToken = JSON.parse(e.postData.contents).events[0].replyToken; 10 // ユーザーのメッセージを取得 11 var userMessage = JSON.parse(e.postData.contents).events[0].message.text; 12 // 応答メッセージ用のAPI URL 13 var url = 'https://api.line.me/v2/bot/message/reply'; 14 15var count = "a"//確認のためにやってます 16 17if(userMessage == "test") {; 18 var data = document.getElementById('data').split(/<div id="data">|</div>/);//divの中を取得 19 var count = Number(data[1]) + 1;//カウント 20} 21 22 23 UrlFetchApp.fetch(url, { 24 'headers': { 25 'Content-Type': 'application/json; charset=UTF-8', 26 'Authorization': 'Bearer ' + ACCESS_TOKEN, 27 }, 28 'method': 'post', 29 'payload': JSON.stringify({ 30 'replyToken': replyToken, 31 'messages': [{ 32 'type': 'text', 33 'text': "テスト"+count, 34 }], 35 }), 36 }); 37 return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON); 38} 39

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 </head> 6 <body> 7 <div id="data">0</div> 8 </body> 9</html>

現状

testにだけ無反応になります。HTMLを参照できていないのか、関数がうまくできていないのか全くわかりません。
イメージ説明

そもそも、もっと賢い方法がある気がします。もしあれば、ご教授ください。
また、どうしてレスポンスがないのか分かればそれもお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

HTMLのdivを書き換えて回数を記録することは、おそらくできません。
代替案として、Googleスプレッドシートに回数を記録する方法があります。

下記は、行頭で指定したスプレッドシートのA1セルからcountの値を読み込み
更新後の値を同じA1セルに書き込む例です。

(先頭が「+」となっている行は追加、「-」の行は削除してください)
("スプレッドシートのID"、"シート名" "アクセストークン"の部分は適切なID・名前に変えてください。)
GASのデプロイ時に「アクセスできるユーザー」を「全員」に設定してください。

diff

1// 記録用のスプレッドシート 2const sh = SpreadsheetApp.openById("スプレッドシートのID").getSheetByName("シート名"); 3const ACCESS_TOKEN = "アクセストークン" 4 5function doPost(e) { 6 // WebHookで受信した応答用Token 7 const replyToken = JSON.parse(e.postData.contents).events[0].replyToken; 8 // ユーザーのメッセージを取得 9 const userMessage = JSON.parse(e.postData.contents).events[0].message.text; 10 // 応答メッセージ用のAPI URL 11 const url = 'https://api.line.me/v2/bot/message/reply'; 12+ let msg = ''; 13- var count = "a"//確認のためにやってます 14 15 if(userMessage == "test") { 16- var data = document.getElementById('data').split(/<div id="data">|</div>/);//divの中を取得 17- var count = Number(data[1]) + 1;//カウント 18+ // セルA1の内容を読み取る 19+ let count = sh.getRange('A1').getDisplayValue(); 20+ if (count === '') count = '0'; 21+ try { 22+ count = parseInt(count); 23+ count++; 24+ msg = 'テスト' + count; 25+ } catch(err) { 26+ msg = '値の変換に失敗しました。カウンタをリセットします。'; 27+ count = 0; 28+ } 29+ // セルA1に更新した値を書き込む 30+ sh.getRange('A1').setValue(count); 31+ } else { 32+ msg = userMessage; 33+ } 34 35 UrlFetchApp.fetch(url, { 36 'headers': { 37 'Content-Type': 'application/json; charset=UTF-8', 38 'Authorization': 'Bearer ' + ACCESS_TOKEN, 39 }, 40 'method': 'post', 41 'payload': JSON.stringify({ 42 'replyToken': replyToken, 43 'messages': [{ 44 'type': 'text', 45- 'text': "テスト"+count, 46+ 'text': msg, 47 }], 48 }), 49 }); 50 return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON); 51}

修正前のコードで、レスポンスがなかった理由は、
「test」というメッセージをLINEに入力した場合
元のコードの「 document.getElementById('data'). ~ 」のところで、
定義されていない変数documentを読み取ろうとしたため、エラーが発生し
その後の処理が行われていないから、だと考えられます。

投稿2021/10/02 10:00

編集2021/10/02 14:29
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

siranui

2021/10/02 13:56

GCPを使わないで行うことって可能ですか?
退会済みユーザー

退会済みユーザー

2021/10/02 13:59 編集

GCPはエラーログ表示を行うときに必要なだけなので、今回のカウントする本体プログラムの部分では特に使う必要はありません。(修正しました)
siranui

2021/10/02 14:07

すみません、GCPのとこを削除してやってみたのですが、やはりレスポンスをしてくれません。test以外のところではちゃんと返してくれるのですが...
siranui

2021/10/02 14:16

```gs if(userMessage == "test") { // セルA1の内容を読み取る let count = sh.getRange('A1').getDisplayValue(); var count2 = count; if (count === '') count = '0'; try { count = parseInt(count); count++; msg = 'テスト' + count; } catch(err) { msg = '値の変換に失敗しました。カウンタをリセットします。'; count = 0; } var count3 = count // セルA1に更新した値を書き込む sh.getRange('A1').setValue(count); } ``` このようにしてcountが何を受け取ったかを確認してみましたが、count2,count3ともにundefinedでした。
退会済みユーザー

退会済みユーザー

2021/10/02 14:32 編集

コードを一部修正しました。 また、下記2点確認ください。 ・スプレッドシートのID、シート名は正しく設定されているでしょうか? ・デプロイ時に「アクセスできるユーザー」を「全員」に設定しているでしょうか。 (仮に修正した場合は、デプロイしなおして、新しく発行されたデプロイURLをLINE DEVELOPERの設定画面に設定しなおすか、又はGAS側で既存のデプロイURLのバージョンを最新にしてください)
退会済みユーザー

退会済みユーザー

2021/10/02 14:47 編集

念のためですが、コード中の"シート名"の部分には、スプレッドシートURLの末尾(gid=の右側)ではなく、スプレッドシートの下のタブの中にある文字列を指定します。 (LINEとやりとりするのとは別の関数でテスト実行してみて、指定したIDとシート名で正しくスプレ度シートのデータを読み書きできるか確認する(スプレッドシートの読み書きの挙動だけ確認する)のもいいかもしれません) それが正しくてもレスポンスが来ない場合、原因は不明です・・環境要因かもしれません(自分の手元ではできているので)
siranui

2021/10/02 14:55

うまくいきました!!シート名は数字かと思ってました! "シート1"としたらうまくいきました! 素人質問に丁寧に答えてくださりありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問