3
9

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 3 years have passed since last update.

【GAS × LINE WORKS】今日一日の予定をまとめて教えてくれる Bot を作りました

Last updated at Posted at 2021-01-21

LINE WORKS を使っていて、今日の予定を思い出すのにいちいちカレンダー見に行くのめんどくさいなー('Д') と思ったのがきっかけです。

調べてみたところ、LINE WORKS カレンダーには通知機能があるのですが、あくまで個々の予定での通知で、まとめてお知らせしてくれるような機能はないようです。
LINE WORKS ガイド - カレンダー予定作成 10.通知

なら作ってしまえ!ヾ(´∀`)ノ
と思って作ったのがこちらです。

1611198006.png

  • Google Apps Script で作成したので、トリガーを作成して毎朝 9時に通知してくれるようにしました。
  • カレンダーへのリンクも貼り付けてあるのでワンクリックで詳細も確認しに行けます。

機能はただこれだけなんですが、意外とというか、結構便利。
自分がやっている単純な動作を一つ自動化しただけでも、何となくスムーズに仕事に入れている気がします。

こういうの、どんどん探していきたいですね!

以下、作り方です。良かったらどーぞ。

作るに当たって必要なもの

  • LINE WORKS アカウント
  • Google アカウント

使用するサービス

  • Google Apps Script(略称 GAS)

Google が提供しているスクリプト言語。
開発環境不要で無料で Gooogle のアプリの連携サービスなどが使用できる。

  • LINE WORKS API

WORKS MOBILE Japan が提供している API
今回使用するのはトーク Bot APIカレンダー API

開発手順

  1. LINE WORKS 認証情報の取得
  2. LINE WORKS Bot の登録
  3. LINE WORKS Service API Token を取得
  4. Google Apps Script でコードを書く
  5. Google Apps Script Home でトリガーを設定

1 ~ 3 は登録・取得手順のリンクを貼っておきましたのでそちらをご参考くださいませ。

Google Apps Script でコードを書く

Google Apps Script Home にアクセスして「新しいプロジェクト」を作成します。
プロジェクト名は何でも良いのですが、私は Concierge Bot にしました。

1611199810.png

そう言えば、Google Apps Script の画面、新しくなりましたね。
まだ慣れていませんが、前より使いやすくなった気がします。

ライブラリの登録

Google Apps Script には javascript のモジュールみたいに ライブラリ という機能があります。これがとても便利。

LINE WORKS の API を使用するにあたり JWT の認証が必要になるのですが、ライブラリを登録しておけば勝手にやってくれます!ヾ(´∀`)ノ

  1. 左側メニューの「ライブラリ」にある「+」をクリック
  2. 「ライブラリを追加」画面でスクリプト ID に 1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod を入力して検索ボタンをクリック
  3. 「LINEWORKS」ライブラリが表示されるので、一番新しいバージョンを選んで追加ボタンをクリック

登録したら、コードを書いていきます。

コード.gs
// LINE WORKS 認証情報
const CONSTS = {
  'apiId': 'xxxxxxxxx',
  'consumerKey': 'xxxxxxxxxxx',
  'serverId': 'xxxxxxxxxxxxxxx',
  'privateKey': '-----BEGIN PRIVATE KEY-----\nxxxxxxxxxx\n-----END PRIVATE KEY-----',
  'accountId': 'xxxxx@xxxxxxx',
  'serviceApiConsumerKey': 'xxxxxxxxxxxx',
  'serviceToken': 'xxxxxxxxxxxxxxxxxxxxxxxxx',
  'botNo': 'xxxxxxxxxxxx'
}

// メインプログラム
function main() {
  const events = getLineworksCalendar()
  LINEWORKS.sendMsg(CONSTS, CONSTS.accountId, `今日の予定は ${events.length}件です`)
  events.forEach((event) => {
    const ical = separateIcal(event.ical)
    let time
    if(ical['DTSTART;VALUE=DATE']){
      time = '終日の予定だよ'
    } else if(ical['DTSTART;TZID=Asia/Tokyo']){
      const start = getTime(ical['DTSTART;TZID=Asia/Tokyo'])
      const end = getTime(ical['DTEND;TZID=Asia/Tokyo'])
      time = `${start.hour}${start.minute}分から${end.hour}${end.minute}分の予定だよ`
    }
    LINEWORKS.sendLink(CONSTS, CONSTS.accountId, `${time}\n●${ical.SUMMARY}`, '予定の詳細を確認', event.viewUrl)
  })
}

// ical データを解析してオブジェクトに変換
function separateIcal(ical){
  const splitN = ical.split('\n')
  let icalArray = {}
  splitN.forEach((e) => {
    const splitC = e.split(':')
    icalArray[splitC[0]] = splitC[1]
  })
  return icalArray
}

// ical データ内の時刻をオブジェクトに変換
function getTime(time){
  const t = time.split('T')[1]
  return {
    'hour': t.slice(0,2),
    'minute': t.slice(2,4),
    'second': t.slice(4,6)
  }
}

// LINE WORKS カレンダーから今日の予定をすべて取得
function getLineworksCalendar() {
  const today = new Date()
  let tomorrow = new Date()
  tomorrow.setDate(tomorrow.getDate() + 1)

  const startDate = Utilities.formatDate(today, 'Asia/Tokyo', 'yyyyMMdd')
  const endDate = Utilities.formatDate(tomorrow, 'Asia/Tokyo', 'yyyyMMdd')
  const uri = `https://apis.worksmobile.com/r/${CONSTS.apiId}/calendar/v2/users/me/calendars/defaultCalendarId/events?rangeDateFrom=${startDate}&rangeDateUntil=${endDate}`
  const headers = {
    'consumerKey': CONSTS.serviceApiConsumerKey,
    'Authorization': `Bearer ${CONSTS.serviceToken}`
  }
  const options = {
    'method': 'get',
    'headers': headers
  }
  try {
    //成功時
    const res = JSON.parse(UrlFetchApp.fetch(uri, options))
    Logger.log('Success:')
    return res.returnValue    
  } catch(e) {
    //エラー時
    Logger.log('Error:')
    Logger.log(e)
  }
}

一番最初の LINE WORKS 認証情報のところは自分の環境での情報を入れてください(*'▽')

Google Apps Script でトリガーを設定

画面左側の時計マークをクリックして、トリガーの画面を表示します。
右下の「トリガーを追加」をクリックしてトリガーを追加します。

1611210433.png

実行する関数は main日付ベースのタイマー を設定します。
私は 9時までには送ってきて欲しいので 午前8時~9時 を選択しました。

1611210596.png

1611210616.png

すると、朝になると今日一日の予定を通知してくれます。

1611198006.png

これで完成です!やったね♪(*‘∀‘)

コーディングで苦戦したところ

  • ical データの解析

Node.js には ical パッケージがあるんですけどね。
GAS では見当たらなかったので自分で分解して必要なデータだけ取り出しました。
split 2回もしてめんどかったです。

  • ical の日付の解析

これもね、moment の GAS 版ライブラリを使おうかと思ったんですけどね。
トップページを和訳して読んでみたら、もう moment.js は更新しないんですって。
使わない方が良いらしいので、自前で解析しました。
良いライブラリが他にありましたら教えてください(*_ _)

ちなみに ical データ内の時刻データはこんな感じです。
EX) 20210121T170000

RFC 基準に沿った書き方のようですが、RFC をよく読むとフォーマットが微妙に違うようなのは私のきのせいでしょうか・・・?
RFC EX) 1985-04-12T23:20:50.52Z

兎に角。
ical データはあんまり扱ったことがなかったので割と苦戦しました。( ´Д`)=3 フゥ

おわりに

ここまでお付き合いいただきありがとうございました。

冒頭にも書きましたが、自分がやっている単純な動作を一つ自動化しただけなのですが、スムーズに動けるというか、少し肩こりが取れた的な感じがします。

業務改善って考えると何やら難しく考えがちですが、こんな感じの積み重ねなのかもしれませんね。

ではまた!(^^)/

参考にさせていただきましたm(_ _)m

LINEWORKS Developers

3
9
3

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
3
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?