@showin (匠 上地)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

スプレットシートで計測した数値で換気の通知をLINEに送信できるようにしたい

解決したいこと

スプレットシートで計測した数値をもとに換気の通知をLINEに送信するシステムを構築しています。
Apps scriptにコードを入力して実行した結果、lineに換気の通知が出来ずにcode 400という訳の分からないエラーが発生しました。
javascriptは初心者なので解決方法を教えて欲しいです。

発生している問題・エラー

  Exception: Request failed for https://api.line.me returned code 400. Truncated server response: {"message":"The request body has 1 error(s)","details":[{"message":"May not be empty","property":"to"}]} (use muteHttpExceptions option to examine full response)
pushMessage
@ pushToLine.gs:111

該当するコード

function pushMessage() {
  const CHANNEL_ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXX"; 
  const USER_ID = [
    'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    ];
  const VEBTILATION_CO2 = 1200; //これを超えたら換気を促す
  const CLOSE_WINDOW_CO2 = 600; //これを下回ったら換気終了を通知

//PUSH用メッセージのテンプレート
  var postData = {
    "to": [USER_ID[0],USER_ID[1]],
    "messages": [{
      "type": "text",
      "text": "",
    }]
  }

  //SpreadSheetの取得
  SS = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = SS.getSheetByName("シート1"); //Spreadsheetのシート名(タブ名)

  //二酸化炭素濃度を取得
  //過去5回の平均を取得
  var co2_1 = sheet.getRange("B1").getValue(); 
  var co2_2 = sheet.getRange("B2").getValue(); 
  var co2_3 = sheet.getRange("B3").getValue(); 
  var co2_4 = sheet.getRange("B4").getValue(); 
  var co2_5 = sheet.getRange("B5").getValue(); 

  var co2 = (co2_1 + co2_2 + co2_3 + co2_4 + co2_5) / 5;
  if(co2 > 3000){
    return;
  }
  Logger.log(co2);

  //1回の変更で2回GASが実行される
  //よくわからんけど2回のうち1回はエラーになる
  try{
    var cell = sheet.getActiveCell();
    console.log('%s %s',cell.getColumn(),cell.getRow());
  }catch(e){
    console.log('Out of Range Error.');
    return;
  }

  //ここらへんはチャタリング(測定値がブレることによって短時間で何回も通知が来る)の防止
  //過去30分間で通知をしたかどうか
  //Trueならば通知はしなくてもいい
  var is_notification_past30_min = false
  var sheetdata = sheet.getSheetValues(1, 3, 30, 1);   
  for(var i = 0; i<30; i++){
    if(sheetdata[i][0] == '要換気'){
      is_notification_past30_min = true;
      break;
    }
  }
  //直近の通知が「要換気」かどうか
  var is_notification_kanki = false
  for(var i = 1; i <= 1440; i++){
    cell = 'C' + i;
    var value =  sheet.getRange(cell).getValue();
    //要換気であれば換気終了の通知を出しても良い
    if(value == '要換気'){
      is_notification_kanki = true;
      break;
    //換気終了であればチャタリング防止
    }else if(value == '換気終了'){
      is_notification_kanki = false;
      break
    }  
  }


  //通知有無のフラグ 0:通知不要 1:換気通知 2:換気終了通知
  var is_notification_flag = 0;
  // 通知有無の判定
  if(co2 > VEBTILATION_CO2 && is_notification_past30_min == false){  //規定の濃度が超えてる かつ 直近30分以内に通知をしていない
    is_notification_flag = 1;  //CO2濃度が一定値を超えた場合
  }else if(co2 < CLOSE_WINDOW_CO2 && is_notification_kanki == true){  //規定の濃度を下回った かつ 直近の通知が「要換気」
    is_notification_flag = 2;  //CO2濃度が一定値を超えた場合
  }else{
    is_notification_flag = 0;
    console.log('NOT need to push a message');
  }

  // 通知有無の判定
  if(is_notification_flag == 1){
    postData.messages[0].text = "換気してください。:" + parseInt(co2) + "ppm";
    var range = sheet.getRange("C1").setValue('要換気');
  }else if(is_notification_flag == 2){
    postData.messages[0].text = "換気を完了してください。:" + parseInt(co2) + "ppm";
    var range = sheet.getRange("C1").setValue('換気終了');
  }else{
    return;
  }

  var url = 'https://api.line.me/v2/bot/message/multicast';
  var headers = {
    'Content-Type':'application/json; charset=UTF-8',
    'Authorization':'Bearer ' + CHANNEL_ACCESS_TOKEN
  };



  var options = {
    'method':'post',
    'headers':headers,
    'payload':JSON.stringify(postData)
  };
  //LINE messanger APIを叩く
  UrlFetchApp.fetch(url, options);
}

参考にしたサイト

https://qiita.com/tororu/items/20e8625d3fb24f3e06da
上記のサイトのプログラムを模写したのですが、エラーが出てしまいました。

0 likes

1Answer

エラーメッセージにThe request body has 1 error(s)とあります
detailsのmessageにはMay not be emptyとあり、propertyがtoと書いてあるので、
toの値がおかしいのでしょう。
ご提示いただいたプログラムでは、USER_IDの0,1が入れられていますが、
USER_IDは1つしか値がない状態です。
これはご提示いただいたプログラムがそうなだけで、本来のプログラムではちゃんとした値が入っている認識であっていますか?

例えばtoの値を下記のように変更するとどうなりますか?

- "to": [USER_ID[0],USER_ID[1]],
+ "to": [USER_ID[0]],
1Like

Comments

  1. @showin

    Questioner

    返信が遅くなり申し訳ありません。回答ありがとうございます。

    これはご提示いただいたプログラムがそうなだけで、本来のプログラムではちゃんとした値が入っている認識であっていますか?についての質問は、自分のLINEBOTで提示されているUSER_IDを入力しています。

    上記の変更する点は、"to": [USER_ID[0],USER_ID[1]],ところを"to": [USER_ID[0]],に変更することで当たっているでしょうか?
  2. 完全に忘れてました、解決しましたか?

    > 上記の変更する点は、"to": [USER_ID[0],USER_ID[1]],ところを"to": [USER_ID[0]],に変更することで当たっているでしょうか?
    その通りです
  3. @showin

    Questioner

    変更したところ
    ```javascript
    var postData = {
    "to": [USER_ID[0]],
    "messages": [{
    "type": "text",
    "text": "",
    }]
    }
    ```
    発生しているエラー
    ```javascript
    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: 1, column: 7)"} (use muteHttpExceptions option to examine full response)
    pushMessage @ pushToLine.gs:111
    ```
    上記の通り、修正したのですが同じエラーが出ました。

  4. ありがとうございます
    USER_IDは、他の方法で送れるのか、確認することは可能ですか?
    (curlやPostmanを使ってみるなど)
    入力しているtoの値が正しければそのようなエラーは出ないと思われるのですが、
    現状ではその値が正しいかが判断つきません
  5. @showin

    Questioner

    ### 修正したコード
    ```javascript
    var postData = {
    "to": USER_ID,
    "messages": [{
    "type": "text",
    "text": "",
    }]
    }
    ```
    改めて自分で調べて修正した結果、LINEに換気の通知ができ解決することができました。
    修正箇所を教えて頂いたおかげで助かりました。
    ありがとうございます。

Your answer might help someone💌