Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【GAS】Googleカレンダーの予定をLINEで受け取る

More than 1 year has passed since last update.

はじめに

Googleカレンダーに登録してある今日の予定、また明日の予定を一定の時刻にLINEで受け取るというものをつくっていきます。

私自身初心者なのでプロジェクト作成方法や設定の仕方等も書いていきます。
なお、コードは最後にまとめてあります。

完成イメージ

①朝、Googleカレンダーの今日の予定をLINEで受け取る。
②夕方、Googleカレンダーの明日の予定をLINEで受け取る。

<送る内容>
・日時
・タイトル
・場所(登録があったら)
・説明(登録があったら)
なお、予定が無ければ無いよと送る。

使用するカレンダー

q_s_cal.png

設定

プロジェクトの新規作成

まず、最初の状態では入っていないGoogle Apps Scriptを追加します。
Googleドライブ > 新規 > ①その他 > ②アプリを追加

q_s_1.png

Google Apps Script を探して ③接続

q_s_2.png

▼▼▼

q_s_3.png

追加できたので早速プロジェクトを新規作成します。
Googleドライブ > 新規 > ④その他 > ⑤Google Apps Script

q_s_4.png

ひとまずプロジェクトに名前を付けます。
ファイル > 名前の変更 でも、画面上部のプロジェクト名をクリックでも変えられます。

q_s_5.png

スクリプトにも。

q_s_6.png
q_s_7.png

以上でプロジェクトの新規作成は完了です。

LINEとの連携設定

LINE Notifyとの連携が必要になるので、その辺りを設定していきます。

こちらにアクセスし、 ①ログイン します。
※LINEアプリの方でメールアドレスの設定とログイン許可の設定が必要です。

q_s_10.png
q_s_11.png

ログインしたら ②マイページ > ③トークンを発行する

q_s_12.png
q_s_13.png

トークンの設定をしていきます。
④トークン名:自由に入力できます。ちなみにココに出ます。 1
⑤トークルームを選択:今回は『1:1でLINE Notifyから通知を受け取る』を選択します。
完了したら ⑥発行する をクリックします。

q_s_14.png

▼▼▼

q_s_15.png

⑦コピー したトークンを使っていきましょう。

以上でLINEとの連携設定は完了です。

プロパティの設定

直打ちを避けたいので、先ほどのトークンはプロパティに設定します。
ファイル > ①プロジェクトのプロパティ

q_s_8.png

②スクリプトのプロパティ > ③行を追加 > さっきのトークンを設定 > ④保存

q_s_9.png

以上でプロパティの設定は完了です。

コード

準備が整ったのでコードを書いていきましょう。

メイン処理

main.gs
function sendTodaySchedule() {
  var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
  // 引数により取得する日付を変えられるようにしたいので、
  // 今日から何日後かを渡すようにします。
  var message = getMessage(0);
  var options =
   {
     'method'  : 'post'
    ,'payload' : 'message=' + message
    ,'headers' : {'Authorization' : 'Bearer '+ accessToken}
    ,muteHttpExceptions:true
   };
  UrlFetchApp.fetch('https://notify-api.line.me/api/notify',options);
}

カレンダー内容の取得処理

main.gs
/**
* メッセージ内容取得
* @param {number} 今日起算の日数
* @return {string} メッセージ内容
*/
function getMessage(prm) {
  const week = ['','','','','','',''];
  var cal = CalendarApp.getCalendarById('*****************@gmail.com');
  var date = new Date();
  var strBody = '';
  var strHeader = '';
  // タイトル
  if ( prm==0 ) {
    strHeader = '今日 ';
  } else if ( prm==1 ) {
    strHeader = '明日 ';
  } 
  date = new Date(date.getYear(),date.getMonth(),date.getDate() + prm);
  strHeader += Utilities.formatDate(date,'JST','yyyy/M/d')
                + '(' +week[date.getDay()] + ') の予定\n';
  // 内容
  strBody = getEvents(cal,date);
  if ( _isNull(strBody) ) strBody = '予定はありません。';
  return strHeader + strBody;
}

/**
* カレンダーイベント内容取得
* @param {object} カレンダー
* @param {date} 日付
* @return {string} イベント内容
*/
function getEvents(prmCal,prmDate) {
  var strEvents = '';
  var strStart = '';
  var strEnd = '';
  var strTime = '';
  var strLocation = '';
  var strDescription = '';
  if ( !_isNull(prmCal) ) {
     var arrEvents = prmCal.getEventsForDay(new Date(prmDate));
     for (var i=0; i<arrEvents.length; i++) {
       if ( !_isNull(strEvents) ) strEvents += '\n';
       strStart = _HHmm(arrEvents[i].getStartTime());
       strEnd = _HHmm(arrEvents[i].getEndTime());
       if ( strStart===strEnd ) {
         strTime = '終日';
       } else {
         strTime = strStart + '' + strEnd;
       }
       strEvents += '' + strTime + '' + arrEvents[i].getTitle() + '';
       strLocation = arrEvents[i].getLocation();
       strDescription = arrEvents[i].getDescription();
       if ( !_isNull(strLocation) ) strEvents += '\n 場所:' + strLocation;
       if ( !_isNull(strDescription) ) strEvents += '\n 説明:' + strDescription;
     }
  }
  return strEvents;
}
/**
* 時刻フォーマット
*/
function _HHmm(str){
  return Utilities.formatDate(str,'JST','HH:mm');
}
/**
* NULL判定
* @param {object} 判定対象
* @return {bool} NULLの場合TRUE
*/
function _isNull(prm) {
  if ( prm=='' || prm===null || prm===undefined ) {
    return true;
  } else {
    return false;
  }
}

難しいことはしていませんが、開始時刻と終了時刻が等しいと終日となるのははじめて知りました。
ということで、ひとまずメッセージ内容をログに出してみます。

main.gs
function test(){
  var message = getMessage(0);
  Logger.log('今日\n' + message);
  message = getMessage(1);
  Logger.log('\n明日\n' + message);
}

▼▼▼

q_s_16.png

では改めて sendTodaySchedule() を実行しましょう。

なお、初回だと承認が必要になります。
①許可を確認 > 「アカウントを選択」にて、承認するアカウントを選択 > ②許可 とすれば承認されます。

q_s_oath_1.png
q_s_oath_2.png

ということで

line.png

LINEきましたね。
大丈夫そうなので少し戻り、明日のスケジュールを送るメイン処理も追加しておきます。

main.gs
function sendTomorrowSchedule() {
  var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
  // getMessage()の引数を1にするだけです。
  // 明後日なら3、1週間後なら7にすれば該当するイベント情報を取得できます。
  var message = getMessage(1);
  var options =
   {
     'method'  : 'post'
    ,'payload' : 'message=' + message
    ,'headers' : {'Authorization' : 'Bearer '+ accessToken}
    ,muteHttpExceptions:true
   };
  UrlFetchApp.fetch('https://notify-api.line.me/api/notify',options);
}

以上でコーディングが完了です。

自動送信の設定

これまた便利な機能。

①編集 > ②現在のプロジェクトのトリガー

q_s_17.png

③新しいトリガーを作成します

q_s_18.png

④実行する関数を選択:sendTodaySchedule
⑤イベントのソースを選択:時間主導型
⑥時間ベースのトリガーのタイプを選択:日付ベースのタイマー
⑦時刻を選択:午前5時~午前6時
を設定 > ⑧保存

q_s_19.png

これで今日の予定を送信するトリガーは完了です。
次に、同じ要領で明日の予定を送信するトリガーを設定していきます。
画面右下にある ⑨トリガーを追加 > 関数(sendTomorrowSchedule)と時間を設定 > 保存

q_s_20.png
q_s_21.png

以上で自動送信の設定が完了です。

まとめ

コード
main.gs
/**
* Googleカレンダーの
* 今日の予定をLINEに送る
*/
function sendTodaySchedule() {
  var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
  var message = getMessage(0);
  var options =
   {
     'method'  : 'post'
    ,'payload' : 'message=' + message
    ,'headers' : {'Authorization' : 'Bearer '+ accessToken}
    ,muteHttpExceptions:true
   };
  UrlFetchApp.fetch('https://notify-api.line.me/api/notify',options);
}

/**
*  Googleカレンダーの
* 明日の予定をLINEに送る
*/
function sendTomorrowSchedule() {
  var accessToken = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
  var message = getMessage(1);
  var options =
   {
     'method'  : 'post'
    ,'payload' : 'message=' + message
    ,'headers' : {'Authorization' : 'Bearer '+ accessToken}
    ,muteHttpExceptions:true
   };
  UrlFetchApp.fetch('https://notify-api.line.me/api/notify',options);
}

/**
* メッセージ内容取得
* @param {number} 今日起算の日数
* @return {string} メッセージ内容
*/
function getMessage(prm) {
  const week = ['','','','','','',''];
  var cal = CalendarApp.getCalendarById('*************@gmail.com');
  var date = new Date();
  var strBody = '';
  var strHeader = '';
  // タイトル
  if ( prm==0 ) {
    strHeader = '今日 ';
  } else if ( prm==1 ) {
    strHeader = '明日 ';
  } 
  date = new Date(date.getYear(),date.getMonth(),date.getDate() + prm);
  strHeader += Utilities.formatDate(date,'JST','yyyy/M/d')
                + '(' +week[date.getDay()] + ') の予定\n';
  // 内容
  strBody = getEvents(cal,date);
  if ( _isNull(strBody) ) strBody = '予定はありません。';
  return strHeader + strBody;
}

/**
* イベント取得
* @param {object} カレンダー
* @param {date} 取得日
* @return {string} イベント情報
*/
function getEvents(prmCal,prmDate) {
  var strEvents = '';
  var strStart = '';
  var strEnd = '';
  var strTime = '';
  var strLocation = '';
  var strDescription = '';
  if ( !_isNull(prmCal) ) {
     var arrEvents = prmCal.getEventsForDay(new Date(prmDate));
     for (var i=0; i<arrEvents.length; i++) {
       if ( !_isNull(strEvents) ) strEvents += '\n';
       strStart = _HHmm(arrEvents[i].getStartTime());
       strEnd = _HHmm(arrEvents[i].getEndTime());
       if ( strStart===strEnd ) {
         strTime = '終日';
       } else {
         strTime = strStart + '' + strEnd;
       }
       strEvents += '' + strTime + '' + arrEvents[i].getTitle() + '';
       strLocation = arrEvents[i].getLocation();
       strDescription = arrEvents[i].getDescription();
       if ( !_isNull(strLocation) ) strEvents += '\n 場所:' + strLocation;
       if ( !_isNull(strDescription) ) strEvents += '\n 説明:' + strDescription;
     }
  }
  return strEvents;
}

/**
* 時間フォーマット
*/
function _HHmm(str){
  return Utilities.formatDate(str,'JST','HH:mm');
}

/**
* NULL判定
*/
function _isNull(prm) {
  if ( prm=='' || prm===null || prm===undefined ) {
    return true;
  } else {
    return false;
  }
}

入門ということでコードは単純です。

最近すっかりGASにハマっているので、ちまちまと遊んだものを書いていければと思います。
次は個人的に便利につかっている、天気予報をまたLINEに送るやつを作ります。

余談ですが、時刻きっかりに送りたい場合はこちらがとても参考になります。

参考サイト

Google Apps ScriptからLINE NotifyでLINEにメッセージを送る - Qiita
Google Apps Script(GAS)から LINE notify API を利用して通知を送る - Qiita
GASでGoogleカレンダーの当日の情報を定期的にGmailに送信する! - IT-LIFEブログ
曜日を一行で取得するJavaScriptはこちらです。 _ Ginpen.com
【GAS】getEventsメソッドを完全マスター

ありがとうございました。

修正(最新:19/10/27)

  • getMessage() を修正いたしました。(19/10/27)
    【誤】weekw[date.getDay()]
    【正】week[date.getDay()]

  1. q_s_line.png 

ikei
雰囲気でプログラミングをやってます。趣味(ほぼGAS)とまれに仕事の備忘録。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away