[小ネタ] ASK CLI でオリジナルの名前で #Alexa スキルをcloneしたい

2018.08.08

Alexa Skills Kitコマンドラインインターフェース(ASK CLI) は非常に便利で、Alexaスキルの開発にはなくてはならないツールです。 特に、Alexa Skills Kit開発者コンソール上にあるスキルを手元の端末にcloneできる機能を非常に多用します。

しかし、現状ではスキル名を日本語にしていると、"_" というディレクトリにcloneされます。 日本語名のスキルが複数ある場合に困ることが多いので、日本語スキル名でディレクトリを作るように改修してみます。

なお、この記事の内容については、簡単な動作確認のみ行なった状態ですので、適用される場合はat your own riskにてお願いいたします。また、次にnpm installした場合には、元に戻ることが予想されます。

環境

以下の環境で確認しました。

  • macOS High Sierra 10.13.6
  • nodebrew 1.0.0
  • ask-cli 1.4.1

修正箇所

nodebrewを使っている私の環境では、ask-cliの実体は$HOME/.nodebrew/current/bin/askにありました。

ask-cliCommander.js を使っているようで、今回修正したいcloneコマンドの実装はlib/clone/clone.js 以下にありました。

肝心のスキル名の取得は、utils/skill-parser.js に処理がありました。

該当箇所は、この utils/skill-parser.js の以下の箇所でした。

/*
 * Get SkillName from manifest
 * Two notes on this function:
 * 1.The name in en-US is prioritized; if no en-US then use the first locale
 * 2.Filter the name by replacing all the invalid character to '-'
 *
 * @params manifest
 * @return skillName
 */
module.exports.parseSkillName = (manifest) => {
    let locales = jsonUtility.getPropertyValueFromObject(manifest,
        ['manifest', 'publishingInformation', 'locales']);
    if (!locales) {
        locales = jsonUtility.getPropertyValueFromObject(manifest,
            ['skillManifest', 'publishingInformation', 'locales']);
    }
    if (!locales) {
        return null;
    }
    let name;
    if (locales.hasOwnProperty('en-US')) {
        name = locales['en-US'].name;
    } else if (locales.hasOwnProperty('en-GB')){
        name = locales['en-GB'].name;
    } else {
        name = locales[Object.keys(locales)[0]].name;
    }
    let result = module.exports.filterSkillName(name);
    if (!result || result.length === 0) {
        console.error('Get skill name error. Skill name should not be empty.');
        return null;
    }
    return result;
};

コメントにばっちり書いてありますねー。そして、filterSkillNameを確認すると...?

/*
 * Filter the name by replacing all the invalid character to '_'
 *
 * @params skillName
 * @return filteredName
 */
module.exports.filterSkillName = (name) => {
    return name.replace(/[^a-zA-Z0-9-_]+/g, '_');
};

置換しています。ということで、今回の修正に関しては、63行目の以下の箇所を

    let result = module.exports.filterSkillName(name);

次のようにシンプルに修正してみました。

    let result = name;

試してみると...

$ ask clone --skill-id amzn1.ask.skill.xxxxxxxxxxxx
-------------------- Clone Skill Project --------------------
Project directory for 連絡先取得のサンプル created at
    ./連絡先取得のサンプル

日本語名でディレクトリが作られました!