1. 概要
Google アシスタントのデベロッパー プラットフォームを使用すると、Google アシスタントのバーチャル パーソナル アシスタント機能を拡張するソフトウェアを作成し、スマート スピーカー、スマートフォン、自動車、テレビ、ヘッドフォンなど 10 億以上のデバイスで公開できます。ユーザーは、Google アシスタントとの会話を通じて、食料品の購入から乗車の予約までさまざまなタスクを実行できます。Google アシスタントのデベロッパー プラットフォームを使用することで、サードパーティ フルフィルメント サービスを開発し、ユーザーとの快適かつ効果的な会話型エクスペリエンスを簡単に作成、管理できます。
この Codelab では、Google アシスタント、Cloud Functions、Cloud Firestore を使用した開発に関する中級レベルのコンセプトについて説明します。この Codelab では、Google アシスタントを使用してユーザーに単語のスペルを尋ねる「スペル練習」というゲームを作成します。
作成するアプリの概要
この Codelab では、以下の機能を備えた高度なゲームを構築します。
- ユーザーからスペルに関する回答を受け取り、値に応じて会話のプロンプトを変更する
- 単語のスペルに関連するヒント(単語の定義や単語の繰り返しなど)で応答する
- ゲームループを作成し、ユーザーが単語のスペルを答えた後にアシスタントとやり取りできるようにする
構築を開始する前に、公開済みのアクションで会話を試すことができます。Google アシスタント対応デバイスを用意し、「OK Google, talk to Spelling Practice」(OK Google, スペル練習)と話しかけてください。このアクションにアクセスするのが 2 回目以降のユーザーの場合、デフォルトでは次のように会話が進行します。
この Codelab を完了すると、次のような会話フローのアクションが完成します。

学習内容
- Cloud Firestore を操作する方法
- スロットを使用してユーザーからデータを収集する方法
- ユーザーの入力を処理して応答を返す
- 条件を使用してシーンにロジックを追加する方法
- ゲームループを追加する方法
必要なもの
この Codelab に必要なもの(および前提条件)は以下のとおりです。
2. 関数のコードを取得する
コマンドラインから、GitHub リポジトリのクローンを作成します。
$ git clone https://github.com/FirebaseExtended/codelab-actions-firestore
3. Firebase プロジェクトを作成してアプリを設定する
Firebase プロジェクトを作成する
- Firebase にログインします。
- Firebase コンソールで [プロジェクトを追加](または [プロジェクトを作成])をクリックし、Firebase プロジェクトに
Spelling-Practiceという名前を付けます。

- プロジェクト作成オプションをクリックします。プロンプトが表示されたら、Firebase の利用規約に同意します。このアプリではアナリティクスを使用しないため、Google アナリティクスの設定はスキップします。
Firebase プロジェクトの詳細については、Firebase プロジェクトについて理解するをご覧ください。
Blaze のお支払いプランにアップグレードする
Cloud Functions for Firebase を使用するには、Firebase プロジェクトを Blaze 料金プランにアップグレードする必要があります。つまり、Google Cloud 請求先アカウントをプロジェクトに関連付ける必要があります。この場合、クレジット カードなどの支払い方法をご登録いただく必要があります。
Blaze プランを含むすべての Firebase プロジェクトで、Cloud Functions の無料枠を引き続きご利用いただけます。この Codelab で説明する手順は、無料枠の使用量上限内に収まります。ただし、Cloud Functions のビルドイメージのホストに使用される Cloud Storage から、少額の料金(約 $0.03)が請求されます。
4. Firebase CLI をインストールする
Firebase CLI(コマンドライン インターフェース)を使用すると、Cloud Functions をデプロイできます。
オペレーティング システムとユースケースに応じて、Firebase CLI をインストールするいくつかの方法があります。次の手順は、Cloud Functions も使用している場合に最も一般的なオプションです。
$ npm -g install firebase-tools
- 次のコマンドを実行して、CLI が正しくインストールされたことを確認します。
$ firebase --version
Firebase CLI のバージョンが 9.0.0 以降であることを確認します。これ以降のバージョンには、Cloud Functions に必要な最新の機能がすべて含まれています。バージョンがこれより低い場合は、上記のように npm install -g firebase-tools を実行してアップグレードします。
- 次のコマンドを実行して、Firebase CLI を承認します。
$ firebase login
- spelling-functions-start ディレクトリから、Firebase プロジェクトを使用するように Firebase CLI を設定します。次のコマンドを実行し、プロジェクト ID を選択して、画面の手順に沿って操作します。プロンプトが表示されたら、任意のエイリアス(
codelabなど)を選択できます。
$ firebase use --add
5. functions ディレクトリ
次に、Firebase SDK for Cloud Functions を使用して、ゲーム「スペル練習」のバックエンドを構築する機能を追加します。
Cloud Functions では、サーバーを設定しなくても Cloud で実行可能なコードを追加できます。この Codelab では、Firebase Authentication、Cloud Storage、Firebase Realtime Database のイベント発生時に実行する関数の作成方法について説明します。まず、認証から始めましょう。
Firebase SDK for Cloud Functions を使用する場合、作成する関数のコードはデフォルトで functions ディレクトリに保存されます。コードを記述する functions/index.js ファイルはすでに作成されています。先に進む前に、functions ディレクトリを自由に確認してください。
$ cd functions $ ls
関数のコードは Node.js アプリになるので、アプリの情報と依存関係を示す package.json が必要です。
Node.js に不慣れな場合は、Codelab を続行する前に、Node.js について詳しく学習することをおすすめします。
package.json ファイルには、必要な 2 つの依存関係、Firebase SDK for Cloud Functions と Firebase Admin SDK がすでに記述されています。これらをローカルにインストールするには、functions ディレクトリから npm install を実行します。
$ npm install
次に、index.js ファイルを見てみましょう。
index.js
/** * Copyright 2021 Google Inc. All Rights Reserved. * ... */ // TODO(DEVELOPER): Import the Cloud Functions for Firebase and Firebase Admin modules here. Also import the Actions SDK here. // TODO(DEVELOPER): Write the getWordDetailsFromDictionaryAPI function here. // TODO(DEVELOPER): Write the createSpellingPracticeWord function here. // TODO(DEVELOPER): Write the app Handle getSpellingWordList function here. // TODO(DEVELOPER): Write the app Handle getSpellingWord function here. // TODO(DEVELOPER): Write the app Handle repeatSpellingWord function here. // TODO(DEVELOPER): Write the app Handle definitionOfSpellingWord function here. // TODO(DEVELOPER): Write the app Handle verifySpellingWord function here.
まず、必要なモジュールをインポートし、TODO の代わりに 4 つの関数を作成します。Codelab の次のステップに進んで、モジュールをインポートします。
6. 必要なモジュールをインポートする
この Codelab には 3 つのモジュールが必要です。
firebase-functionsモジュールを使用すると、Cloud Functions のトリガーを記述できます。firebase-adminモジュールを使用すると、管理者アクセス権を持つサーバーで Firebase プラットフォームを使用できます(Cloud Firestore への書き込みなど)。- Actions SDK Node.js フルフィルメント ライブラリは、Google アシスタントの Actions SDK ハンドラをフルフィルメントします。
- 次の npm コマンドを実行して、Actions SDK をインストールします。
$ npm install @assistant/conversation
index.jsファイルで、最初の TODO を次のコードに置き換えます。
これらの変更により、必要な各モジュールがインポートされます。
また、Firebase Admin SDK は、Cloud Functions 環境やその他の Google Cloud コンテナにデプロイするときに自動的に設定されるようにすることができます。以下の変更で admin.initializeApp(); を呼び出すと、次のようになります。
index.js
/**
* Copyright 2021 Google Inc. All Rights Reserved.
* ...
*/
// Import the Actions SDK
const {conversation} = require('@assistant/conversation');
const https = require('https');
const app = conversation();
const cors = require('cors')({origin: true});
// Import the Firebase SDK for Cloud Functions.
const functions = require('firebase-functions');
// Import and initialize the Firebase Admin SDK.
const admin = require('firebase-admin');
admin.initializeApp();
// To access Cloud Firestore
const db = admin.firestore();
// TODO(DEVELOPER): Write the getWordDetailsFromDictionaryAPI function here.
// TODO(DEVELOPER): Write the createSpellingPracticeWord function here.
// TODO(DEVELOPER): Write the shuffleWordList function here.
// TODO(DEVELOPER): Write the app Handle getSpellingWordList function here.
// TODO(DEVELOPER): Write the app Handle getSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle repeatSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle definitionOfSpellingWord function here.
// TODO(DEVELOPER): Write the app Handle verifySpellingWord function here.
次に、関数を使用してアシスタント アクションをサポートするビジネス ロジックを追加します。
7. 関数を作成する
単語の定義を取得して Cloud Firestore に書き込む
dictionaryapi.dev パブリック API を使用して単語の定義を取得します。
index.js ファイルで、getWordDetailsFromDictionaryAPI の TODO を次のコードに置き換えます。
index.js
// Retrieves word definition and audio pronunciation from api.dictionaryapi.dev service
// Function uses service provided by https://dictionaryapi.dev/
async function getWordDetailsFromDictionaryAPI(word) {
let responseData="";
let req = https.request({
host: 'api.dictionaryapi.dev',
port: 443,
path:'/api/v2/entries/en/' + word,
method:'GET'
}, (res) => {
res.setEncoding('utf8');
res.on('data', d => {
responseData+=d;
})
res.on('end',function(){
let object = JSON.parse(responseData)
const wordListRef = db.collection('wordlist');
wordListRef.doc(object[0].word).set(
object[0]
);
return responseData;
});
});
req.end();
}
Cloud Firestore トリガーを追加する
次に、Cloud Firestore で新しいドキュメントが作成されるたびにトリガーされる Cloud Functions の関数を作成します。dictionaryapi.dev API を呼び出して、直前に作成した getWordDetailsFromDictionaryAPI 関数を介して単語の定義を取得します。
index.js ファイルで、createSpellingPracticeWord の TODO を次のコードに置き換えます。
index.js
// 新しい Firestore ドキュメントごとに getWordDetailsFromDictionaryAPI を介して単語の定義を取得する Firestore トリガー
exports.createSpellingPracticeWord = functions.firestore
.document('wordlist/{word}')
.onCreate((snap, context) => {
const newValue = snap.data();
const word = newValue.word;
getWordDetailsFromDictionaryAPI(word);
});
ゲームの単語リストを取得する
Cloud Firestore からスペル練習の単語リストをアシスタント用に取得する Cloud Functions を作成できます。これには、アプリ ハンドラを使用します。
index.js ファイルで、getSpellingWordList の TODO を次のコードに置き換えます。
この関数を特殊な app.handle に追加することで、アシスタントから関数にアクセスできるようになります。
index.js
// Store the list of spelling words in Assistant session
app.handle('getSpellingWordList', conv => {
const wordListRef = db.collection('wordlist').limit(50);
const snapshot = wordListRef;
if (snapshot.empty) {
console.log('No matching documents.');
return;
}
VocabularyList = []
return snapshot.get().then(snapshot => {
snapshot.forEach(doc => {
if (doc.data().word) {
let definition = 'unknown';
let audio = 'unknown';
try {
if(doc.data().hasOwnProperty('meanings')) {
if(doc.data().meanings[0].hasOwnProperty('definitions')) {
definition = doc.data().meanings[0].definitions[0].definition;
}
}
if(doc.data().hasOwnProperty('phonetics')) {
if(doc.data().phonetics.length > 0)
audio = doc.data().phonetics[0].audio;
}
} catch (error) {
console.log(error);
}
let obj = {
word: doc.data().word,
answer: doc.data().word.split("").join(" "),
definition: definition,
audio: audio
}
VocabularyList.push(obj);
}
// Shuffle the array
let currentIndex = VocabularyList.length, temporaryValue, randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = VocabularyList[currentIndex];
VocabularyList[currentIndex] = VocabularyList[randomIndex];
VocabularyList[randomIndex] = temporaryValue;
}
conv.session.params.vocabWord = VocabularyList;
conv.session.params.vocabWordIndex = 0;
});
});
})
アシスタント セッションから単語を取得する
単語リストから次のスペル単語を返す Cloud Functions を作成できます。
index.js ファイルで、getSpellingWord の TODO を次のコードに置き換えます。
index.js
// Returns a spelling practice word to Google Assistant and uses Speech Synthesis Markup Language (SSML) to format the response
app.handle('getSpellingWord', conv => {
if (!conv.session.params.vocabWord.empty) {
conv.session.params.vocabWordIndex+=1;
const ssml = '<speak>' +
'<audio src="'+ conv.session.params.vocabWord[conv.session.params.vocabWordIndex].audio +'">Use phonetics to spell the word.</audio> ' +
'</speak>';
conv.add(ssml);
}
else
conv.add('Great job! You completed the Spelling practice');
});
ゲームで単語を繰り返すことを有効にする
ゲームで現在の単語を繰り返す Cloud Functions を作成できます。
index.js ファイルで、repeatSpellingWord の TODO を次のコードに置き換えます。
index.js
// Returns current spelling word
app.handle('repeatSpellingWord', conv => {
if (!conv.session.params.vocabWord.empty) {
const ssml = '<speak>' +
'<audio src="'+ conv.session.params.vocabWord[conv.session.params.vocabWordIndex].audio +'">Use phonetics to spell the word. </audio> ' +
'</speak>';
conv.add(ssml);
}
else
conv.add('Great job! You completed the Spelling practice');
});
単語の定義を取得する
ゲームの現在の単語の定義を提供する Cloud Functions を作成できます。
index.js ファイルで、definitionOfSpellingWord の TODO を次のコードに置き換えます。
index.js
// Returns spelling word definition from Assistant session parameter
app.handle('definitionOfSpellingWord', conv => {
conv.add( 'It means ' + conv.session.params.vocabWord[conv.session.params.vocabWordIndex].definition);
});
ユーザーのスペルチェックの回答を確認する
ゲームの現在の単語のスペルをユーザーがどのように答えたかを検証する Cloud Functions を作成できます。
index.js ファイルで、verifySpellingWord の TODO を次のコードに置き換えます。
index.js
// Verifies user spelling response
app.handle('verifySpellingWord', conv => {
try {
userResponse = conv.intent.params.userresponse.resolved.join("");
if (userResponse.toLowerCase() === conv.session.params.vocabWord[conv.session.params.vocabWordIndex].word.toLowerCase()) {
conv.add('You are correct. Say next to continue.');
}
else {
conv.add('Sorry, wrong answer. The correct answer is ' + conv.session.params.vocabWord[conv.session.params.vocabWordIndex].answer + ' . Say next to continue.');
}
} catch (error) {
conv.add('Sorry. I did not understand your response' );
}
});
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
すべての関数をデプロイする
Cloud Functions は、Firebase にデプロイした後にのみ有効になります。
spelling-functions-start ディレクトリのルートから次のコマンドを実行します。
$ firebase deploy --only functions
コンソールに次のような出力が表示されます。
i deploying functions i functions: ensuring necessary APIs are enabled... ⚠ functions: missing necessary APIs. Enabling now... i env: ensuring necessary APIs are enabled... ⚠ env: missing necessary APIs. Enabling now... i functions: waiting for APIs to activate... i env: waiting for APIs to activate... ✔ env: all necessary APIs are enabled ✔ functions: all necessary APIs are enabled i functions: preparing functions directory for uploading... i functions: packaged functions (X.XX KB) for uploading ✔ functions: functions folder uploaded successfully i starting release process (may take several minutes)... i functions: creating function createSpellingPracticeWord(us-central1)... ✔ functions[createSpellingPracticeWord(us-central1)]: Successful create operation. i functions: creating function ActionsOnGoogleFulfillment(us-central1)... ✔ functions[ActionsOnGoogleFulfillment(us-central1)]: Successful create operation. ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/spelling-practice-1234/overview
後で使用するために、ActionsOnGoogleFulfillment 関数の HTTP エンドポイント URL をメモしておきます。エンドポイントを取得するには、Firebase コンソールを開き、[spelling-practice] プロジェクトをクリックします。Functions ダッシュボードを開いて、関数のエンドポイントを表示します。

必要な関数がすべて追加されました。次に、Cloud Firestore の設定に進みます。
8. Cloud Firestore を有効にする
Cloud Firestore を有効にする必要があります。
Firebase コンソールの [構築] セクションで、[Firestore] をクリックします。次に、[データベースを作成] をクリックします。

Cloud Firestore 内のデータへのアクセスは、セキュリティ ルールによって制御されます。まず、データに基本的なルールを設定して、開始する必要があります。Firebase コンソールの [ルール] タブで、次のルールを追加し、[公開] をクリックします。
次のルールでは、ログインしているユーザーにデータアクセスを制限し、認証されていないユーザーが読み取りや書き込みを行うことを防ぎます。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
//
// WARNING: These rules are insecure! We will replace them with
// more secure rules later in the codelab
//
allow read, write: if request.auth != null;
}
}
}
9. Cloud Firestore にスペルワードのデータを追加する
このステップでは、スペル単語のデータを Cloud Firestore に書き込んで、アシスタント(とゲーム)の単語リストを生成できるようにします。
Cloud Firestore データは、コレクション、ドキュメント、フィールド、サブコレクションに構造化されます。ゲームの各単語は、wordlist という名前の最上位のコレクションに独自のドキュメントとして保存されます。Firestore コレクションの新しいドキュメントごとに、createSpellingPracticeWord 関数がトリガーされ、Dictionary API サービスから単語の詳細が取得されます。
Cloud Firestore コレクションを作成する
- Firebase コンソールで、Cloud Firestore セクションに移動します。
- [+ コレクションを開始] をクリックします。
- [コレクション ID] テキスト ボックスに「
wordlist」と入力し、[次へ] をクリックします。

次に、単語「agreement」のドキュメントを作成します。
- [ドキュメント ID] テキスト ボックスに「
agreement」と入力します。 - [フィールド] テキスト ボックスに「
word」と入力し、[値] テキスト ボックスに「agreement」と入力します。 - [Save] をクリックします。

このドキュメントを Cloud Firestore に追加すると、createSpellingPracticeWord 関数がトリガーされ、単語の定義の詳細が取得されます。単語ごとに新しいドキュメントを作成して、単語を追加します(例: awe、car、true、tell、better、commute など)。
10. Google アシスタントを設定する
以降のセクションでは、Google アシスタントの開発環境をセットアップして Actions プロジェクトを作成する方法について説明します。
Google の権限の設定を確認する
この Codelab で構築するアクションをテストするには、必要な権限を有効にしてシミュレータがアクションにアクセスできるようにする必要があります。権限を有効にする手順は次のとおりです。
- [アクティビティ管理] ページに移動します。
- まだログインしていない場合は、Google アカウントにログインします。
- 次の権限を有効にします。
- ウェブとアプリのアクティビティ
- [ウェブとアプリのアクティビティ] の [Chrome の履歴と Google サービスを使用するサイト、アプリ、デバイスでのアクティビティを含める] チェックボックスをオンにします。

Actions プロジェクトを作成する
Actions プロジェクトは、アクションのコンテナの役割を果たします。この Codelab の Actions プロジェクトを作成する手順は次のとおりです。
- Actions Console を開きます。
- [新しいプロジェクト] をクリックします。
- 利用規約に同意する

- Firebase コンソールを使用して作成した
spelling-practice-codelabを入力または選択します。(この名前は内部参照用です。後でプロジェクトの表示名を設定することもできます)。

- [プロジェクトをインポート] をクリックします。
- [What kind of Action do you want to build?](アクションの種類を選んでください)画面で [Custom](カスタム)カードを選択します。
- [次へ] をクリックします。
- [Blank project](空のプロジェクト)カードを選択します。
- [Start building](始める)をクリックします。
- 表示名に「Spelling Practice」と入力して、[保存] をクリックします。
ユーザーは、「呼び出し」によってアクションとの会話を開始します。たとえば、「OK Google, Spelling Practice につないで」というフレーズで、Spelling Practice というアクションを呼び出すことができます。この場合は、Spelling Practice がアクションの「表示名」です。
アクションを本番環境にデプロイするには表示名が必要です。ただし、アクションのテストでは、表示名を定義する必要はありません。代わりに、シミュレータで「Talk to my test app」(テスト用アプリにつないで)というフレーズを使ってアクションを呼び出すことができます。
フルフィルメントの構成
この Codelab の前半で作成してデプロイした Cloud Functions のイベント ハンドラをアシスタントに接続する必要があります。
フルフィルメントを構成する手順は次のとおりです。
- サイド ナビゲーションで [Webhook] をクリックします。
- フルフィルメント オプションとして [Https endpoint] を選択します。

- 関数のエンドポイントの URL を [HTTPs endpoint] テキスト ボックスに入力し、[Save] をクリックします。

次のセクションでは、Actions Console でメイン呼び出しのプロンプトをカスタマイズします。
メイン呼び出しを設定する
ユーザーがアクションを呼び出した後の動作を定義するには、「メイン呼び出し」を編集する必要があります。
Actions Builder のデフォルトでは、呼び出しがトリガーされたときの応答として汎用のプロンプト「Start building your Action by defining main invocation.」(アクションを構築するには、最初にメイン呼び出しを定義します。」)が返されます。
ユーザーから呼び出されたときにアクションが応答として送信するプロンプトを変更する手順は、次のとおりです。
- ナビゲーションで [Main invocation](メイン呼び出し)をクリックします。

Call your webhookをオンにして、テキスト ボックスにイベント ハンドラ名getSpellingWordListを追加します。- コードエディタで、
speechフィールドのテキストを、次のウェルカム メッセージに置き換えます。Welcome to Spelling Practice
注: プロンプトを編集する際は、YAML 形式または JSON 形式のいずれかを使用できます。
- [Save] をクリックします。
シミュレータでメイン呼び出しをテストする
Actions Console には、アクションのテストに使用できる「シミュレータ」というウェブツールが用意されています。インターフェースでハードウェア デバイスやその設定をシミュレートして、スマートディスプレイ、スマートフォン、スピーカー、KaiOS で実際に実行しているかのようにアクションとの会話ができます。
シミュレータでアクションのメイン呼び出しをテストする手順は、次のとおりです。
- 上部のナビゲーション バーにある [Test](テスト)をクリックしてシミュレータに移動します。
- シミュレータでアクションを呼び出すには、左上の入力欄に「
Talk to Spelling Practice」と入力し、キーボードの Enter キーを押します。

アクションのメイン呼び出しをトリガーすると、カスタマイズされたウェルカム メッセージでアシスタントが応答します。この段階では、アシスタントが挨拶で応答して会話が終了します。
イベントログを表示する
[Test] タブを開くと、右側のパネルに会話の履歴が「イベントログ」として表示されます。イベントログには、会話のターンの間に発生したイベントが表示されます。イベントログを表示するには、イベントの前のグレーのアイコンをクリックします。
作成中のアクションのイベントログは 1 つのみで、ユーザーの入力(「Talk to Spelling Practice」)とアクションからの応答の両方が表示されます。次のスクリーンショットに示されているのは、現時点でのアクションのイベントログです。

11. スペル練習の会話を構築する
前のセクションでは、ユーザーがアクションを呼び出した直後の動作を定義しました。このセクションでは、アクションによる会話の続きを作成します。スペル練習には 4 つのシーンがあり、各シーンは実行する前にアクティブにする必要があります。シーンをアクティブにする方法として最も一般的なのは、そのシーンに遷移するときにアクティブにする方法です。ユーザー入力がシーンのユーザー インテントに一致したら、そのインテントが別のシーンへの遷移をトリガーするときにアクティブにするようにアクションを設定します。
メイン呼び出しから開始シーンに遷移する
このセクションでは、Start という新しいシーンを作成し、ユーザーに Spelling Practice を開始するかどうかを尋ねるプロンプトを送信できるようにします。また、メイン呼び出しからこの Start シーンへの遷移も追加します。
シーンを作成して遷移を追加する手順は次のとおりです。
- 上部のナビゲーションにある [Develop](開発)をクリックし、左側のナビゲーションで [Main invocation] をクリックします。
- 右側にある [Transition](遷移)でプルダウン メニューをクリックし、テキスト ボックスに「
Start」と入力します。

- [追加] をクリックします。これで、
Startというシーンが作成され、アクションがユーザーに歓迎のプロンプトを表示した後にStartシーンに遷移するように設定できました。 - 左側のナビゲーションで [Scenes](シーン)をクリックし、シーンのリストを表示します。
- [Scenes] で [Start](開始)をクリックし、
Startシーンを表示します。 Startシーンの [On Enter](開始時)で [+] をクリックします。- [Send prompts] をオンにします。
speechフィールドの文(Enter the response that users will see or hear...)を、ユーザーに尋ねる質問(Use phonetic alphabet to spell the word. For example alpha for a, bravo for b, charlie for c etc. Do you want to continue?)に置き換えます。
候補ワードとは、ユーザーに提示する応答の候補です。ユーザーはクリックで選択でき、その候補がユーザー入力として処理されます。このセクションでは、先ほど設定したプロンプト(Do you want to play
Spelling Practice
?)を使用して、画面付きデバイスのユーザーをサポートします。
Start シーンのプロンプトに候補ワードを追加する手順は次のとおりです。
Startシーンで、コードエディタの下にある候補をクリックします。この操作で、候補ワードが 1 つ追加されます。titleフィールドで、Suggested Responseを'Yes'に置き換えます。- 同じ形式を使用して、
'No'と'Help with Phonetics'という候補ワードを手入力で追加します。コードの該当部分は次のようになります。 - [Save] をクリックします。

シミュレータでアクションをテストする
ここまでの変更により、メイン呼び出しから Start シーンに遷移し、続行するかどうかをユーザーに尋ねることができるようになりました。シミュレーション画面には候補ワードも表示されます。
シミュレータでアクションをテストする手順は次のとおりです。
- ナビゲーション バーで、[Test] をクリックしてシミュレータに移動します。
- シミュレータでアクションをテストするには、入力欄に「
Talk to Spelling Practice」と入力します。 - Enter キーを押すと、アクションは
Main invocationプロンプトで応答し、先ほど追加したStartシーンのプロンプトを使って「Welcome to Spelling Practice. フォネティック コードを使用して単語をスペルします。たとえば、a はアルファ、b はブラボー、c はチャーリーなどです。続行しますか?」
このやり取りを次のスクリーンショットに示します。

- 候補ワードの [
Yes]、[No]、[Help with Phonetics] のいずれかをクリックして、プロンプトに応答します。(「Yes」(はい)または「No」(いいえ)と音声で応答するか、「Help with Phonetics」(発音のヘルプ)と音声で応答するか、入力欄に「Yes」または「No」または「Help with Phonetics」と入力することもできます)。
プロンプトに応答すると、アクションから入力を認識できないことを示すメッセージ「Sorry, I didn't catch that. Can you try again?」(認識できませんでした。もう一度お願いします)が返されます。アクションがまだ「Yes」や「No」を認識して応答できるようには設定されていないため、入力に一致するのは NO_MATCH インテントとなります。
NO_MATCH システム インテントはデフォルトでは汎用の応答を返しますが、この応答をカスタマイズして、ユーザー入力を理解できなかったことをユーザーに伝えることもできます。ユーザー入力が 3 回連続で一致しない場合、アシスタントはユーザーとアクションの会話を終了します。
no インテントと phonetics インテントを追加する
アクションからの質問にユーザーが応答できるようになったので、次は、アクションがユーザーの応答(「Yes」、「No」、「発音のヘルプ」)を理解できるように設定しましょう。以降のセクションでは、ユーザーが「Yes」、「No」、「Help with Phonetics」と応答したときに一致するユーザー インテントを作成し、それらのインテントを Start シーンに追加します。システム インテント yes を使用し、他のインテントを作成します。
no インテントを作成する
次に、ゲームをプレイしたくないというユーザーの回答を理解し、応答できるようにするため、no インテントを作成します。このインテントを作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- ナビゲーションで [Custom Intents] をクリックし、インテントのリストを開きます。
- インテントのリストの下部にある [+](プラス記号)をクリックします。新しいインテントに
noという名前を付け、Enter キーを押します。 - [no] をクリックして
noインテント ページを開きます。 - [Add training phrases] で、[Enter Phrase] テキスト ボックスをクリックし、次のフレーズを入力します。
NoNI don't wantnope

- [Save] をクリックします。
no インテントを Start シーンに追加する
これで、アクションはユーザーが「No」またはそれに類似する応答(「nope」など)のインテントを返したときに理解できるようになりました。no ユーザー インテントを Start シーンに追加する必要があります。ユーザーが応答しているのは Start プロンプト(「Welcome to Spelling Practice. フォネティック コードを使用して単語をスペルします。たとえば、a はアルファ、b はブラボー、c はチャーリーなどです。続行しますか?」)。
このインテントを Start シーンに追加する手順は次のとおりです。
- ナビゲーションで [Start] シーンをクリックします。
Startシーンで [User intent handling](ユーザー インテントの処理)の横にある [+](プラス記号)をクリックします。- [Intent](インテント)のプルダウンで [no] を選択します。

- [Send prompts] をクリックし、
speechフィールドのテキストを次のメッセージに置き換えます。Good Bye
エディタのコードの該当部分は次のようになります。
candidates:
- first_simple:
variants:
- speech: >-
Goodbye.
- [Transition] のプルダウンで、[End conversation] を選択します。
- [Save] をクリックします。
シミュレータで no インテントをテストする
アクションはこの段階で、ゲームをプレイしたくないというユーザーのインテントを理解し、適切な応答を返せるようになりました。
シミュレータでこのインテントをテストする手順は次のとおりです。
- ナビゲーション バーで、[Test] をクリックします。
- 入力欄に「
Talk to Spelling Practice」と入力し、Enterキーを押します。 - 入力欄に「
No」と入力し、Enter キーを押します。または、候補ワードの [No] をクリックします。

システム YES インテントを Start シーンに追加する
次に、Start シーンに SYSTEM インテント「YES」を追加します。ユーザーが Start プロンプト(「Welcome to Spelling Practice. フォネティック コードを使用して単語をスペルします。たとえば、a はアルファ、b はブラボー、c はチャーリーなどです。続行しますか?」)。
このユーザー インテントを Start シーンに追加する手順は次のとおりです。
- ナビゲーションで [Start] シーンをクリックします。
Startシーンで [User intent handling] の横にある [+](プラス記号)をクリックします。- [All System Intents] で、インテントのプルダウンから [YES] を選択します。

- [Call your webhook] をクリックし、[
event handler] テキスト ボックスを先ほど作成した関数(getSpellingWordList)で更新します。 - [Transition] でプルダウンをクリックし、[End conversation](会話を終了)を選択します。
- [Save] をクリックします。
シミュレータで YES インテントをテストする
アクションはこの段階で、ゲームをプレイしたいというユーザーのインテントを理解し、適切な応答を返せるようになりました。
シミュレータでこのインテントをテストする手順は次のとおりです。
- ナビゲーション バーで、[Test] をクリックします。
- シミュレータでアクションをテストするには、入力欄に「
Talk to Spelling Practice」と入力して Enter キーを押します。 - 入力欄に「
Yes」と入力し、Enter キーを押します。または、候補ワードの [Yes] をクリックします。
アクションは、すべてのスペル練習単語のリストを取得し、セッションに保存します。その後、セッションが終了します。先ほどの設定で YES インテントの遷移として End conversation を選択したためです。
Phonetics インテントを作成する
Phonetics インテントを作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- ナビゲーションで [Custom Intents] をクリックし、インテントのリストを開きます。
- インテントのリストの下部にある [+](プラス記号)をクリックします。新しいインテントに
phoneticsという名前を付け、Enterキーを押します。 phoneticsインテントをクリックして、phoneticsインテント ページを開きます。- [Add training phrases](トレーニング フレーズを追加)セクションで、[Enter Phrase](フレーズを入力)テキスト ボックスをクリックし、次のフレーズを入力します。
how do I spell wordsphoneticshelp me with phoneticsphonetic alphabet

- [Save] をクリックします。
phonetics インテントを Start シーンに追加する
これで、アクションはユーザーが「phonetics」のインテントを返したときに理解できるようになりました。この phonetics ユーザー インテントを Start シーンに追加しましょう。ユーザーが応答しているのは Start のプロンプト(「Welcome to Spelling Practice. フォネティック コードを使用して単語をスペルします。たとえば、a はアルファ、b はブラボー、c はチャーリーなどです。続行しますか?」)。
このユーザー インテントを Start シーンに追加する手順は次のとおりです。
- ナビゲーションで [Start] シーンをクリックします。
Startシーンで [User intent handling] の横にある [+](プラス記号)をクリックします。- インテントのプルダウンで [phonetics] を選択します。

- [Transition] でプルダウンをクリックし、[End conversation](会話を終了)を選択します。
- [Save] をクリックします。
開始シーンからスペル シーンへの遷移
このセクションでは、Spelling という新しいシーンを作成し、ユーザーにフォネティック アルファベットを使用して単語のスペルを尋ねるプロンプトを送信できるようにします。
シーンを作成して遷移を追加する手順は次のとおりです。
- 上部のナビゲーションにある [Develop](開発)をクリックし、次に、左側のナビゲーションで [Start] シーンをクリックします。
- [ユーザーのインテント処理] セクションで
when actions.intent.YES is matchedをクリックし、右側の [遷移] セクションでプルダウン メニューをクリックして、テキスト ボックスにSpellingと入力します。 - [追加] をクリックします。これで、
Spellingというシーンが作成され、YES インテントと一致した後にSpellingシーンに遷移するように設定できました。 - 左側のナビゲーションで [Scenes](シーン)を展開し、シーンのリストを表示します。
- [Scenes] で [Spelling](スペル)をクリックし、
Spellingシーンを表示します。 Spellingシーンの [On Enter](開始時)で [+] をクリックします。- [Call your webhook] をクリックし、イベント ハンドラのテキスト ボックスに「getSpellingWord」と入力します。
- [Send prompts] をオンにします。
speechフィールドの文(Enter the response that users will see or hear...)を {} に置き換えます。実際のプロンプトは Webhook によって入力されます。
候補ワードとは、ユーザーに提示する応答の候補です。ユーザーはクリックで選択でき、その候補がユーザー入力として処理されます。
Spelling シーンのプロンプトに候補ワードを追加する手順は次のとおりです。
Spellingシーンで、コードエディタの下にある候補をクリックします。この操作で、候補ワードが 3 つ追加されます。titleフィールドで、Suggested Responseを'Repeat'に置き換えます。- 同じ形式を使用して、
'Skip'という候補ワードを手入力で追加します。 - 同じ形式を使用して、
'Quit'という候補ワードを手入力で追加します。コードの該当部分は次のようになります。 - [Save] をクリックします。
suggestions:
- title: 'Repeat'
- title: 'Skip'
- title: 'Quit'

Repeat インテントを作成する
repeat インテントを作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- ナビゲーションで [Custom Intents] をクリックし、インテントのリストを開きます。
- インテントのリストの下部にある [+](プラス記号)をクリックします。新しいインテントに
repeatという名前を付け、Enterキーを押します。 repeatインテントをクリックして、definitionインテント ページを開きます。- [Add training phrases](トレーニング フレーズを追加)で、[Enter Phrase](フレーズを入力)テキスト ボックスをクリックし、次のフレーズを入力します。
one more time pleasesay the word againrepeat the wordtell me againrepeat

- [Save] をクリックします。
repeat インテントを Spelling シーンに追加する
これで、アクションはユーザーが「repeat」のインテントを返したときに理解できるようになりました。この repeat ユーザー インテントを Spelling シーンに追加しましょう。ユーザーが応答しているのは Spelling のプロンプト(「Spell the word using phonetic alphabet」)であるためです。
このユーザー インテントを Spelling シーンに追加する手順は次のとおりです。
- ナビゲーションで [Spelling] シーンをクリックします。
Spellingシーンで [User intent handling] の横にある [+](プラス記号)をクリックします。- インテントのプルダウンで [repeat] を選択します。

- [Webhook を呼び出す] をオンにして、イベント ハンドラのテキスト ボックスに「repeatSpellingWord」と入力して、単語の定義を取得します。
- [Send prompts] をオンにします。
speechフィールド(Enter the response that users will see or hear...)の文を「'」に置き換えます。実際のプロンプトは Webhook によって入力されます。
「繰り返しが一致した場合」に候補ワードを追加
- [User Intent handling](ユーザー インテントの処理)の [When Repeat is matched](リピートが一致したとき)で、コードエディタの下にある [suggestions](候補)をクリックします。この操作で、候補ワードが 3 つ追加されます。
titleフィールドで、Suggested Responseを'Skip'に置き換えます。- 同じ形式を使用して、
'Quit'という候補ワードを手入力で追加します。コードは次のスニペットのようになります。
suggestions:
- title: 'Skip'
- title: 'Quit'

- [保存] をクリックします。
definition インテントを作成する
definition インテントを作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- ナビゲーションで [Custom Intents] をクリックし、インテントのリストを開きます。
- インテントのリストの下部にある [+](プラス記号)をクリックします。新しいインテントに
definitionという名前を付け、Enterキーを押します。 definitionインテントをクリックして、definitionインテント ページを開きます。- [Add training phrases](トレーニング フレーズを追加)で、[Enter Phrase](フレーズを入力)テキスト ボックスをクリックし、次のフレーズを入力します。
I would like to know the definitiontell me the definitionwhat does it meanmeaningdefinitionwhat is the definition?

- [Save] をクリックします。
definition インテントを Spelling シーンに追加する
これで、アクションはユーザーが「定義」のインテントを返したときに理解できるようになりました。この definition ユーザー インテントを Spelling シーンに追加しましょう。ユーザーが応答しているのは Spelling のプロンプト(「Spell the word using phonetic alphabet」)であるためです。
このユーザー インテントを Spelling シーンに追加する手順は次のとおりです。
- ナビゲーションで [Spelling] シーンをクリックします。
Spellingシーンで [User intent handling] の横にある [+](プラス記号)をクリックします。- インテントのプルダウンで [definition] を選択します。

- [Call your webhook] をオンにして、イベント ハンドラのテキスト ボックスに「definitionOfSpellingWord」と入力し、単語の定義を取得します。
- [Send prompts] をオンにします。
speechフィールド(Enter the response that users will see or hear...)の文を `` に置き換えます。実際のプロンプトは Webhook によって入力されます。
Webhook レスポンスに候補ワードを追加する
Startシーンで、コードエディタの下にある [suggestions](候補)をクリックします。この操作で、候補ワードが 3 つ追加されます。titleフィールドで、Suggested Responseを'Skip'に置き換えます。- 同じ形式を使用して、
'Quit'という候補ワードを手入力で追加します。コードは次のスニペットのようになります。
suggestions:
- title: 'Skip'
- title: 'Quit'

- [Save] をクリックします。
skip インテントを作成する
skip インテントを作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- ナビゲーションで [Intents] をクリックし、インテントのリストを開きます。
- インテントのリストの下部にある [+](プラス記号)をクリックします。新しいインテントに
skipという名前を付け、Enterキーを押します。 skipインテントをクリックして、skipインテント ページを開きます。- [Add training phrases](トレーニング フレーズを追加)で、[Enter Phrase](フレーズを入力)テキスト ボックスをクリックし、次のフレーズを入力します。
next wordgo nextnextskipskip word

- [Save] をクリックします。
Skip インテントを Spelling シーンに追加する
これで、アクションはユーザーが「スキップ」のインテントを返したときに理解できるようになりました。この skip ユーザー インテントを Spelling シーンに追加しましょう。ユーザーが応答しているのは Spelling のプロンプト(「Spell the word using phonetic alphabet」)であるためです。
このユーザー インテントを Spelling シーンに追加する手順は次のとおりです。
- ナビゲーションで [Spelling] シーンをクリックします。
Spellingシーンで [User intent handling] の横にある [+](プラス記号)をクリックします。- インテントのプルダウンで [skip] を選択します。

- 右側にある [Transition](遷移)でプルダウン メニューをクリックし、[
Spelling] を選択します。

- [Save] をクリックします。
quit インテントを作成する
Quit インテントを作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- ナビゲーションで [Intents] をクリックし、インテントのリストを開きます。
- インテントのリストの下部にある [+](プラス記号)をクリックします。新しいインテントに
Quitという名前を付け、Enterキーを押します。 Quitインテントをクリックして、定義インテント ページを開きます。- [Add training phrases](トレーニング フレーズを追加)で、[Enter Phrase](フレーズを入力)テキスト ボックスをクリックし、次のフレーズを入力します。
I quitGoodbyeCancelExitQuit

- [保存] をクリックします。
Quit インテントを Spelling シーンに追加する
これで、アクションはユーザーが「終了」のインテントを返したときに理解できるようになりました。この quit ユーザー インテントを Spelling シーンに追加しましょう。ユーザーが応答しているのは Spelling のプロンプト(「Spell the word using phonetic alphabet」)であるためです。
このユーザー インテントを Spelling シーンに追加する手順は次のとおりです。
- ナビゲーションで [Spelling] シーンをクリックします。
Spellingシーンで [User intent handling] の横にある [+](プラス記号)をクリックします。- インテントのプルダウンで [quit] を選択します。

- 右側の [Transition](遷移)でプルダウン メニューをクリックし、[
End conversation] を選択します。
- [Save] をクリックします。
phonetic_alphabet 型を作成する
このセクションでは、phonetic_alphabet という新しい型を作成します。この型は、単語のスペルをユーザーが選択できるフォネティック アルファベットの選択肢を指定するために使用します。また、選択肢の類義語が返された場合に備え、それぞれに似ている言葉もいくつか定義します。後のセクションで phonetic_alphabet 型をスロットに追加し、ユーザーの回答を取得できるようにします。
phonetic_alphabet 型を作成する手順は次のとおりです。
- ナビゲーションで [Develop] をクリックします。
- [Types] の [+](プラス記号)をクリックします。
- 「
phonetic_alphabet」と入力してEnterキーを押します。 - [
phonetic_alphabet] をクリックしてオプション ウィンドウを開きます。 - [What kind of values will this Type support?] セクションで、[Words and synonyms] オプションを選択します。
- [Add entries] で、次のエントリと対応する値を入力します。
a | alpha、apple、amsterdam |
b | bravo, butter, baltimore |
c | charlie, cat, casablanca |
d | delta, dog, denmark |
e | echo, edward, edison |
f | foxtrot、fox、florida |
g | golf, george, gallipoli |
h | hotel, harry, havana |
i | india, ink, italia |
j | juliette, johnny, jerusalem |
k | kilo, king, kilogramme |
l | lima, love, london |
m | mike, money, madagascar |
n | november, new york, nancy |
o | oscar、orange、oslo |
p | papa, paris, peter |
q | quebec, queen |
r | romeo, roma, robert |
s | sierra、sugar、santiago |
t | tango、tommy、tripoli |
u | uniform、umbrella、uncle |
v | victor, vinegar, Valencia |
w | whiskey, william, washington |
x | x-ray |
y | yankee, yellow, yorker |
z | zulu、zebra、zurich |
Key-Value テーブルは以下のようになります。

- [Save] をクリックします。
スロットフィルを設定する
次に、Spelling シーンにスロットフィルを設定する必要があります。スロットフィル ロジックを設定する手順は次のとおりです。
- ナビゲーションで [Spelling] シーンをクリックします。
Spellingシーンで、[Slot filling](スロットフィル)の [+](プラス記号)をクリックします。- [Enter slot name](スロット名を入力)欄に、スロット名として「
userresponse」を入力します。 - [Select type](型を選択)プルダウンで、スロットの型として [phonetic_alphabet] を選択します。
- [このスロットは値のリストを受け入れます] をオンにします。
- [This slot is required](このスロットを必須にする)をオンにします。
- [スロット値の書き戻しをカスタマイズ] オプションを選択し、セッション パラメータのテキスト ボックスに「userresponse」と入力します。

- [Save] をクリックします。
Spelling 画面に条件を追加
Spelling シーンに条件を追加する手順は次のとおりです。
- ナビゲーションで [Spelling] シーンをクリックします。
Spellingシーンで [Condition] の横にある [+](プラス記号)をクリックします。- 条件として
scene.slots.status == "FINAL"と入力します - [Call your webhook] をオンにして、イベント ハンドラのテキスト ボックスに verifySpellingWord と入力し、ユーザーの回答を確認します。
- [Send prompts] をオンにします。
speechフィールド(Enter the response that users will see or hear...)の文を {} に置き換えます。実際のプロンプトは Webhook によって入力されます。
Webhook レスポンスに候補ワードを追加する
Startシーンで、コードエディタの下にある [suggestions](候補)をクリックします。この操作で、候補ワードが 3 つ追加されます。titleフィールドで、Suggested Responseを'Next'に置き換えます。- 同じ形式を使用して、
'Quit'という候補ワードを手入力で追加します。コードは次のスニペットのようになります。
suggestions:
- title: 'Next'
- title: 'Quit'

- [Save] をクリックします。
12. シミュレータでスペル練習をテストする
シミュレータでアクションをテストする手順は次のとおりです。
- ナビゲーション バーで、[Test] をクリックしてシミュレータに移動します。
- シミュレータでアクションをテストするには、入力欄に「
Talk to Spelling Practice」と入力します。 - Enter キーを押すと、アクションは
Main invocationプロンプトで応答し、先ほど追加したStartシーンのプロンプトを使って「Welcome to Spelling Practice. フォネティック コードを使用して単語をスペルします。たとえば、a はアルファ、b はブラボー、c はチャーリーなどです。続行しますか?」 - 「はい」と話しかけて続行します
- シミュレータが単語の音を再生してスペルを読み上げる
- 発音記号を使用して単語のスペルを入力できます。たとえば、「better」の場合は、「bravo echo tango tango echo romeo」と入力または発言します。
- シミュレータは、正解または不正解のいずれかの回答を返します。
- 次の単語に進むには「次」と、ゲームループを終了するには「終了」と発言します。
13. 完了
これで、ゲーム「スペル練習」を正常にビルドできました。
Cloud Firestore、Cloud Functions、Google アシスタント Action Builder を使用してゲームを構築するために必要な主な手順について説明しました。
学習した内容
- Cloud Firestore を操作する方法
- スロットを使用してユーザーからデータを収集する方法
- ユーザーの入力を処理して応答を返す
- 条件を使用してシーンにロジックを追加する方法
- ゲームループを追加する方法
その他の学習リソース
Google アシスタントのアクションの構築については、以下のリソースをご覧ください。
- Google アシスタントのアクションの開発に関するドキュメント
- Actions on Google GitHub ページのサンプルコードとライブラリ
- Google アシスタントを使用するデベロッパー向けの Reddit 公式コミュニティ
- 会話の設計ガイドライン(会話型アクションに関するベスト プラクティスとガイドライン)
- Cloud Firestore の概要
プロジェクトをクリーンアップする(推奨)
料金が発生するのを避けるため、使用する予定のないプロジェクトは削除することをおすすめします。この Codelab で作成したプロジェクトを削除する手順は次のとおりです。
- Firebase プロジェクトとリソースを削除する手順については、プロジェクトのシャットダウン(削除)をご覧ください。
注意: Google Cloud コンソールの [設定] ページで、削除するプロジェクトが正しく選択されていることを確認してください。
- 省略可: プロジェクトを Actions Console からすぐに削除したい場合は、プロジェクトを削除するの手順を完了してください。この手順で削除していないプロジェクトは、約 30 日後に自動的に削除されます。
Twitter で @ActionsOnGoogle と @Firebase をフォローして最新情報をチェックしてください。また、作成したアクションについて、ハッシュタグ #GoogleIO でツイートしてください。