目的
LINEボットにリッチメニューを追加し、スプレッドシートの情報(日程情報、メンバーの出欠 、天気予報(tenki.jpのスクレイピング))を回答する機能を追加する。
※ボットとの1対1トークだとリッチメニューが出る。
※グループトークだとリッチメニューは出ないが、コマンドには応答してくれる。
※2022年になってからtenki.jpがrequestsで取得できなくなった。記事を書き直すのも大変なので、そのまま公開する。詳しく調べてないが、たぶんUser Agentをチェックして応答を拒否していると思われる。
背景
前回記事「LINEボットでチャット内容をメールに転送する」に続き、趣味のグループについて、日程情報やメンバーの出欠や天気予報を、ボットが教えてくれたら便利かもしれないと思ったので、機能を追加してみた。
環境
- iPhoneX 14.4.2
- LINE 11.6.5
- Google Apps Script(GAS) March 15, 2021
- Windows10 バージョン2004(OSビルド19041.928)
- Google Chrome バージョン: 90.0.4430.93(Official Build) (64 ビット)
全体像
ユースケース図
アクターの補足説明
GAS(Google Apps Script)トリガーとは、指定時刻になったり、スプレッドシートが更新されたら、GASを自動で実行してくれるトリガー機能とする。
クラス図っぽいもの
天気予報のスクレイピングはただの関数でやってるので、クラス図に出てこない。
他にもクラスに入ってないものがあるけどご愛敬。
やったこと
- ボットの作成などは前回記事「LINEボットでチャット内容をメールに転送する」でできているものとする
- スプレッドシートの作成(名簿、日程
、天気予報、リッチメニューのキャッシュ) - GASの作成
- GASトリガーの設定
- リッチメニューの画面を作成
- リッチメニューを登録
ボットの作成などは前回記事でできているものとする
前回記事「LINEボットでチャット内容をメールに転送する」をリファクタしたコードをGitHub LINE_BOT_TENSOU tag 1.0.2に用意した。(詳しくはReadme参照)
スプレッドシートの作成
ユースケースにもある以下の四つのスプレッドシートを作成して、IDとシート名をそれぞれ控える。
※スプレッドシートのURLは、以下の書式となっており、XXXXXXXの部分がIDになる。
https://docs.google.com/spreadsheets/d/XXXXXXX/edit
-
日程情報スプレッドシート
※1行目(F列以降)にはメンバーの名前が入っている。
※2行目以降がイベント予定で、E列が空欄になっているイベントはボットに無視される。
※2行目以降(F列以降)には出欠が入っている。
GASの作成
そして、今回の機能追加したボットをGitHub LINE_BOT_TOBA tag 1.0.2に用意した。
チャンネルアクセストークンはスクリプトプロパティに設定する。以下はコードの利用箇所。
const CHANNEL_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('CHANNEL_ACCESS_TOKEN');
また、先に控えたスプレッドシートのIDとシート名をスクリプトプロパティに設定する。以下はコードの利用箇所。
// 「名簿」のスプレッドシート
const MEMBER_SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('MEMBER_SPREADSHEET_ID');
const MEMBER_SHEET_NAME = PropertiesService.getScriptProperties().getProperty('MEMBER_SHEET_NAME');
// 「日程調整」のスプレッドシート
const SCHEDULE_SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('SCHEDULE_SPREADSHEET_ID');
const SCHEDULE_SHEET_NAME = PropertiesService.getScriptProperties().getProperty('SCHEDULE_SHEET_NAME');
// 「天気予報」のスプレッドシート
const FORECAST_SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('FORECAST_SPREADSHEET_ID');
const FORECAST_SHEET_NAME = PropertiesService.getScriptProperties().getProperty('FORECAST_SHEET_NAME');
// 「リッチメニュー」のスプレッドシート
const RICHMENUS_SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('RICHMENUS_SPREADSHEET_ID');
const RICHMENUS_SHEET_NAME = PropertiesService.getScriptProperties().getProperty('RICHMENUS_SHEET_NAME');
GASトリガーの設定
以下の画面イメージの様に、指定時刻のトリガーを仕掛ける。
getForecastFromUrlToSpreadsheet() は、ユースケースの「天気予報スプレッドシート」にある「tenki.jpから10日間天気予報を取得して、スクレイピングして、スプレッドシートを更新」する処理である。私は12時間毎に起動させている。ちなみに石川県七尾市の天気予報をとってきているので、変えたい場合は、コードの以下のgetUrlを変更する。
//tenki.jpから10日予報取得
let getUrl = 'https://tenki.jp/forecast/4/20/5620/17202/10days.html';
updateRichMenuAll() は、ユースケースの「リッチメニュー応答文のキャッシュ用スプレッドシート」にある「新しいリッチメニュー応答文で、スプレッドシートを更新」する処理である。こちらも12時間ごとに起動させている。
また、日程情報スプレッドシートが変更されたら、キャッシュ用スプレッドシートを更新しなおす必要がある。日程情報スプレッドシートのスクリプトエディタで、以下の画面イメージの様なonChange()にupdateRichMenuAll()を設定する。
リッチメニューの画面を作成
リッチメニューに使う、四分割画像を用意するために、元となる画像を4枚用意して、1枚の画像に合成する。
使い慣れたツールがなければ、ブラウザで画像結合ツール にアクセスして画像を合成する。
リッチメニューの文字を画像に埋め込む。
使い慣れたツールがなければ、ブラウザで画像にウォーターマークを挿入するツールにアクセスして、画像に文字を埋め込む。
作成した画像をGoogleDriveに保存してリンクを取得する。
リンクの<ファイルID>部分を、後の「リッチメニューを登録」に使用する。
※GoogleDriveで共有リンクを生成すると以下のURLとなる
https://drive.google.com/file/d/<ファイルID>/view?usp=sharing
https://drive.google.com/open?id=<ファイルID>
リッチメニューを登録
- 先の章でGoogleDriveに保存したリッチメニュー画像のファイルIDを、GASのスクリプトプロパティDRIVE_FILE_IDに登録する
- GASの「LINEボットMessageingAPI.gs」を開く
- myMakeRichMenu()を選択し実行する
- mySetDefaultRichMenu()を選択し実行する
使い方
- GitHubから1.0.2をダウンロードする
- ダウンロードしたファイルを解凍する
- GoogleDriveにスクリプトファイル(GAS)を作り、解凍したファイルからコピペなどして同じ内容になるようにする※
- GoogleDriveに以下のスプレッドシートを作成する(本文を見てヘッダーをそろえること)
天気予報- リッチメニュー
- 日程調整
- 名簿
- 作成したスプレッドシートやファイルのIDを調べる
- GASに以下のスクリプトプロパティを作成する
- CHANNEL_ACCESS_TOKEN:チャンネルアクセストークン
- FORECAST_SPREADSHEET_ID:天気予報スプレッドシートのID
- FORECAST_SHEET_NAME:天気予報スプレッドシートのシート名
- RICHMENUS_SPREADSHEET_ID:リッチメニュースプレッドシートのID
- RICHMENUS_SHEET_NAME:リッチメニュースプレッドシートのシート名
- SCHEDULE_SPREADSHEET_ID:日程調整スプレッドシートのID
- SCHEDULE_SHEET_NAME:日程調整スプレッドシートのシート名
- MEMBER_SPREADSHEET_ID:名簿スプレッドシートのID
- MEMBER_SHEET_NAME:名簿スプレッドシートのシート名
- DRIVE_FILE_ID:リッチメニュー画像のファイルID
- リッチメニュースプレッドシートにシート名「ログ」を追加する
- GASに以下のライブラリを追加する
- Moment
- Parser
- GASに以下のトリガーに設定する
getForecastFromUrlToSpreadsheet:10日間天気予報をスクレイピングして天気予報スプレッドシートを更新する(七尾市和倉町の10日間天気予報を対象にスクレイピングするので、変えたい場合はgetUrlにセットするURLを変更する)- updateRichMenuAll:リッチメニューの応答文を更新する
- 日程調整スプレッドシートのonChange()にupdateRichMenuAll()を設定する
- リッチメニューの画面を作成する
- リッチメニューを登録する
※もっと良い方法があれば、教えていただけると助かります。
おわりに
今回、応答文のキャッシュをスプレッドシートに持たせたが、リッチメニューの応答は、タップ後3秒ぐらいかかっている。とても遅く感じるので、Jsonに持たせるとか他の方法にした方がよさそうだ。ただし、スプレッドシートは分かりやすくてとても勉強になったので、趣味のレベルで今後も活用したい。
リンク
使用ツールサイト
- photocombine.net さん
参考サイト
- タカハシさん
- luthさん
- @baby-degu さん(原著Atit さん)