はじめに
今年もAlexa Developerスキルアワードに参加しました。
社内有志3人で、ハッカソンのような短期集中開発を行い、「業界用語変換」というスキルができました。
_人人人人人人人人人人_
> ザギンでシースー <
 ̄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"
}
]
}
};
}
終わり
これであとはJSONを工夫すればいろいろ出せるはず
VUIの個性を活かしながら視覚情報とタッチパネルにも対応していくことを考えるのはむずかしいなと感じています。
スマホとどう使い分けていくのか、エンジニアだけでなくいろいろなひととコラボレーションして模索していきたいと思いました。
スマートスピーカー Advent Calender 2019 空き枠ありますので、興味のある方ぜひご投稿ください