3行でまとめる
- scarper で貸出資料一覧を取得
- Google Calendar API で資料ごとに登録・更新・削除
- AWS Lambda + Cloud Watch で定期実行
貸出資料一覧を取得
Rust で。
- reqwest で図書館サイトへログインする
- 貸出資料一覧のページに遷移し、得た HTML を scraper に食わせる
LibraryItem
構造体に詰めてVec<LibraryItem>
で返す
#[derive(Debug)] struct LibraryItem { title: String, due_date: chrono::naive::NaiveDate, }
参考:
Google Calendar API を Rust からいじる
準備
- GCP で Service Account を作る
- サービス アカウント | IAM のドキュメント | Google Cloud
- 認証情報をダウンロードしておく
- 自分のアカウントから Service Account にカレンダーを共有する(読み書き権限つき)
プログラム
- JWT(Json Web Token) を使って、カレンダー API を叩くためのアクセストークンを取得する
- jsonwebtoken crate が便利
- アクセストークンを使ってカレンダー API を叩く
- API Reference | Calendar API | Google Developers
- たとえばイベント一覧なら GET リクエスト:
let events = reqwest::blocking::Client::new() .get(CALENDAR_API_ROOT.to_string() + "events") .bearer_auth(access_token) .send() .unwrap();
- 全イベントを CalendarItem 構造体につめて
Vec<CalendarItem>
で返す
#[derive(Debug)] struct CalendarItem { summary: String, start: chrono::naive::NaiveDate, id: String, }
参考:
情報反映処理
上の2節の Vec を集めて、
let library_items = get_books_list_from_library(); let calendar_items = get_items_list_from_calendar(&access_token);
各アイテムがこの2つに所属するしかたによってやることを分岐する。
- library_items になくて、 calendar_items にある ⇒ 返却した資料。 当該 calendar_item の id を使って、削除 API を叩く
- library_items にあって、 calendar_items にない ⇒ 新しく借りた資料。 登録 API を叩く
- library_items, calendar_items の両方にある ⇒ 持っている資料。 返却期日が同じならば何もしない。異なるならば、貸出延長が行われているため更新 API を叩く。
定期実行
まずプログラムを AWS Lambda に対応させる。
- aws-lambda-rust-runtime crate を追加し、 main 関数の interface を合わせる
x86_64-unknown-linux-musl
向けにクロスビルドする- musl 向けのリンカがなくて失敗したりした
- musl 向けビルド環境の Docker イメージがあるみたいなので使うと楽かもしれない
- reqwest で、 OpenSSL ではなく rustls を使うように設定しないといけないはず
- musl 向けのリンカがなくて失敗したりした
AWS Lambda に載せる。
- Amazon Linux 2 カスタムランタイムの関数を立ち上げる
- 手元で
cargo build --release
したバイナリをbootstrap
とリネームし、他に必要なファイルを同梱した zip を作る - zip を AWS Lambda コンソールからアップロードする
- 必要に応じてタイムアウト時間を長くする
- 試しにトリガしてみる
定期実行させる。
- CloudWatch Events トリガを設定する
- 10 分毎など
窓口で延長処理をすると自動で Google カレンダーに反映される。便利。
参考: