phantasm

まったり趣味を満喫するブログ。気になったことを記録していく予定。

開園時刻を教えてくれるbot

自宅待機期間、何か作ってないと腕がなまりそうだったので、つくりました。

github.com

概要

日付とパークを指定すると、こんな感じで運営情報を返してくれます。

f:id:frozenheart084:20200508141945p:plain

会話サンプル

一応今のところ非公開の予定ですが、需要があれば公開するかもしれません。

使い方

「日付」と「パーク種別」を入力して送信してください。

日付

以下の2パターンの入力に対応しています

(年指定には対応していません)

  • 1/11
  • 1月11日

あと直近の日付を示すキーワードとして、

  • 明日 / あした
  • 明後日 / あさって

にも対応しています。

指定がなければその日の情報を返します。

パーク種別

  • ランド / 陸 / land
  • シー / 海 / sea

に対応しています。指定がなければ陸の情報を返します。

構成

全体構成

java+spring boot+gradleで実装しました。

Herokuにデプロイして、それをLINE公式アカウントのweb hookに設定する形で反応させています

実装等はこの辺を参考にしましたが、ちょっとわかりにくいかもしれない・・・?

https://developers.line.biz/ja/docs/messaging-api/building-sample-bot-with-heroku/ 

データについて

ソース見てもらったほうが早いんですが、json形式のファイルを用意して、そこから指定された日付の情報を引いてくるような作りになっています。

データ作成は別でやる必要がありますが、毎回ほかのサイトから引っ張ってくるのは負荷等を考えると避けたほうがいいかなと思ったので、今の作りになっています。

これくらいのデータ量と内容ならjsonで十分だと考えたので、DBも立てていません。

気軽にまねできるんじゃないかなと思います。

 大変だったこと

構築

HerokuのURLに「LINE」が含まれるとリジェクトされる

LINE公式アカウントを作ったら、webhookのURL(今回で言うとHerokuでデプロイしたURL)を登録するのですが、
そのWebhook URLに「LINE」が含まれてるとダメだそうです…

これ本当にわからなくて半日近くハマってました。気づいた時の悲しさが尋常じゃない。

というかエラーメッセージもう少し親切でもいいと思うんですよ。「URLに使用できない文字列があります」とか。接続エラーっぽいメッセージにするのやめてほしい。

実装

LINEのテキスト解析がすごく大変だった

今回の場合、ユーザーの自由入力になるので、すごく難しかったです。

(普段実装するのはバッチが多いので、入力は固定文字列になることが多い)

結局、日付は正規表現で、パーク種別は固定の文字列が含まれていることで、それぞれ判断するようにしました。

ただ、こちらの都合に合わせた形の入力をお願いしなければならないので、本当はもっといろいろなバリエーションに対応したかったです・・・・

jarに含まれる設定ファイルがうまく読み込めなかった

ローカルで動かしたときは全然取得に問題はなかったのですが、いざHerokuにデプロイして動かしてみると、設定ファイルを読み込むタイミングで以下のエラーが出るように…

class path resource [ファイルパス.json] cannot be resolved to absolute file path because it does not reside in the file system:

結局何だったのかというと、実装の問題でした。

jarに含まれるファイルは、ファイルとして操作するとうまくいかないので、streamで扱う必要があったとのことでした。

つまりFiles.readAllLines使ってたのが原因でした。

InputStreamにしてあげればそれでよかったので、一度stream化してからbyte→String変換を自力で行う形で実装しました。

今後について

一応これの開発はいったん終わりにするつもりです。

手が空くか暇になったときにでも、改善は進めていけたらいいなと思います。

設定ファイルは定期的に差し替えないといけないね。

 

Herokuの扱い方もわかったし、今度はパークフードガチャでも作ってみようかなと思いました。需要あるかはわからないけど。

久しぶりにコードかけたのでよかったです。

腕が鈍らない程度に新しいものを作ってみようと思います。