1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GASとスプレッドシートを使って、LineBotを定期的にPUSHさせてみた。

Last updated at Posted at 2021-01-15

###背景
家に花を飾っていて妻と子供が育てているのですが、よく水やりを忘れてます。
ちょっとその辺のホームセンターで綺麗な花を買ってきては1ヶ月ももたずに枯れていきます。
「なんてかわいそうなんだ、それならば私が水やりをやってあげよう!」と頑張ってみましたが、幾分私もそんなにマメな性格ではないので、時折忘れています。(親子は似るんだなぁ)
スマホに通知がくれば忘れずに水やりできるだろう、と考え作ってみました。

###使用したもの
・GoogleAppsScript
・GoogleSpreadSheet
・LINEbot
・VSCODE

###開発内容

※LINEアカウント作成等は割愛いたします。
・月毎に水やりの周期が変わるので、スプレッドシートに記載した周期を取得
・LINEボットに水やり当日に発言させる。
・発言と同時にGoogleカレンダーへ次回の水やり日を登録する。
 (LINEの通知だけで十分ですが、アレクサにGoogleカレンダーの予定を喋らせたかったので)

スプレッドシート.png

使い慣れた環境がよかったので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("xxxxxxxxxxxx@gmail.com");
  // 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でトリガーを設定します。

トリガー4.png

トリガー1.png

トリガー2.png

トリガー3.png

デプロイします。

デプロイ.png

通知が来ました。
Screenshot_2021-01-15-08-56-08-89.png

###補足
jsの日付比較は何かと面倒です。
今回は使っていませんが、ライブラリの「moment」を使用すると1行でできそうです。
ちなみにスクリプトIDは以下のとおりです。

スクリプトID: MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48

###まとめ
これでお花が枯れないと思うと心が躍ります。
次はラズパイを組み合わせてみたいと思ってます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?