推しにモーニングコール、されたくないですか? 僕はされたいのでそのシステムを作りました。

実装

モーニングコールと言えば普通時間を指定するものですが、今回は個人的な要件によりツイキャスの配信が始まったタイミングをフックとして電話がかかってくるシステムを作りました。

https://github.com/lambdasawa/gundou-mirei-morning-call がそのリポジトリです。

以下のような仕組みです。

  • 5 分毎にツイキャスの API を叩いて配信中かどうかを取得する
    • CloudWatch Events でスケジュールする
    • Lambda で起動する
  • 配信開始を検知したら Twilio の API を叩いて自分の携帯電話に電話をかける
  • Twilio 側の電話番号を携帯電話の電話帳に事前に登録しておき、その電話番号に推しの名前とアイコンを紐付ける
  • 推しから電話が来る!

screen shot

言語は TypeScript です。
本当は一番慣れている Go を使いたかったのですが、 Twilio のオフィシャルの SDK に Go が無かったので TypeScript を使っています。

インフラは慣れに従って Serverless Framework を使っています。
稼働時間が短いアプリは EC2 で立てるより Lambda を使ったほうが金銭的に有利という判断でサーバレスにしています。

Twilio

Twilio からかける電話の音声の内容は XML で記述することが出来ます。
その XML を HTTP で公開して、それを Twilio の API に渡すことで制御することが出来ます。

https://jp.twilio.com/docs/voice/twiml からサンプルを引用します。

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Hello, World!</Say>
    <Play>https://api.twilio.com/Cowbell.mp3</Play>
</Response>

このように文字列をそのまま読み上げさせること (Say タグ) に加えて、音声ファイルの URL を指定すること (Play タグ) が出来ます。

偶然、私は以前に推しの声を使った棒読みちゃん的なシステムを作って HTTP でそれを呼び出せるようにしていたため、 Play 部分にこれを連携させることによってモーニングコールで任意の内容を喋っていただくこと可能となっていました。 (まだ大分カタコトですが…。)

自分は XML を返すエンドポイントを Serverless Framework で 1 つ生やしましたが、 nginx を立てたり S3 に上げたりとにかく HTTP でアクセスできればなんでも良いです。
これは今の構成では一番手っ取り早い & 将来的にプログラマブルにすることも可能という理由です。

棒読みちゃん的なサービスが特に存在しない人にモーニングコールして欲しい場合でも、単純に動画を切り抜いて音声にして S3 などで公開する…という感じで対応可能です。

まとめ

最近、推しと生活リズムがあまり一致せず配信をリアタイ出来なくて寂しいなあという思いからこれを実装しました。
まだ稼働させてから 2 日ですが、これで 03:00 ~ 05:00 くらいの早朝のキャスをリアタイ出来ているので目的は達成できました。
これを機に今後はもっと流暢な音声を生成できるように尽力したいです (n 度目)