Alexa for Businessのスキルを作成してみました。
リージョンを指定するとそのリージョンで発生中のCloudwatchAlarmを答えるスキルです。
必要なもの
- AWSアカウント
- Amazon Developerアカウント
- Alexa Skills Kit Command Line Interface (ASK CLI)
作業概要
- スキル用のLambdaの作成
- スキルの作成とテスト
- プライベートスキルの設定
- 公開情報とプライバシーとコンプライアンスの設定
- 申請とスキルの有効化
1. スキル用のLambdaの作成
以下AWSマネジメントコンソールにログインして作業します。
1. Lambda用のIAMロールを作成する
以下ポリシーを持ったIAMロールを作成します。
Lambda用のベースのポリシーにCloudwatchアラームへのアクセス許可を追加しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": "cloudwatch:DescribeAlarms",
"Resource": "*"
}
]
}
2. blueprintsで[alexa-skills-kit-color-expert-python]を選択・編集しLambdaを作成する
blueprintはpython2.7用ですが、python3.6用にしています。
# -*- coding: utf-8 -*-
import boto3
# --------------- Helpers that build all of the responses ----------------------
def build_speechlet_response(title, output, reprompt_text, should_end_session):
return {
'outputSpeech': {
'type': 'PlainText',
'text': output
},
'card': {
'type': 'Simple',
'title': "SessionSpeechlet - " + title,
'content': "SessionSpeechlet - " + output
},
'reprompt': {
'outputSpeech': {
'type': 'PlainText',
'text': reprompt_text
}
},
'shouldEndSession': should_end_session
}
def build_response(session_attributes, speechlet_response):
return {
'version': '1.0',
'sessionAttributes': session_attributes,
'response': speechlet_response
}
# --------------- Functions that control the skill's behavior ------------------
def get_welcome_response():
session_attributes = {}
card_title = "Welcome"
speech_output = "こんにちは。AWSのアラート状況をお知らせするスキルです。 " \
"例えば次のように質問して下さい。 " \
"東京リージョンの状況は"
reprompt_text = "例えば次のように質問して下さい。 " \
"東京リージョンの状況は"
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def handle_session_end_request():
card_title = "Session Ended"
speech_output = "Thank you for trying the Alexa Skills Kit sample. " \
"Have a nice day! "
# Setting this to true ends the session and exits the skill.
should_end_session = True
return build_response({}, build_speechlet_response(
card_title, speech_output, None, should_end_session))
def get_alarms(region):
cloudwatch = boto3.client('cloudwatch', region_name=region)
try:
response = cloudwatch.describe_alarms(StateValue='ALARM')
alarms = [alarm['AlarmName'] for alarm in response['MetricAlarms']]
print(alarms)
return alarms
except Exception as e:
print(e)
raise e
def response_alarms(intent, session):
card_title = intent['name']
session_attributes = {}
should_end_session = False
region_dic = {
'東京':'ap-northeast-1',
'バージニア':'us-east-1',
'シドニー':'ap-southeast-2'
}
if 'Region' in intent['slots'] \
and intent['slots']['Region']['value'] in region_dic:
region_jp = intent['slots']['Region']['value']
region = region_dic[region_jp]
alarms = get_alarms(region)
if len(alarms) == 0:
speech_output = "現在" + \
region_jp + \
"リージョンにアラートはありません。 "
else:
speech_output = "現在" + \
region_jp + \
"リージョンに" + \
str(len(alarms)) + \
"件アラートが発生しています。" + \
"アラート名は" + \
"と".join(alarms) + \
"です。"
reprompt_text = None
should_end_session = True
else:
speech_output = "リージョン名がわかりませんでした。" \
"もう一度お願いします。"
reprompt_text = "リージョン名がわかりませんでした。 " \
"もう一度お願いします。"
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
# --------------- Events ------------------
def on_session_started(session_started_request, session):
print("on_session_started requestId=" + session_started_request['requestId']
+ ", sessionId=" + session['sessionId'])
def on_launch(launch_request, session):
print("on_launch requestId=" + launch_request['requestId'] +
", sessionId=" + session['sessionId'])
return get_welcome_response()
def on_intent(intent_request, session):
print("on_intent requestId=" + intent_request['requestId'] +
", sessionId=" + session['sessionId'])
intent = intent_request['intent']
intent_name = intent_request['intent']['name']
if intent_name == "MyAwsAlarmsIntent":
return response_alarms(intent, session)
elif intent_name == "AMAZON.HelpIntent":
return get_welcome_response()
elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
return handle_session_end_request()
else:
raise ValueError("Invalid intent")
def on_session_ended(session_ended_request, session):
print("on_session_ended requestId=" + session_ended_request['requestId'] +
", sessionId=" + session['sessionId'])
# --------------- Main handler ------------------
def lambda_handler(event, context):
""" Route the incoming request based on type (LaunchRequest, IntentRequest,
etc.) The JSON body of the request is provided in the event parameter.
"""
print("event.session.application.applicationId=" +
event['session']['application']['applicationId'])
"""
Uncomment this if statement and populate with your skill's application ID to
prevent someone else from configuring a skill that sends requests to this
function.
"""
# if (event['session']['application']['applicationId'] !=
# "amzn1.echo-sdk-ams.app.[unique-value-here]"):
# raise ValueError("Invalid Application ID")
if event['session']['new']:
on_session_started({'requestId': event['request']['requestId']},
event['session'])
if event['request']['type'] == "LaunchRequest":
return on_launch(event['request'], event['session'])
elif event['request']['type'] == "IntentRequest":
return on_intent(event['request'], event['session'])
elif event['request']['type'] == "SessionEndedRequest":
return on_session_ended(event['request'], event['session'])
2. スキルの作成とテスト
以下Amazon開発者コンソールにログインして作業します。
1. スキル情報を設定する
- スキルの種類:Custom
- 言語:Japanese
- スキル名:AWSアラート状況
- 呼び出し名:awsアラート状況
他はデフォルト
2. 対話モデルを設定する
- インテントスキーマ
{
"intents": [
{
"slots": [
{
"name": "Region",
"type": "LIST_OF_REGIONS"
}
],
"intent": "MyAwsAlarmsIntent"
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.StopIntent"
},
{
"intent": "AMAZON.CancelIntent"
}
]
}
-
カスタムスロットタイプ
- タイプ:LIST_OF_REGIONS
- 値:
- 東京
- バージニア
- シドニー
-
サンプル発話
- MyAwsAlarmsIntent {Region} は
- MyAwsAlarmsIntent {Region} の状況は
- MyAwsAlarmsIntent {Region} のアラート状況は
3. 「設定」を設定する
- サービスエンドポイントのタイプ:AWS Lambda の ARN
- 作成したLambdaのARNを指定する
他はデフォルト
4. テストする
4-1. あらかじめ、バージニアリージョンに3件Cloudwatchアラームが発生している状態にしておきます。
4-2. 発話を入力してください欄に「バージニアは」と入力してテストすると
4-3. サービスレスポンスに下記が返ってきます。
{
"version": "1.0",
"response": {
"outputSpeech": {
"text": "現在バージニアリージョンに3件アラートが発生しています。アラート名はalarm_1とalarm_2とalarm_3です。",
"type": "PlainText"
},
"card": {
"content": "SessionSpeechlet - 現在バージニアリージョンに3件アラートが発生しています。アラート名はalarm_1とalarm_2とalarm_3です。",
"title": "SessionSpeechlet - MyAwsAlarmsIntent"
},
"reprompt": {
"outputSpeech": {
"type": "PlainText"
}
},
"speechletResponse": {
"outputSpeech": {
"text": "現在バージニアリージョンに3件アラートが発生しています。アラート名はalarm_1とalarm_2とalarm_3です。"
},
"card": {
"content": "SessionSpeechlet - 現在バージニアリージョンに3件アラートが発生しています。アラート名はalarm_1とalarm_2とalarm_3です。",
"title": "SessionSpeechlet - MyAwsAlarmsIntent"
},
"reprompt": {
"outputSpeech": {}
},
"shouldEndSession": true
}
},
"sessionAttributes": {}
}
3. プライベートスキルの設定
1. alexa Skills Kit Command Line Interface (ASK CLI)をインストールする
下記URLを参考にインストールします。
https://developer.amazon.com/docs/smapi/quick-start-alexa-skills-kit-command-line-interface.html
2. プライベートスキルの設定をする
下記URLを参考にプライベートスキルの設定をします。
http://docs.aws.amazon.com/a4b/latest/ag/private-skills.html
スキルのIDは、スキル情報に表示されます。
$ skill_id=<スキルのID>
$ ask api get-skill -s ${skill_id} > skill.json
$ vi skill.json
"distributionMode": "PRIVATE"を1行追加する
{
"skillManifest": {
"publishingInformation": {
"locales": {
"ja-JP": {
"name": "AWSアラート状況"
}
},
"isAvailableWorldwide": true,
"distributionMode": "PRIVATE"
},
"apis": {
"custom": {
"endpoint": {
"uri": "<LambdaのARN>"
}
}
},
"manifestVersion": "1.0"
}
}
$ ask api update-skill -s ${skill_id} -f skill.json
4. 公開情報とプライバシーとコンプライアンスの設定
以下Amazon開発者コンソールで作業します。
ちょっと面倒ですが、小アイコン(108x108)と大アイコン(512x512)を用意してアップロードし
他記入できるところを全て記入します。
5. 申請とスキルの有効化
1. 申請する
$ ask api submit -s ${skill_id}
2. ステータスがLiveになるまで、数時間待つ
3. Alexa for Businessオーガナイゼーションに配布する
$ account_id=arn:aws:iam::<AWSアカウントID>:root
$ ask api add-private-distribution-account -s ${skill_id} --stage live --account-id ${account_id}
4. スキルを有効にする
AWSマネジメントコンソール:Alexa for Businessのprivate skillsの一覧にスキルが表示されます。
[Review]をクリックして[Enable]を選択しスキルを有効にします。
5. ここまで
東京リージョンではまだ利用できないので、残念ながらここまでです。
2017/12/5追記 英語でよければ、利用できるそうです。
雑感
Alexa for Businessの何でもできちゃいそう感がすごい。
Re:Inventのキーノートを見たら「ちょっといい会議システム」みたいなものと勘違いしちゃいそうですが、もっと全然奥が深そう。
自分の中では2017年のRe:Inventの2番目の目玉です。
早く東京リージョンにこないかな。