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

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

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

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

解決済

LineにClassroomから転送するボットでエラー

loKA
loKA

総合スコア15

Google Apps Script

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

1回答

0評価

0クリップ

191閲覧

投稿2022/04/17 09:53

前提

https://takaremonn.ml/blog/2020/10/30/google-classroomの投稿をlineに転送するボットを作ってみた/?unapproved=28&moderation-hash=12627480ea90c04da704981e7480d4cd#comment-28
このサイトに従って全角の「”」「’」を半角に訂正するのみの改造を加え、実行してみたところ、エラーが発生しました。
原因と対処法を教えてください。

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

Exception: Request failed for https://api.line.me returned code 400. Truncated server response: {"message":"The property, 'to', in the request body is invalid (line: -, column: -)"} (use muteHttpExceptions option to examine full response)

該当のソースコード

Google

function myFunction() { var lock = LockService.getUserLock(); //多重実行防止のためのロック try { lock.waitLock(25); //****0時から6時まで処理スキップ****** var day = new Date(); var hour = day.getHours(); Logger.log("day_hour:" + day + "_" + hour); if(hour >=25 && hour <=26){ //return; } //******************************* var optionalArgs = { //最大取得コース数 pageSize: 10 }; var courses = Classroom.Courses.list(optionalArgs).courses; //コースの取得 Logger.log(courses); var i = 0; for (var i = 0; i < courses.length; i++) { //コース別繰り返し処理 Logger.log("i:" + i); var course = courses[i]; var sheet = SpreadsheetApp.getActiveSheet();//シートOpen var announcements = Classroom.Courses.Announcements.list(course.id).announcements; var sheet_array = sheet.getDataRange().getValues(); //シートの配列への格納 Logger.log("sheet_array:" + sheet_array); if (announcements && announcements.length > 0) { //投稿件数>0のときの処理 Logger.log("announcements.length:" + announcements.length); if(announcements.length < 5){ var an_length = announcements.length; //投稿件数<5のとき取得は投稿件数 } else { var an_length = 5; //投稿件数>5のとき取得は5件まで } Classroom繰り返し処理: for (var j = 0; j < an_length; j++) { //取得件数まで繰り返し(配列のため初期値0) var announcemessage = []; //取得物格納用1次元配列の定義 var announcement = announcements[j];//投稿内容(JSON) Logger.log(announcement); var announcement_updateTimesheet = announcement.updateTime;//投稿(更新)時刻 var announcement_creatoruserId = creatoruId(announcement);//UserIdを名前に変換 var message_announcement = announcement.text;//投稿メッセージ Logger.log("sheet_array.length:" + sheet_array.length); if(sheet_array.length != 1){ for (var sheet_j = sheet_array.length; sheet_j > 0; sheet_j){//シートでの一致検索 Logger.log("sheet_array[sheet_j – 1][2]:" + sheet_array[sheet_j - 1][2]); if(sheet_array[sheet_j - 1][2] == message_announcement){//投稿メッセージがシートで発見したら次の投稿へContinue continue Classroom繰り返し処理; } } } var message_announcement_attachment = ""; if (announcement.materials != undefined){ //添付物があるときの処理 if(announcement.materials[0].driveFile != undefined){ message_announcement_attachment = String.fromCharCode(10) + String.fromCharCode(10) +"*添付ファイル*" + String.fromCharCode(10) + announcement.materials[0].driveFile.driveFile.alternateLink; } else if(announcement.materials[0].link != undefined){ message_announcement_attachment = String.fromCharCode(10) + "*リンク*" + String.fromCharCode(10) + announcement.materials[0].link.url; } else if(announcement.materials[0].youtubeVideo != undefined){ message_announcement_attachment = String.fromCharCode(10) +"*YouTubeVideo*" + String.fromCharCode(10) + announcement.materials[0].youtubeVideo.alternateLink; } else if(announcement.materials[0].form != undefined){ message_announcement_attachment = String.fromCharCode(10) +"*フォーム*" + String.fromCharCode(10) + announcement.materials[0].form.formUrl; } if(announcement.materials.length >= 2){ //添付物が2以上のとき for(var k = 1; k < announcement.materials.length; k++){ if(announcement.materials[k].driveFile != undefined){ message_announcement_attachment = String.fromCharCode(10) + announcement.materials[k].driveFile.driveFile.alternateLink; } else if(announcement.materials[k].link != undefined){ message_announcement_attachment = String.fromCharCode(10) + announcement.materials[k].link.url; } else if(announcement.materials[k].youtubeVideo != undefined){ message_announcement_attachment = String.fromCharCode(10) + announcement.materials[k].youtubeVideo.alternateLink; } else if(announcement.materials[k].form != undefined){ message_announcement_attachment = String.fromCharCode(10) + announcement.materials[k].form.formUrl; } } } } //***各項目の1次元配列の作成*** announcemessage.push(announcement_updateTimesheet);//投稿の作成(更新)時刻 announcemessage.push(announcement_creatoruserId);//投稿者 announcemessage.push(message_announcement);//投稿メッセージ announcemessage.push(message_announcement_attachment);//投稿メッセージの添付 announcemessage.push("sent");//送信済フラグ Logger.log("j_announcemessage:" + j +"_" + announcemessage); //******* var message = announcemessage[1] + String.fromCharCode(10) + String.fromCharCode(10) + announcemessage[2] + announcemessage[3];//送信メッセージの作成 sheet_sent(message)//送信処理 sheet.appendRow(announcemessage);//シート配列への追加 } //—————- Logger.log("j_sheet_array:" + j +"_" + sheet_array); sheet.sort(1);//シートの並び替え } } } catch(e) { Logger.log(e); } finally { lock.releaseLock();//ロック解除 } return; } function creatoruId(announcement){ var announcement_creatoruserId; switch (announcement.creatorUserId){ case announcement.creatorUserId = "{ユーザーID1}"://?それぞれcaseで処理 announcement_creatoruserId = "{1さんの表示名}"; break; } if (announcement_creatoruserId == undefined){ announcement_creatoruserId = "名無し"; } return(announcement_creatoruserId); } function sheet_sent(message){ var CHANNEL_ACCESS_TOKEN = '{*****}'; //?チャンネルアクセストークンを入力する var group_ID = '{*******}'; //?グループIDを入力 var postData = { "to" : group_ID, "messages": [{ "type": "text", "text": message, }], "notificationDisabled" : "false", }; var url = "https://api.line.me/v2/bot/message/push"; var headers = { "Content-Type": "application/json", 'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN, }; var options = { "method": "post", "headers": headers, "payload": JSON.stringify(postData) }; var response = UrlFetchApp.fetch(url, options); return; // 実際のフォルダとスプレッドシート情報を比較。 var updateFolderMap = []; for (key in lastUpdateMap) { if( UPDATE_SHEET_ID == lastUpdateMap[key].fileId ){ continue; } if(key in sheetData) { // フォルダ名がシートに存在する場合。 if(lastUpdateMap[key].lastUpdate > sheetData[key].lastUpdate) { // フォルダが更新されている場合。 sheet.getRange(sheetData[key].rowNo, 2).setValue(lastUpdateMap[key].lastUpdate); sheet.getRange(sheetData[key].rowNo, 3).setValue(lastUpdateMap[key].fileId); updateFolderMap.push({filename:key, lastUpdate:lastUpdateMap[key].lastUpdate, fileId:lastUpdateMap[key].fileId}); } } else { // フォルダ名がシートに存在しない場合。 var newRow = sheet.getLastRow() + 1; sheet.getRange(newRow, 1).setValue(key); sheet.getRange(newRow, 2).setValue(lastUpdateMap[key].lastUpdate); sheet.getRange(newRow, 3).setValue(lastUpdateMap[key].fileId); updateFolderMap.push({filename:key, lastUpdate:lastUpdateMap[key].lastUpdate, fileId:lastUpdateMap[key].fileId}); } } function apiRequest() { const uri = 'https//.......' const options = { 'method': 'get', 'headers': headers, "muteHttpExceptions" : true, "validateHttpsCertificates" : false, "followRedirects" : false } try { const res = UrlFetchApp.fetch(uri, options); Logger.log(res) } catch(e) { // 例外エラー処理 Logger.log('Error:') Logger.log(e) } } }

記載してください。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

qnoir

2022/04/17 10:10

そのエラーは、toに指定したグループIDが正しくない(存在しないIDを含む)か、そのグループがLINEからのメッセージを受け取れない設定になっている場合に起こります。 下記を確認してください。 ・group_ID変数に設定しているグループIDが、本当に正しいIDであるか。 (先頭と末尾の{}記号は除いていますよね?) ・LINE DEVELOPERSのチャンネルの設定画面→Messaging API設定で、「グループトーク・複数人トークへの参加を許可する 」が有効になっているか。 ・作ったチャンネルを、LINE側で友達登録しているか。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Google Apps Script

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