himanago

Azure・C#などのMS系技術やLINE関連技術など、好きな技術について書くブログ

CEK裏技「無音無限ループ」スキルをストア公開するためには?

はじめに

前回こんな記事を書きました。 himanago.hatenablog.com

今回はその続編として、裏技である「無音無限ループ」を使用した腹話術スキルをストア公開した際の話を書きます。

特に無音無限ループは使い方によっては非常に危険なので、安全性が要求されるストア公開では細心の注意が必要です。
そんな話を下記「第4回ボット自慢/苦労自慢 LT 大会」でも話したので、そのときのスライドを交えつつ、その後の改善についても併せてまとめます。

linedevelopercommunity.connpass.com

公開したスキル

「テキスト腹話術」という、LINE Bot経由で好きなことをClovaにしゃべらせるスキルです。
clova.line.me

アーキテクチャ等は前回記事を見てください。

Azure Functionsなどで構築しています。
そして肝になるのがCEK裏技の「無音無限ループ」(勝手に命名)です。

無音無限ループとは

f:id:himanago:20190728014222p:plain

CEKの AudioPlayer 機能で無音mp3の再生をさせ、その再生終了時の AudioPlayer.PlayFinished イベントで再度無音mp3を再生させることで無限ループを作り、スキルを終了せず無限のセッションを得る裏技です。

f:id:himanago:20190728014726p:plain

テキスト腹話術スキルでは、「LINEからのメッセージ送信」で無限ループをbreakし、その内容をしゃべるよう実装しています(ここでDurable Functionsを組み合わせています。詳細は前回記事)。

ストア公開のきっかけ

もともとこのスキルはDurable Functionsを活かしたサンプル(というかネタスキル)として開発したものだったので、一般公開を目指してデザインされたものではありませんでした。

実は以前、Clova Skill Awards を狙って新しいスキルを開発していたのですが、作っていたものとほぼ同じギミックのスキルが先に公開されてしまいました。

後発ではパクリになってしまうため(特にアワード期間中は)出すことができなくなり、アワードに応募するために秘蔵の腹話術スキルを公開に向けて再構築することにしました(今回のアワードはストア公開が前提)。

アワードは無事入賞できてよかったのですが、ギミックがかぶったスキルが最優秀賞(!)だったので、やっぱりちょっと悔しかったですね…。

という感じで急遽のストア公開でしたが、裏技を使っているスキルということでいくつかのハードルがありました。

無音無限ループの危険性

そもそも無音無限ループ自体が、使い方次第で非常に危険だということが挙げられます。

f:id:himanago:20190728015639p:plain

無音無限ループは、短い無音mp3を繰り返し再生させることで無限のセッションを得る裏技ですが、それが動作している間はClovaへの音声指示が効かなくなります。

例えば1秒のmp3をループ再生している場合、1秒間隔でClovaは新しい処理を行うことになるので、ユーザーの音声を聞き取る余裕がありません。

テキスト腹話術の場合、LINE Botのリッチメニューにより終了操作が行えますが、手元にLINEがない場合(特に連携アカウントの持ち主が外出中でほかの人がスキル起動した場合など)やそもそもBotを友だち追加していない場合、詰みます。

こうなると、デバイスを再起動するしか止める方法がないのです…。

ストア申請した結果

アワード狙いのストア申請とはいえ、無音無限ループの手法自体は「これを世に出さないのはもったいない!」と思っていたので、申請時のコメントで「裏技っぽいけどスキルの幅が広がる思うのでどうか通して…!」的なことを書いて泣きつきながら申請しました。

…いま思うとちょっと恥ずかしいですが。

で、さすがに一発通過とはならずリジェクトされました。

細かい指摘はいくつかありましたが、大きかったのは以下2点。

友だち追加していない場合には先に進めないようにしてほしい

友だち追加していない状態だと、スキル使えないですからね。

これは当然。

ちなみに、Botとの連携が必須のスキルの場合は必ずチェックされるポイントのようで、 説明文への明記も必須みたいです。

また、Botのアカウント名もスキルと同じ名前にするなど、わかりやすくすることが求められます。
※アカウント名の変更には制限(1度変えると7日間変更できなくなる!)があるので要注意

ちなみに友だち追加してるかどうかのチェックは(急いでたし)こんなふうに「プロフィール取得に失敗したら友だち追加していないとみなす 」って感じで実装したんですが、これでよかったんだろうか…

// 友だち追加チェック
try
{
    await messagingClient.GetUserProfileAsync(userId);
}
catch
{
    cekResponse.AddText("連携するLINEアカウントが友だち追加されていません。" +
        "Clovaアプリの本スキルのページから、連携するLINEアカウントを友だち追加してください。");
    break;
}

音声でスキルを終了できるようにすることは必須

まぁ、やはりそうですよね。友だち追加しててもBot操作ができないケースでは変わらず詰みますからね。

やはり音声によるコントロールを行えるようにすることはマストなようでした。

無音無限ループ中の挙動を検証

音声で終了操作をするために、無音無限ループの動作を検証してみました。

すると、いくつかの事実が判明しました。

無音無限ループ中、

  • shouldEndSessionをfalseにした状態で
  • Clovaに何らかの発話をさせると
  • その後の一定時間(無音mp3再生終了まで)は

Clovaがウェイクワードなしで指示を聞き取る状態になっていたのです。

これまで無音mp3を1秒にしていた(+ウェイクワード認識時の効果音をオフにしていた)ため気づかなかったのですが、mp3の長さを長めにしたら、腹話術による発話後にClovaが指示待ち状態になることに気づきました。

といっても、shouldEndSession = falseでしゃべらせてるんですから当たり前ですね。
これは普通のスキルにおいて、Clovaの発話後にユーザーの返答待ちにするやりかたです。

なので、「止めて」をインテントで登録しておけばスキルが終了することがわかりました。

また、mp3再生中、ウェイクワード「ねぇClova」で指示を聞いてくれることも判明。

これもmp3を長めにしたら気づいたことですが、よくよく考えてみれば、これはAudioPlayerの機能として当然の動きで、音楽再生のスキルを作った場合、「止めて」とか「次」とか言えるようにするのが普通ですよね。

ということで、音声でスキルを終了させる隙が2か所存在したのです。

f:id:himanago:20190728023335p:plain

無音無限ループ “安全版”の誕生 ⇒ 無事公開!

こうして、音声でコントロールできることがわかりました。

公開用に、無音mp3の長さを「5秒」にしました。

これは反応速度の許容範囲と音声指示に必要な長さのぎりぎりの妥協点です。これより短いと音声コントロールの失敗率が高くなり、長いと腹話術の反応速度が非常に鈍く感じるようになります(5秒でもサーバー側のタイミング次第で10秒ほど待つこともありますが)。

なんとか公開までたどり着くことができました。

細かい点含め、申請とリジェクトを何往復もしてようやく公開になりました。

最後まで対応いただいたストアの審査担当のみなさんには本当に感謝です。ありがとうございました。

その後のアップデート

先日アップデートを行い、shouldEndSession = falseでしゃべらせて「止めて」待ちにするのはやめました。

理由としては、スタンバイ効果音をオンにしていると、Clovaがしゃべるたびにポンという音が出て腹話術中にかなり邪魔になるのと、Clovaへの指示ではない会話も聞き取ってしまい、誤動作の原因になってしまうからです。
利用例で挙げている「ごっこ遊び」とかでは致命的。

また、対象デバイスからXperia Ear Duoを外しました。
こちらはストアの担当の方から正常動作しないという報告を受けたためです。

AudioPlayer利用のスキルに対応したとのことだったのでいけると思っていたのですが、実機を持っていないので検証できず泣く泣く対象外ということで…。

LT資料

スライドはこちらに置いてあります。

www.slideshare.net