LoginSignup
5
2

More than 3 years have passed since last update.

Alexaスキル「業界用語変換」でAPL部分を作りました

Last updated at Posted at 2019-12-07

はじめに

今年もAlexa Developerスキルアワードに参加しました。
社内有志3人で、ハッカソンのような短期集中開発を行い、「業界用語変換」というスキルができました。

_人人人人人人人人人人_
> ザギンでシースー:sushi: <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

担当パートざっくり

スキル全体 @daisukeArk
形態素解析部分 @ryosukeeeee
APL部分 @sr-mtmt

技術的なキャッチアップの機会にしようということで、私はAPLを触ってみることにしました。
さらに、以前Alexaスキルを作ったときはNode.js(TypeScript)で書いていたけれど、
今回はPythonで書いてみようということに。

APLとは

Alexaを始めとする音声アシスタントたちにいよいよ当たり前に画面が付き始め、
視覚情報も提供できるようになりました。

Alexa Presentation Language(APL)は、
アニメーション、グラフィック、画像、スライドショー、ビデオを含んだ視覚要素を
スキルのやりとりに合わせて変えていくことで様々な演出をすることができます。

例としてAlexaのイベントで展示されていたりするのはPIZZA SALVATORE CUOMOのスキルですね。
体験版で実際には購入しなくてもスキルの操作だけ試すことができます。

つくってみた

ちなみにNode.js版はこちらのシリーズを参考にさせていただきました。
https://qiita.com/Mount/items/72d9928ff2c0ae5de737

スキル開発コンソール画面の使い方やJSONの話とかはPythonも同じなので割愛します。

# Launch Requestのhandle
def handle(self, handler_input):
    # type: (HandlerInput) -> Response

    session_attr = AttributesManager.session_attributes
    logger.info(session_attr)

    speak_output = "いらっしゃいませ。\nあなたの言葉を業界人の言葉に変換します。\n「”銀座で寿司”ってなんていうの」というふうに聞いてください"

    builder = (
        handler_input.response_builder
        .speak(speak_output)
        .ask(speak_output)
    )

    # APL対応デバイスのときだけbuilderにAPL情報を追加
    if(is_apl_supported(handler_input.request_envelope)):
        builder.add_directive(
            RenderDocumentDirective(
                document=GetAplJsonDocument.get_apl_json("launch"),
                datasources=GetAplJsonDatasources.get_apl_json("launch")
            )
        )

    return builder.response
# APL情報の入ってるJSONファイルを取ってくる
class GetAplJsonBase(object):
    _document_type = None

    @classmethod
    def get_apl_json(cls, intent_name):
        # このファイルの場所からの相対パスではなくLambdaから見た絶対パス指定なので注意
        file_path_base = '/var/task/'

        with open(file_path_base + cls._document_type + '/' + intent_name + '.json', 'r', encoding="utf-8") as f:
            return json_load(f)


class GetAplJsonDocument(GetAplJsonBase):
    _document_type = 'document'


class GetAplJsonDatasources(GetAplJsonBase):
    _document_type = 'datasources'


def is_apl_supported(request):
    apl_interface = request.context.system.device.supported_interfaces.alexa_presentation_apl
    return apl_interface is not None

APL情報のJSONはテキストファイルじゃなくて、jsで定義したほうが使い勝手が良いかも、という指摘もあったのですが
色々試していて形式が定まらなかったこともあり、今回はテキストファイルからJSONを読み込んで渡しています。

jsで定義する場合の参考はこちら

function createDatasource(attributes) {
  return {
    "riddleGameData": {
        "properties": {
            "currentQuestionSsml": "<speak>" 
                + attributes.currentRiddle.question
                + "<speak>",
            "currentLevel": attributes.currentLevel,
            "currentQuestionNumber": (attributes.currentIndex + 1),
            "numCorrect": attributes.correctCount,
            "currentHint": attributes.currentRiddle.hints[attributes.currentHintIndex]
        },
        "transformers": [
            {
                "inputPath": "currentQuestionSsml",
                "outputName": "currentQuestionSpeech",
                "transformer": "ssmlToSpeech"
            },
            {
                "inputPath": "currentQuestionSsml",
                "outputName": "currentQuestionText",
                "transformer": "ssmlToText"
            }
        ]
    }
  };
}

参考元)https://github.com/alexa-labs/skill-sample-nodejs-level-up-riddles/blob/master/Step%203%20-%20Add%20APL/lambda/custom/index.js#L461-L487

終わり

これであとはJSONを工夫すればいろいろ出せるはず

VUIの個性を活かしながら視覚情報とタッチパネルにも対応していくことを考えるのはむずかしいなと感じています。
スマホとどう使い分けていくのか、エンジニアだけでなくいろいろなひととコラボレーションして模索していきたいと思いました。

スマートスピーカー Advent Calender 2019 空き枠ありますので、興味のある方ぜひご投稿ください:sunny:

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2