GAS와 스프레드시트를 사용하여 LineBot을 정기적으로 PUSH시켜 보았다.

### 배경
집에 꽃을 장식하고 아내와 아이가 키우고 있지만 잘 물을 잊고 있습니다.
조금 그 근처의 홈 센터에서 깨끗한 꽃을 사 와서는 1개월도 없이 시들어 갑니다.
"그렇게 귀여워, 그렇다면 내가 물을 해줄게!"라고 노력해 보았습니다만, 약간 나도 그렇게 엄청난 성격이 아니기 때문에, 때때로 잊고 있습니다. (부모와 자식은 비슷하다)
스마트 폰에 통지가 주면 잊지 않고 물을 줄 수있을 것이라고 생각 만들어 보았습니다.
### 사용한 것
· GoogleAppsScript
· GoogleSpreadSheet
・LINEbot
· VSCODE
### 개발 내용
※LINE 계정 작성 등은 할애합니다.
・월마다 물의 주기가 바뀌므로, 스프레드 시트에 기재한 주기를 취득
・LINE 봇에게 물을 주고 당일에 발언시킨다.
· 발언과 동시에 Google 캘린더에 다음 회수일을 등록한다.
(LINE의 통지만으로 충분합니다만, 알렉사에게 Google 캘린더의 예정을 말하고 싶었기 때문에)

익숙한 환경이 좋았기 때문에 VSCODE로 코딩했습니다.

linebot.js

// アクセストークンとuserIdを設定
// userIDはビジネスアカウントでログインした場合、LINEアカウントと連携すると表示される。
const CHANNEL_ACCESS_TOKEN = "アクセストークン";
const To = "ユーザーID";

function main() {
  // スプレッドシートの入力値を取得
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getSheets()[0];
  const range = sh.getRange("A5:C16");
  const date = new Date();
  const month = date.getMonth() + 1;

  // 水やりの日だけLINE送信
  if (isWateringDay(sh, range, date)) {
    const message = range.getCell(month, 3).getValue(); // メッセージを取得
    push(message); // LINEメッセージ送信
    registCalenderEvent(range, month);
  }
}

/*
  スプレッドシートのデータを取得し、次回の水やり日を演算する
  @return:当日が水やり日→true、それ以外→false
*/
function isWateringDay(sh, range, date) {
  // スプレッドシートの毎月の水やり周期を取得
  let numberOfMonth = [];
  for (let i = 1; i <= 12; i++) {
    numberOfMonth.push(range.getCell(i, 2).getValue());
  }

  // スプレッドシートの水やり起点(開始日)を取得
  const start = sh.getRange("A1").getValue();
  let calDate = new Date(start);

  // 水やりする日を更新
  while (date > calDate) {
    if (date.getDate >= calDate.getDate) {
      calDate.setDate(calDate.getDate() + numberOfMonth[calDate.getMonth()]);
    }
  }

  console.log("現在年月日:" + date);
  console.log("次回の水やり日:" + calDate);

  // 現在年月日と水やりの日付が一致した場合、trueを返す
  if (date.getFullYear() == calDate.getFullYear()) {
    console.log("年が一緒");
    if (date.getMonth() == calDate.getMonth()) {
      console.log("月が一緒");
      if (date.getDate() == calDate.getDate()) {
        console.log("日が一緒");
        return true;
      }
    }
  }
  return false;
}

// 次回の水やり日をgoogleカレンダーに登録
function registCalenderEvent(range, month) {
  // カレンダーに登録する日時を作成
  let nextWateringDayStart = new wateringDateToCalendar(7, 0, range, month);
  let nextWateringDayEnd = new wateringDateToCalendar(8, 0, range, month);

  // アクセス可能なカレンダーのIDを指定して、Googleカレンダーを取得する
  let myCalendar = CalendarApp.getCalendarById("[email protected]");
  // Googleカレンダーに予定を登録する
  myCalendar.createEvent("水やり", nextWateringDayStart, nextWateringDayEnd);
}

// カレンダー用date
function wateringDateToCalendar(hour, minutes, range, month) {
  let date = new Date();
  // 時間を設定
  date.setHours(hour);
  date.setMinutes(minutes);
  // 日(次回の水やりの日)を設定
  date.setDate(date.getDate() + range.getCell(month, 2).getValue());

  return date;
}

// プッシュ
function push(text) {
  const url = "https://api.line.me/v2/bot/message/push";
  const headers = {
    "Content-Type": "application/json; charset=UTF-8",
    Authorization: "Bearer " + CHANNEL_ACCESS_TOKEN,
  };

  const postData = {
    to: TO,
    messages: [
      {
        type: "text",
        text: text,
      },
    ],
  };

  const options = {
    method: "post",
    headers: headers,
    payload: JSON.stringify(postData),
  };
  return UrlFetchApp.fetch(url, options);
}



GAS에서 트리거를 설정합니다.




배포합니다.

알림이 왔습니다.

### 보충
js의 날짜 비교는 뭔가 귀찮습니다.
이번에는 사용하지 않지만 라이브러리의 "moment"를 사용하면 한 줄로 할 수 있습니다.
덧붙여서 스크립트 ID는 다음과 같습니다.
스크립트 ID: MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48
### 정리
이것으로 꽃이 시들지 않는다고 생각하면 마음이 뛰어납니다.
다음은 라즈파이를 조합해 보고 싶습니다.

좋은 웹페이지 즐겨찾기