Clova審査一発通過のための注意点

2018年8月7日に「Clovaスキルストア」がオープンしました。
http://clova-blog.line.me/ja/archives/10982355.html

それに伴い誰でもClovaスキルを作成して公開することができるようになりました。
しかし、スキルを公開するためには審査が必要です。

いくつか注意点があるのでまとめてみました。
これを参考にしてスキル担当者の負担を減らし、皆さん一発通過を目指しましょう

まずは[デザインガイドライン](https://clova-developers.line.me/guide/#/Design/Design_Guideline_For_Extension.md#extension%E3%81%AE%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%82%AC%E3%82%A4%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3)を確認することをおすすめします。

# 注意点1：スキル名と呼び出し名（メイン）は一致させる
スキルの基本情報入力画面でスキル名や呼び出し名の設定があります。
スキル名は文字通りスキルの名前です。呼び出し名は「ねぇClova」と言った後に反応する言葉です。

呼び出し名には**メイン**と**サブ**の2種類あります。メインはスキル名と一致させましょう。
サブは他の言い回しを登録することができますが、全然関係の無い言葉は登録することができません。


弊社では[BMI測定スキル](https://clova-skill-store.line.me/appbridge?target=extensionDetail&extensionId=jp.co.ienter.bmi)を作成しました。
BMIという言葉はClovaで言ったところ小文字の**bmi**と認識されてしまいました。
なので、サブには小文字のbmiを登録して回避しました。

この機能はGoogle HomeやAlexaには無い機能なので嬉しいですね。

![s100.png](https://qiita-image-store.s3.amazonaws.com/0/154355/35e6918a-5194-22b5-8897-41f186bbe587.png)

# 注意点2：単語1語または汎用的な言葉でないこと
スキル名と呼び出し名（メイン）には単語1語だけや汎用的な言葉を使うことはできません。
弊社場合だとスキル名「BMI」だけだと単語1語だけなのでリジェクトされてしまいます。
「BMI測定」とすることで汎用的な言葉ではなくなり、リジェクトを回避できました。

GoogleアシスタントやAlexaでもスキルを公開した時に、
このガイドラインの影響でスキル名が一致しなくなるという事が考えられるので注意しましょう。

私は個人でリリースしたスキルが影響受けました。。。
Googleアシスタントは「運命数」でリリース
Clovaだと「ソウルナンバー占い」としました。

![s104.png](https://qiita-image-store.s3.amazonaws.com/0/154355/f10d8814-afb8-1482-5d24-d64dd08f33ba.png)



# 注意点3：審査担当者へのコメントはわかりやすく
審査員は人力で審査を行っています。なので、スキルの実行方法はわかりやすく記述しましょう。
私は、発話に反応するIntent名を列挙しています。どういう言葉でどういうIntentが反応するかを書きました。

![s101.png](https://qiita-image-store.s3.amazonaws.com/0/154355/8384f77a-862f-231c-0ba7-a013494451a4.png)

# 注意点4：利用者に見せるための説明文もわかりやすく記述する
ここに記述するのはスキル利用者が目にする部分なので、説明文はくどくなく、わかりやすく記述するように心がけましょう。
ヘルスケア系は「医学的な助言を行わない」や占い系も「参考程度に留めておきましょう」という感じで責任を負わないようなニュアンスで書きます。

![s102.png](https://qiita-image-store.s3.amazonaws.com/0/154355/579e6ea3-8703-c28a-06fb-993c6c14d287.png)

# 注意点5：代表サンプル発話の1つ目は必ず「ねぇClova」をつける
昔の画面ではそのような説明が無く、この付け忘れで何度もリジェクトされました。
最近画面が変わってわかりやすくなりました。
代表サンプル発話の１つ目には必ず「ねぇClova」とつけないと審査が通りません。そして、その後に続く言葉は、基本情報で設定した呼び出し名（メイン）と一致させる必要があります。

![s103.png](https://qiita-image-store.s3.amazonaws.com/0/154355/c3fdfbc9-26a6-a1a9-c566-2c74c371b0cd.png)

サポートされている実行フレーズです。

「ねぇClova、＜呼び出し名（メイン）＞を起動して」
「ねぇClova、＜呼び出し名（メイン）＞を開いて」
「ねぇClova、＜呼び出し名（メイン）＞に繋いで」

# 注意点6：セッション情報が残ったままになっている
スキルはセッションが切れるまで、セッション情報が保持されています。
スキルを起動して終了しても情報が残ったままになっているため注意が必要です。

shouldEndSessionがtrueならスキルが終了する。falseならスキルを継続する設定があるのですが、
プログラムの書き方でグローバル変数にshouldEndSessionのフラグを持たせてしまっている場合は気をつけないといけません。

以下はダメな例です。一度スキルを起動してから直ぐにスキルを終了させ、もう一度スキルを起動すると、「こんにちはClova！」と言ってから直ぐにスキルが終了してしまいます。
この原因はセッションが残ったままになっており、shouldEndSessionのendFlgがtrue状態になったままになっており、スキルが終了してしまう原因でした。

```javascript:index.js（ダメな例）
// どこでも見えるように定義した場合
var endFlg = false;

exports.handler = function (event, context, callback) {

    var requestJson = JSON.parse(event.body).request;
    
    if (requestJson.type === 'LaunchRequest') {
        // 起動時処理
        speechText = 'こんにちはClova！';

        responseAction(callback);

    } else if (requestJson.type === 'SessionEndedRequest') {
        // セッション切れ
        speechText = 'ご利用ありがとうございました。';

        // ここでtrueにした情報がセッションが残ったままになってしまう。
        endFlg = true;

        responseAction(callback);
    }    
};

// セッション結果を返す処理
function responseAction (callback) {
    var responseJson = JSON.stringify({
        "version": "1.0",
        "response": {
            "outputSpeech": {
                "type": "SimpleSpeech",
                "values": {
                    "type":"PlainText",
                    "lang":"ja",
                    "value": speechText
                }
            },
            "card": {},
            "directives": [],
            "shouldEndSession": endFlg
        }
    });
    
    response.body = responseJson;

    callback(null, response);
}
```

良い例はLaunchRequest時に正しくendFlgを初期化してあげることが必要です。


```javascript:index.js（良い例抜粋）
// どこでも見えるように定義した場合
var endFlg = false;

exports.handler = function (event, context, callback) {

    var requestJson = JSON.parse(event.body).request;
    
    if (requestJson.type === 'LaunchRequest') {
        // 起動時処理
        speechText = 'こんにちはClova！';

        // フラグ初期化する
        endFlg = false;

        responseAction(callback);

    } else if (requestJson.type === 'SessionEndedRequest') {
        // セッション切れ
        speechText = 'ご利用ありがとうございました。';

        endFlg = true;
        responseAction(callback);
    }    
};
```
これはプログラマーの問題でもありますが、見落としがちな例です。
実装には十分気をつけるのと、テストはしっかり行いましょう！

# まとめ
要点を抑えれば、一発で審査を通すことも可能です。
人力で行っているので担当者の負担を少しでも減らしましょう！

これで大手3種類のスマートスピーカースキルが出揃いました。
現在Clovaはスキルの申請が通ればTシャツキャンペーンを行っているので、スキルを作ってTシャツゲットしましょう！

システム化のご検討やご相談は弊社までお問い合わせください。
https://i-enter.co.jp/contact/