firebaseで購読中マンガの新刊チェックCRON作った
create: 2019-12-20
JavaScript firebase cron

マンガって、いつの間にか新刊が出てますよね。
毎回 Kindle で買ってるんだから、 Amazon もリコメンドしてくれればいいのに。
お気に入り著者の新刊メールに登録していても、なんか欲しい情報じゃなく、微妙な感じだし。

発売中に遅れてお知らせじゃなく、発売前に知りたいんだよ!

それ、firebase にやらせよう

月半ば、月末に新刊情報を取得して slack 通知するやつを作りたい。
仕様は下記の通り。

  • 月半ば、月末に cron 実行
  • 楽天ブックスの新刊マンガ API から最新版を取得
  • 全部だと情報過多なので、自分の購読しているマンガ・著者のみ抽出
  • レポートは slack に投稿

これなら firebase の機能だけでイケそうじゃない?

ってことで作ってみました。

※このあと掲載しているサンプルコードは抜粋なのでこのままでは動作しません

月半ば、月末に cron 実行

firebase では cron実行 が可能です。
関数のスケジュール設定によると、課金は Google アカウントごとに3つまで無料。
プロジェクトごとに3つ、ではないので注意。
超過分は $0.10/個 です。

たくさんのジョブも1時間毎のスケジュールにして、中で切り分ければ1つとして登録できそうですね。

月半ば、月末はざっくりで 14 日と 28 日の 19 時に設定しました。
これなら 14,28 of month 19:00 に設定すれば OK です。
月末判定処理とか面倒じゃろ?
タイムゾーンはデフォルトだと GMT で9時間遅れるので、忘れずに設定しましょう。

const functions = require('firebase-functions')
const checkManga = require('./check-manga')
functions.pubsub
  .schedule('14,28 of month 19:00')
  .timeZone('Asia/Tokyo')
  .onRun(checkManga)

楽天ブックスの新刊マンガ API から最新版を取得

非公式ではありますが、楽天ブックスでは最新刊の一覧を API で提供してくれています。
http://books.rakuten.co.jp/event/book/comic/calendar/js/booklist.jsonGET でリクエストするだけです。

楽天のマンガ新刊 API で JSON のパース問題」で別記事にしましたが、レスポンスの JSON にちょっとした罠があります。

// check-manga.js
const rp = require('request-promise')
const { post, error } = require('../common/push-slack')
const handler = require('./rakuten-handler')
const { filterItems } = require('./book-filter')

const options = {
  transform: function(body) {
    // 1文字目に謎文字があるので削除してからパース
    return JSON.parse(body.substr(1))
  }
}

exports.checkManga = async function() {
  try {
    let url =
      'http://books.rakuten.co.jp/event/book/comic/calendar/js/booklist.json'

    const json = await rp.get(url, options)
    const newList = handler(json)

    // 購読中一覧をフィルタする
    return filterItems(newList)
  } catch (e) {
    error({ text: JSON.stringify(e) })
    throw e
  }
}

全部だと情報過多なので、自分の購読しているマンガ・著者のみ抽出

例えば本日取得の最新版は、2020 年 1 月発売の情報です。
これだけでも 700 件オーバーなので、自分の購読しているマンガのみを抽出します。
なんだかよくわからない情報もいっぱいなので、発売日タイトル著者名出版社EISBN くらいに整理してリスト化します。
他にもいろいろあるので、必要なら追加すると良いですね。

JSON のcolumnに列タイトルが列挙されているので、必要な列番号を取り出して取得します。

// rakuten-handler.js
// 楽天APIからコミック情報リストを取得する
exports = function handler({ column, list }) {
  const newList = []
  // 列名リストから必要な情報の列番号を取り出す
  const columns = ['eisbn', 'ttl', 'athr', 'ahid_id', 'fc1_id'].map((c) =>
    column.indexOf(c)
  )

  for (const item of list) {
    // オブジェクトに整形する
    const newItem = {}
    columns.forEach((c) => {
      newItem[column[c]] = item[c]
    })

    // { eisbn: 9784065175583, ttl: 'ウィッチクラフトワークス(14)', athr: '水薙竜', ahid_id: 'アフタヌーンKC', fc1_id: '11月7日' },
    newList.push(newItem)
  }

  return newList
}

フィルタ処理は載せていません。著者・タイトルリストに部分一致するものを抜き出すロジックを作ればよいです。

レポートは slack に投稿

整形した情報はslackにポストするだけです。
#generalチャンネルにぶん投げるようにしました。

新刊リスト

趣味丸出しのリストですね。

著者情報で検索しているのでスピンオフ作品も混ざってますが、趣旨とズレてるわけではないのでそれはそれで。
これで月半ばに買い漏れ、月末に翌月の最新巻がチェックできるようになりました!

よつばと! はまだ~?

おまけ:リストは全コミック情報ではないらしい

チェックしているマンガが引っかからなかったのでバグか?と思って調べていたら、全部のコミックがリスト化されているわけではないようです。
2019 年 12 月発売の[武田すん]グレイプニル(7)[沙村広明]波よ聞いてくれ(7)も、リストに入っていませんでした。
グレイプニルは、ネット上の新刊リストでも入ってたり入っていなかったり。

網羅性の高いAPIを探すか、出版社ごとにスクレイピングするか。
期待する動作にはまだ遠い。。。