himanago

C#とかAzureとかMS系の技術メモ中心に書きたいです

LINE BOOT AWARDS 2018にエントリーしてみました&その話を.NET Conf 2018 Tokyoでしてきました

はじめに

ここに書くのはだいぶ久しぶりです…
先日、LINE BOOT AWARDS 2018にClovaスキル&LINE Botを開発してエントリーしたので、そのことと、 それについて.NET Conf 2018 TokyoのUnconference枠で話をしてきたので、それについて書いておこうと思います。
(.NET Confでは10分枠だったのでその補足もかねてその時よりも若干詳しく、スライドベースで書いていきます。スライド資料はここ

スマートスピーカー

f:id:himanago:20181021011841p:plain

ちらほら流行り始めている(気がする)スマートスピーカー
エンジニア界隈では使っている人も見ますが、一般家庭への浸透率ってどの程度なものなんでしょう。

LINE BOOT AWARDSへの挑戦

f:id:himanago:20181021011857p:plain

個人的にも気になっていたスマートスピーカー。LINEの「Clova」がプリッツの懸賞で当たりました。
プリッツ5箱分食べると1回応募できるという具合だったので、この懸賞のためにプリッツを食べ続ける覚悟もしていましたが、2回目の応募で当たったのでかなり運がよかったです…!

f:id:himanago:20181021011910p:plain

せっかくスマートスピーカーが入手できたので、それならばスキルの開発をしてみたいと思うのがエンジニアというもの。

f:id:himanago:20181021011918p:plain

ちょうど、LINE BOOT AWARDS 2018という開発コンテストが開催中でした。
グランプリの賞金が1000万円とものすごい額。そこまでは狙えないにしろ、どこまでいけるか、挑戦してみることにしました。

f:id:himanago:20181021011925p:plain

とはいえ、スケジュールはものすごくタイトでした。 Clovaが届いたのが9/23(日)。アワードのエントリーに締め切りが10/10(水)。
これだけでずいぶん短いですが、Clovaが届いたときには、まだ特にアワードに応募することなんて考えてもいませんでした。

応募するきっかけをくれたのが、2つのイベントです。
(スライドには書いていないのですが)ひとつは9/29(土)に実施された、Amazonが出しているスマートスピーカーである「Alexa」のアワードの最終プレゼンを見に行ったこと。
ここで結構刺激を受けてきまして、いつか自分もこういうアワードに挑戦してみたいなぁと思ったわけです。 alexaskillawards.connpass.com

もうひとつが、こちらはスライドに書いていますが10/2(火)に参加したCogbot勉強会。
ちょうどLINE BOOT AWARDSとのコラボ回だったのですが、ふつうにLINE系開発の情報収集目的で参加しました。
しかしそこでアワードの概要やC#での開発についての話、また最後のLTで短期間でもAzureを利用してアワードに挑戦するという話(これが自分にはいちばん響きました)を聞いて、これは自分もアワードに挑戦すべきなのではないか…?と思わされてしまいました。 cogbot.connpass.com

そして、10/4(木)、突然、シャワーを浴びているときに、作るもののアイディアが降ってきました。
(入浴中とかって結構アイディアを思いつくこと多いですよね。なんででしょう)
思いついたらもう最後、3連休を利用して一気に作ってやろうと決意を固めました。

3連休ではアワードのもくもく会への参加をし、また締め切り日には有休を取得して最後の追い込み。実質4日間での開発でした。

どんなものを作ったか

f:id:himanago:20181021011934p:plain 絵本読み聞かせのシステムです。
特徴としては

  • お話を読んでくれると同時にLINEにその絵が送られてくる
  • 登場人物ごとに異なる声/話し方でしゃべってくれる

というものです。

デモ動画を置いておきます。 www.youtube.com

Clovaのオーディオ再生機能とAITalk Web APIを組み合わせ、音声再生を連続して実行し、同時にLINEに画像を送っています。

仕組みなど

そのほか、アーキテクチャまわりはアワード応募時の技術解説として書いた以下の記事に書いています。
締め切り当日に一気に書いたのであんまりまとまってないですが…。 qiita.com

今回開発したのは、スマートスピーカーのスキル(Clovaスキル)と、LINE Botを連携させています。
Clovaの特徴のひとつとしてLINE Botとの連携があり、それぞれの可能性を拡げてくれます。
ClovaスキルとLINE Botの開発は似ています(ここでは触れませんがClovaやLINE以外のVUI/Botもかなり似通った利用フローや開発方法といえると思います)。

ClovaスキルとLINE Botの開発方法・今回の構成

f:id:himanago:20181021011955p:plain Clovaスキルの場合は「CEK」がデバイスと自分の作成したバックエンド(Extensionサーバー)との仲介をしてくれます。
対話の定義はCEK上で行い、ユーザーの発話の解釈などはすべてやってくれます。

f:id:himanago:20181021012011p:plain 対してBotのほうは「Messaging API」が仲介をしてくれるのですが、こちらはPush/Replyといったメッセージ送受信を中継してくれるだけです。
なので、ユーザーから送られたメッセージの解釈などは自分で開発する必要があります(バックエンドでやる)。

f:id:himanago:20181021012019p:plain さきほどの技術解説記事でも説明していますが、今回の構成図はこのようになっています。
Clova/LINE Botの共通のバックエンドとしてAzure Functionsを用いています。
読み上げる絵本の情報(本文、読み手がだれか、感情やスピードなど各種パラメータ)をCosmos DBにMongoDBの形式で格納し、本文にあわせて送られる絵の画像はBlob Storageに格納しています。

Azure Functionsによるバックエンド

f:id:himanago:20181021012026p:plain Functionsは非常に便利なサーバーレスのサービスですが、今回はサーバーレスらしい従量課金プランではなく、App Serviceプランでの稼働です。
通常のWebアプリと同じように常時稼働させる形式をとることで、従量課金プランの弱点である初回起動の遅さを克服しています。
Clovaスキルは特にタイムアウトが天敵なので、この選択は必須といえるかなと思います。

[※2018/11/7追記]
App Serviceプランにするだけではだめで、常時接続をオンにする必要があります。オフだとしばらくするとサービスが止まってしまい関数起動が遅くなってしまいます。
常時接続オンにできるのはS1以上なのでちょっとお高め。

[※2018/11/23追記]
Azure Functions のv2を使って再作成していますが、触った感触、コールドスタート問題、かなり改善されている…?
もしかしたら従量課金プランでもClovaのバックエンドとして問題なく使えるかも…。検証して再度追記します。
IPアドレスの問題があるので今回の要件ではどちらにしろApp Serviceプランにしないとですが

[※2018/11/25追記]
何度か試しましたが、成功率はかなり高くなっているようです(コールドスタートで3/4回成功)。
とはいえタイムアウトすることもまだあるので、そのままでは本番運用にはまだ厳しいような気がします。
Azure Functionsはv2からランタイムが.NET Core になってパフォーマンス改善された結果なんでしょうか。

azure.microsoft.com

[※2018/12/20追記]
Logic Appsを利用してコールドスタートを回避するパターンを思いついたので、Qiitaに書きました。
これでコールドスタートを気にする必要がなくなります。 qiita.com

(追記おわり)

また、今回は絵本を無料/有料2種類のコンテンツがある想定にしており、有料のものはLINE Payで追加購入できるようにしています。
そのため、LINE Payとの連携も行っているのですが、LINE Payは連携するシステムのサーバーのIPアドレスを事前に登録しておく必要があります。
App ServiceプランではIPアドレスが変わらないので、この点でも必須なのでは、と考えました。
(こちらの記事を参考にさせていただきました) poke-dev.hatenablog.com

Azure Functionsのリモートデバッグタイムアウトになったり迷子になったりするのでなかなか使えず、コンソール出力を使ってのデバッグがメインでした。はじめはつらかったものの、慣れればどうにかなるものでした。

BlobストレージとLINE Botの画像送信

f:id:himanago:20181021012037p:plain このスライドに書いてある通り、Blob StorageとLINE Botの画像送信は相性がいいです。
通常の画像メッセージでも今回使ったイメージマップメッセージでも、画像はバイナリデータではなくURLの指定で行います。
Blob Storageは上げたデータをURLでアクセスさせることができるので、そのまま利用できるという寸法です。

f:id:himanago:20181021012049p:plain さきほども少し触れましたが、今回は通常の画像メッセージではなく「イメージマップ」を使っています。
もともとは画像に対してタップした際のアクションを定義するLINE Botの機能ですが、トーク画面に対してめいっぱいの幅を使って画像を表示させることができるため、今回の絵本の絵の送信に適しています。もくもく会にてアドバイスいただいたのですが、これによって非常に絵本が読みやすくなりました。

このイメージマップですが、デバイス幅にあわせた画像が表示される機能で、利用するには複数の幅の画像を事前に用意しておく必要があります。
Messaging APIリファレンスからの引用ですが、

イメージマップに使える画像の仕様は以下のとおりです。

画像フォーマット:JPEGまたはPNG 画像の幅:240px、300px、460px、700px、および1040px データサイズ:最大1MB 5つの異なるサイズの画像を「baseUrl/{画像の幅サイズ}」の形式でアクセスできるようにします。これにより、デバイスに応じて望ましい解像度でLINEに画像がダウンロードされます。

たとえば、ベースURLが以下の場合を考えます。

https://example.com/images/cats

幅が700pxの画像のURLは以下になります。

https://example.com/images/cats/700

となっており、Blob Storageへの格納は、スライドに書いた通り、これに沿うようにする必要があります。
(ファイル名を拡張子を外した画像の幅サイズの数字にしてディレクトリ構成を工夫するだけ)

C#出のLINE開発について

f:id:himanago:20181021012059p:plain

Cogbot勉強会でもC#には厳しい、という話が…。
完全に個人的な意見ですが、Clovaも(AWSとセットの)Alexaに対抗するなら、Azureを味方につけやすいC#との親和性を高めてもよいのではないかなぁと思います。
公式のSDKがないとはいえ、C#で開発する場合もコミュニティSDKや周辺ツールがあります。
今回の開発でも、Messaging API、CEK、LINE Pay用のC#SDKを使わせていただきました。

今回使った機能(Clovaのオーディオ関連など)で一部SDKが対応していないものもありそこは自前で実装しましたが、ベースとなるものがあるだけ開発のハードルはかなり下がり、かなりありがたかったです。

おわりに

f:id:himanago:20181021012107p:plain

今回は一気に開発しましたが、やはり目標や締め切りがあったことで、かなり真剣に取り組めました。
.NET Confで話したい、というモチベーションもありました。
締め切り後の連絡にもかかわらずUnconference枠で参加させていただき、.NET Confの管理者の方には大変感謝しています。ありがとうございました。

そしてアワードの途中経過について

そして!
今回開発した「Clova&LINEで絵本読み聞かせ」ですが、なんとFinal Stage進出の連絡をいただきました!
このような評価をいただけて大変うれしく思います。
Finalは11/10(土)に実施とのことで、ここでは展示審査もあるようなので、さらなるブラッシュアップをしていきたいと思います。

これからもがんばります!
以上です。