スキルの応答にカードを追加する
ユーザーとAlexaデバイスとの対話には、Amazon Alexaアプリ(Fire OS、Android、iOS、デスクトップウェブブラウザで利用可能なコンパニオンアプリ)に表示するカードを追加することができます。これらは、音声での対話について説明したり、音声の対話を補強したりする視覚的なカードです。カスタムスキルでは、応答にこのカードを含めることができます。
カードを確認するには、Alexaアプリを開いてアクティビティページに移動します。スキルに画面専用のコンテンツ(DisplayテンプレートまたはAlexa Presentation Language)が含まれていない場合は、Echo Showなどの画面付きデバイスにカードを表示することもできます。
カードの概要
カードは、インタラクションを補強することができます。たとえば、音声の応答は、簡潔に、そして「耳で聞き取ることを前提に記述する」必要があります。カードでは、音声で応答するには長すぎたり、聞いただけでは分かりにくかったりする詳細情報や便利な情報を表示させることができます。たとえば、このシンプルなカードは、ユーザーのギフトカードの残高に関する詳細情報を提供します。
Alexa Skills Kitでは、さまざまなタイプのカードが提供されています。
Simple
カード:プレーンテキストを表示します。開発者は、カードのタイトルと本文のテキストを指定します。Standard
カード:プレーンテキストだけでなく、画像も表示できます。開発者は、タイトルと本文のテキストと、表示する画像のURLを指定します。LinkAccount
カード:アカウントリンクでのみ使用する特殊なカードタイプです。このカードを使うと、ユーザーはアカウントリンクプロセスを開始できます。- ユーザーがスキルに特定の権限を付与する必要がある場合は、
AskForPermissionsConsent
カードがAlexaアプリに送信されます。
カードをAlexaアプリに送信するには、サービスがAlexaに返す応答にカードを含めます。通常、スキルがユーザーのリクエストした情報を応答で返す際、カードのみを返します。ユーザーに詳しい情報をたずねる質問などの、その他の応答には通常カードを含めません。
カードを確認するには、Alexaアプリを開いてアクティビティページに移動します。
効果的なカードを設計する際の推奨事項については、スキルカードデザインのベストプラクティスを参照してください。
テキストを表示する基本的なカードを作成する
最もシンプルなカードは、プレーンテキストで構成されたものです。タイトルと本文を指定すると、以下のようにAlexaアプリに表示されます。
カードに含めることのできる文字数(タイトルと本文の合計)は、8,000文字以内です。
Simpleカードを作成するには、JSON応答にcard
プロパティを追加します。
type
をSimple
に設定します。title
プロパティとcontent
プロパティに、表示するテキストを設定します。改行を挿入するには、content
内で「\r\n
」または「\n
」を使用します。
このサンプルコードはAlexa Skills Kit SDK for Node.js (v2)を使用しています。
ResponseBuilder
オブジェクトのspeak
メソッドとwithSimpleCard
メソッドを使って、読み上げとカードのテキストを定義します。getResponse()
メソッドは、指定されたプロパティを含む応答を返します。
return handlerInput.responseBuilder
.speak("これはAlexaが読み上げるテキストです。Alexaアプリを開いてカードを見てください。")
.withSimpleCard(
"これはカードのタイトルです。",
"これはカードの内容です。このカードはプレーンテキストのコンテンツです。\r\nコンテンツが読みやすいように改行を使用して調整します。")
.getResponse();
このサンプルコードはAlexa Skills Kit SDK for Pythonを使用しています。
ResponseFactory
オブジェクトのspeak
メソッドとset_card
メソッドを使って、応答に含める読み上げとカードのテキストを定義します。
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response
from ask_sdk_model.ui import SimpleCard
class HelloWorldIntentHandler(AbstractRequestHandler):
"""ハローワールドインテント用ハンドラー"""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("HelloWorldIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
speech_text = "これはAlexaが読み上げるテキストです。Alexaアプリを開いてカードを見てください。"
card_title = "これはカードのタイトルです"
card_text = “これはカードの内容です。このカードにはプレーンテキストのみ含まれます。\r\nコンテンツが読みやすいように改行を使用して調整します。"
return handler_input.response_builder.speak(speech_text).set_card(
SimpleCard(card_title, card_text)).response
このサンプルコードはAlexa Skills Kit SDK for Javaを使用しています。
ResponseBuilder
オブジェクトのwithSpeech()
メソッドとwithSimpleCard
メソッドを使って、読み上げとカードのテキストを定義します。build()
メソッドは、指定されたプロパティを含む応答を返します。
@Override
public Optional<Response> handle(HandlerInput handlerInput, IntentRequest intentRequest) {
String speechText ="これはAlexaが読み上げるテキストです。Alexaアプリを開いてカードを見てください。";
String cardTitle = "これはカードのタイトルです";
String cardText = “これはカードの内容です。このカードにはプレーンテキストのみ含まれます。\r\nコンテンツが読みやすいように改行を使用して調整します。";
return handlerInput.getResponseBuilder()
.withSpeech(speechText)
.withSimpleCard(cardTitle, cardText)
.build();
}
このJSON応答は、シンプルなプレーンテキストのoutputSpeech
文字列を返す方法の例です。この応答には、タイトルとシンプルなコンテンツを表示するカードも含まれています。
{
"version": "1.0",
"response": {
"outputSpeech": {
"type": "PlainText",
"text": "これはAlexaが読み上げるテキストです。Alexaアプリを開いてカードを見てください。"
},
"card": {
"type": "Simple",
"title": "これはカードのタイトルです",
"content": “これはカードの内容です。このカードにはプレーンテキストのみ含まれます。\r\nコンテンツが読みやすいように改行を使用して調整します。"
}
}
}
テキストと画像を表示するカードを作成する
カードでは、1枚のみですが画像を表示することができます。この場合、タイトルと本文のほかに、表示する画像のURLを2つ(小さい画像用と大きい画像用)指定します。
カードに含めることのできる文字数(title
、content
、2つのURL
の合計)は、8,000文字以内です。画像のURLは、それぞれ2000文字以内でなければなりません。
画像付きのカードを作成するには、JSON応答にcard
プロパティを追加します。
type
をStandard
に設定します。title
プロパティとtext
プロパティに、表示するテキストを設定します。- このタイプのカードでは、
Simple
のようにcontent
プロパティを使うのではなく、text
プロパティを使用することに注意してください。 - 改行を挿入するには、
text
内で「\r\n
」または「\n
」を使用します。
- このタイプのカードでは、
smallImageUrl
とlargeImageUrl
を指定したimage
オブジェクトを追加します。smallImageUrl
とlargeImageUrl
に、表示する画像の小さいバージョンと大きいバージョンのURLを設定します。画像の形式、サイズ、ホスティング要件の詳細については、以下を参照してください。
{
"version": "1.0",
"response": {
"outputSpeech": {"type":"PlainText","text":"タクシーが向かっています!"},
"card": {
"type": "Standard",
"title": "車の手配",
"text": "予約車は中央通り123番地に向かっています。\n見積料金は2500円です"
"image": {
"smallImageUrl": "https://ridehailer.com/resources/card-images/race-car-small.png",
"largeImageUrl": "https://ridehailer.com/resources/card-images/race-car-large.png"
}
}
}
}
画像の形式とサイズ
以下の形式の画像が提供できます。
- JPEG
- PNG
画像のサイズは500 KB未満である必要があります。
画像を含める際、解像度の低い画像と高い画像の2つのURLを指定します。異なるサイズの画面にカードを表示する際、異なるサイズの画像が使い分けられます。
プロパティ | 説明 | 推奨サイズ(ピクセル) |
---|---|---|
smallImageUrl |
小さい画面に表示されます | 横720 x 縦480 |
largeImageUrl |
大きい画面に表示されます | 横1200 x 縦800 |
画面のサイズが変わってもカードを適切に表示するには、smallImageUrl
とlargeImageUrl
の両方を指定してください。URLを1つしか指定しない場合、表示される画面のサイズにかかわらずその画像が使用されます。それによってカードが見えづらくなる場合があります。たとえば、smallImageUrl
のみを指定した場合では、大きな画面に表示するときに画像が拡大されるため、画質が低下する可能性があります。
推奨サイズに近い画像を使用すれば、アプリの画像の画質が損なわれることはありません。小さい画像は拡大されることで、画質が下がることがあります。逆に、大きい画像は読み込みに時間がかかるので、必要以上に大きなサイズを指定するとアプリでのカードの表示パフォーマンスが下がる可能性があります。
たとえば、以下は、非常に小さい画像を拡大している例です。
カードは、必ずAlexaアプリで(できれば、さまざまな画面サイズの複数のデバイスを使用して)テストをして、適切に表示されることを確認してください。
画像をホストする
Alexaアプリは、実行時に、指定したURLから画像を読み込みます。指定する画像ファイルは、以下の要件を満たすHTTPSエンドポイントでホストされる必要があります。
- エンドポイントでは、Amazon認定の認証局が署名したSSL証明書を提供します。これは、多くのコンテンツホスティングサービスで提供されています。たとえば、Amazon Simple Storage Service(Amazon S3)(Amazon Web Servicesが提供)などのサービスでファイルをホストできます。
- エンドポイントで、画像のCross-Origin Resource Sharing(CORS)を許可していること。これにより、Amazon Alexaアプリが画像をダウンロードして、アプリで表示する前に処理や検証ができるようになります。
CORSを有効にするには、画像のサーバーで、応答にAccess-Control-Allow-Origin
ヘッダーを設定する必要があります。リソースをAlexaアプリのみに限定する場合は、取得元としてhttp://ask-ifr-download.s3.amazonaws.comとhttps://ask-ifr-download.s3.amazonaws.comのみを許可してください。
この設定方法は、画像のホストによって異なります。たとえば、Amazon S3バケットで画像をホストする場合は、以下のCORSコンフィギュレーション(JSONで表示)を使用してバケットを設定します。
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"http://ask-ifr-download.s3.amazonaws.com",
"https://ask-ifr-download.s3.amazonaws.com"
],
"ExposeHeaders": []
}
]
S3およびCORSの詳細については、Enabling Cross-Origin Resource Sharingを有効にするを参照してください。
Standardカードに画像を含める際によくある問題
このセクションでは、Standard
カードに画像を含める際に発生する可能性がある、よくある問題について説明します。
画像のスペースが空白になっている場合: 以下の理由が考えられます。
-
画像がない: 指定した画像のURLが実際の画像を参照していない、公開されていない画像を参照している、URLの有効期限が切れている、などの原因で発生します。
注: Amazon S3を使用して画像をホストする場合、画像を公開し、有効期限を設定しないでください。一部のホスティングソリューション(Amazon S3など)では、画像URLに有効期限を設定することが可能です。この場合、有効期限が過ぎるとURLは無効になります。Alexaアプリでは、実行時に、指定したURLから画像を読み込むため、URLは常に有効な画像を参照している必要があります。画像に使用するURLには、有効期限を設定しないでください。 - 画像のホストがCORS対応ではない: 画像をホストするサーバーがCORS対応ではありません。
- 画像の形式が正しくない: 画像のURLで参照している画像が、サポート対象外の形式(
PNG
、JPEG
以外)になっています。 - 画像が大きすぎる:指定した画像ファイルのサイズが大きすぎます。
画像もプレースホルダーもない状態でカードが表示される: 応答に実際の画像オブジェクトが含まれていない場合に発生します。カードは表示されますが、画像は表示されません。
例として、以下のJSONを見てみましょう。Standard
カードとして指定されていますが、image
がありません。
{
"version": "1.0",
"response": {
"outputSpeech": {"type":"PlainText","text":"タクシーが向かっています!"},
"card": {
"type": "Standard",
"title": "車の手配",
"text": "予約車は中央通り123番地に向かっています。\n見積料金は2500円です"
}
}
}
このコードでは次のようなカードが作成されます。
アカウントリンクに使用するカードを定義する
Alexaスキルの中には、エンドユーザーのIDと別のシステムのユーザーアカウントを結び付ける機能が必要なものもあります。この機能を、「アカウントリンク」と呼びます。Alexaユーザーとシステムのユーザーアカウント間でリンクを作成することを目的としているためです。
ユーザーがこのリンクを必要とするインテントを呼び出したときにリンクが確立されていない場合、スキルでは、Alexaアプリを使用してアカウントをリンクするよう指示する応答をユーザーに返す必要があります。アプリに表示されるカードは、ユーザーにアカウントをリンクさせるための特殊なタイプのカードです。アカウントリンクカードは、アクティビティフィードに加えて、Alexaアプリのメインホームフィードに表示されます。
カードにはスキルのアイコンと名前が含まれます。「アカウントをリンク」というリンクは、スキルのアカウントリンクの設定時に開発者コンソールで設定した認証画面のURIに移動します。
アカウントリンクのカードを作成するには、JSON応答にcard
プロパティを追加します。タイプをLinkAccount
に設定し、それ以外のプロパティは渡しません。
{
"version": "1.0",
"response": {
"outputSpeech": {"type":"PlainText","text":"Alexaアプリに移動して、アカウントをリンクしてください。"},
"card": {
"type": "LinkAccount"
}
}
}
以下の例は、Alexa Skills Kit SDK for Node.jsとAlexa Skills Kit SDK v2 for Javaを使ってアカウントリンクカードを返す方法を示しています。
このサンプルコードはAlexa Skills Kit SDK for Node.js (v2)を使用しています。
const OrderCarIntentHandler = {
// ...
handle(handlerInput){
// このインテントではユーザーのタクシー予約プロフィールと支払い情報を
// 取得するためにアクセストークンが必要です。
// アクセストークンはContextオブジェクトにあります。ハンドラーに渡される
// HandlerInputオブジェクトでリクエストに
// アクセスします。
var accessToken = handlerInput.requestEnvelope.context.System.user.accessToken;
if (accessToken == undefined){
// リクエストにはトークンが含まれなかったため、ユーザーに
// リンクするよう伝えてアカウントリンクカードを返します。
var speechText = "車を手配するには、タクシー予約アカウントが必要です。" +
"Alexaアプリを使用してAmazonアカウントとタクシー予約アカウントを" +
"リンクしてください。";
return handlerInput.responseBuilder
.speak(speechText)
.withLinkAccountCard()
.getResponse();
} else {
// トークンを使ってユーザーのプロフィールにアクセスします。ここでもトークンが有効な
// タクシー予約ユーザーを表すことを確認する必要があります。
// ...
}
}
};
このサンプルコードはAlexa Skills Kit SDK for Javaを使用しています。
public class OrderCarIntentHandler implements RequestHandler {
// ...
@Override
public Optional<Response> handle(HandlerInput handlerInput) {
// このインテントではユーザーのタクシー予約プロフィールと支払い情報を
// 取得するためにアクセストークンが必要です。
// アクセストークンはContextオブジェクトにあります。ハンドラーに渡される
// HandlerInputオブジェクトでリクエストに
// アクセスします。
String accessToken = handlerInput
.getRequestEnvelope()
.getContext()
.getSystem()
.getUser()
.getAccessToken();
if (accessToken != null) {
// メソッドを呼び出してトークンを検証し、ユーザーのタクシー予約プロフィールを
// 取得し、車を手配します。
return orderCarForUser(accessToken, handlerInput);
} else {
// リクエストにはトークンが含まれなかったため、ユーザーに
// リンクするよう伝えてアカウントリンクカードを返します。
String speechText = "車を手配するには、タクシー予約アカウントが必要です。"
+ "Alexaアプリを使用してAmazonアカウントとタクシー予約アカウントを"
+ "リンクしてください。";
// 出力音声とアカウントリンクカードを含む応答を作成します。
return handlerInput.getResponseBuilder()
.withSpeech(speechText)
.withLinkAccountCard()
.build();
}
}
}
詳細については、カスタムスキルのアカウントリンクを参照してください。
特定の権限を申請するためにAskForPermissionsConsentカードを送信する
スキルはAskForPermissionsConsent
権限カードを表示して、ユーザーに動的に同意を求めることができます。ユーザーの同意をリクエストする権限カードについては、ユーザー同意をリクエストする権限カードを参照してください。
関連トピック
- スキルカードデザインのベストプラクティス
- Alexaから送信されたリクエストを処理する
- スキルにアカウントリンクを追加する
- スキルのユーザー情報のアクセス許可を設定する
- カスタムスキルのJSONインターフェースのリファレンス
- カスタムスキルのビルド手順
最終更新日: 2023 年 05 月 16 日