数式を変換してくれるTwitter Botを作りました
こんにちは。このような技術記事を書くのが初めてなので拙い部分もあるかと思いますが最後まで読んでいただけると嬉しいです。
早速ですが、題名の通りリプライ中に含まれる数式を画像に変換して返すTwitter Botを作ったので、(宣伝がてら)使った技術なんかを書いていこうと思います。
概要
こんな感じで
このBotを開発しようと思ったきっかけは数学の議論の際に文字だけだと見にくくて理解にとても時間がかかるといったツイートを見かけたからで、開発中もTwitter上で数学の話をするという使い方を想定していたのですが、それ以外の使い方も大歓迎です。(実際記事に数式の画像を貼るために使うという方がいらっしゃいました。)
特徴
すぐに使える
@FormulaConvertをフォローし、リプライを送るだけで使うことができます。特別な利用申請や別にアカウント登録する必要がなく、Twitterアカウントを持っている方であれば誰でもすぐに使うことができます。
数式の自由度が高い
1ツイートに収まり、追加のパッケージが必要ない数式であればどんな数式でも表すことができます。
実際にこんな感じでナビエ・ストークス方程式も変換することができます。
使用した技術
言語
- Java
ライブラリ
- Twitter4J
- Jackson
- SQLite-JDBC
サーバー
- OCI ARM A1インスタンス
データベース
- SQLite3
その他
- Docker
- paperist/texlive-ja
言語にはJavaを採用しました。理由は一番慣れているからぐらいで深い理由はありません。
ライブラリは以上の通りですが、Twitter4Jについては後述します。JacksonはネストされたJSONも解析してパースしてくれるため採用しました。Gsonは最初にJSONの構造を指定する必要があるのですが、長いものは指定が面倒なのでやめました。データベースは履歴を保存するだけなので、一番簡単なSQLiteを使い、Javaから操作するためにSQLite-JDBCを採用しました。
サーバーにはOCI ARM A1インスタンスを採用しました。これについて記事を書きたいぐらい推しているVPSなのですが、簡潔に言うと無料で使えるかなり性能の高いVPSです。実際に複数のWebアプリやBotを動かしていますが、余裕をもって動作しています。(利用者が少ないからというのもありますが・・・)
また、詳しい流れは後述しますが、数式のコンパイルはDocker上のupLaTeXで行なっています。TeXLiveは環境構築がかなり面倒なので、Dockerを使うことで環境構築の手間を省きました。
Twitter API
Twitter APIを使うためには申請が必要なのですが、チェックボックスを付けていくだけと目的などを英語で書く必要があった以前に比べて非常に楽になっていました。しかしこれが罠(?)で、通知などをWebhookで受け取るためのAccount Activity APIを使うにはこの申請に加えてPremiumへの申請も必要でした。申請してすぐに使えるようになると思っていたので、Account Activity APIを使うために必要な設定を行うタブがなくて2時間ぐらい探してました。
そしてこのWebhookを受け取るためにJavaの標準ライブラリのHTTP Serverを使いました。初めてHTTP Serverを使ったのですが、Webhookの受け取りなどちょっとしたWebサーバーを建てるのには非常に便利でした。ただし、Challenge-Response Checksのために正しいレスポンスをする必要があり、そのためにクエリストリングを受け取る必要があるのですが、ただの文字列としてしか受け取れないため、クエリストリングぐらいはMapで受け取れるようになったらもっと便利なのにな・・・とは思いました。
また、ライブラリにTwitter4Jを採用した理由ですが、PremiumにアップグレードすることによってTwitter API v1.1も使えるようになりました。今後はv2がメインになっていくようなのでv2を使ってもいいのですが、現状v2対応のライブラリがいくつかあり、とりあえずこれを使っておけばいいみたいなライブラリがなかったのと、v2に関する記事が調べた限りではあまりなかったので、今回はとりあえずTwitter4Jでv1.1を使うことにしました。もしv2に対応したJava用のライブラリでおすすめのものがあれば教えていただきたいです。
画像の生成について
画像の生成は以下のような流れになっています。
特にtexlive-extra-utilsパッケージに含まれるpdfcropコマンドは非常に便利なコマンドで、自動で文字(正確にはバウンディングボックス情報)を認識して切り抜いてくれるコマンドです。ページ番号なしでPDFを生成することによって、コマンド一つで数式のみを切り抜くことができました。
感想
数式の生成は意外とすぐに実装できたのですが、Account Activity APIの申請やHTTPサーバーの実装に時間がかかったりとTwitter API周りの実装に時間がかかってしまいました。しかし公開してから1週間程度ですがフォロワーも100人を超え、結構利用してくださる方も多くとても嬉しいです。今後機能を追加するかは未定ですがもしよろしければフォローしてくださると幸いです。
Discussion