Actions Builder를 사용하여 Google 어시스턴트용 Interactive Canvas 작업 빌드하기

Actions on Google 개발자 플랫폼을 사용하면 스마트 스피커, 스마트폰, 자동차, TV, 헤드폰 등 10억 대 이상의 기기에서 Google의 가상 개인 비서인 Google 어시스턴트의 기능을 확장하는 소프트웨어를 만들 수 있습니다. 사용자는 Google 어시스턴트와의 대화를 통해 식료품 구매, 택시 예약과 같은 작업을 할 수 있습니다. 현재 사용 가능한 항목의 전체 목록은 작업 디렉터리를 참고하세요. 개발자는 Actions on Google을 사용하여 사용자와 타사 서비스 간의 즐겁고 유용한 대화 환경을 쉽게 만들고 관리할 수 있습니다.

이 Codelab은 고급 모듈로, 이미 Google 어시스턴트 작업을 빌드한 경험이 있는 개발자를 대상으로 합니다. 이전에 Actions on Google을 사용하여 개발해 본 적이 없다면 Google의 입문 Codelab(레벨 1레벨 2)에 따라 플랫폼을 숙지하는 것을 적극 권장합니다. 이 모듈에서는 작업의 기능을 확장하여 잠재고객을 확대하는 데 도움이 되는 일련의 기능을 안내합니다.

이 Codelab에서는 Google 어시스턴트에 내장된 프레임워크인 Interactive Canvas를 사용하여 대화형 작업에 전체 화면 게임을 추가합니다. 게임은 대화에서 어시스턴트가 사용자에게 응답으로 전송하는 대화형 웹 앱입니다. 이 웹 앱을 받은 사용자는 스마트 디스플레이나 Android 휴대기기에서 음성 입력이나 텍스트 입력을 통해 게임을 플레이할 수 있습니다.

이 Codelab을 진행하면서 전체 게임을 직접 빌드하는 대신 부분적으로 사전 빌드된 Snow Pal이라는 게임을 배포하고 게임의 로직을 추가합니다. Snow Pal은 전통적인 행맨 게임의 변형입니다. 특정 단어를 나타내는 빈 공간이 여러 개 제시되면 단어 안에 들어갈 만한 글자를 추측하는 게임입니다. 추측이 틀릴 때마다 Snow Pal이 조금씩 더 녹습니다. Snow Pal이 완전히 녹기 전에 단어를 알아내면 승리입니다.

af9931bb4d507e39.png

그림 1. 일부 완료된 Snow Pal 게임

빌드할 항목

이 Codelab에서는 Interactive Canvas를 사용하여 작업을 빌드합니다. 작업에 포함할 기능은 다음과 같습니다.

  • 전체 화면으로 제공되며 사용자가 음성으로 플레이할 수 있는 단어 게임
  • 사용자가 눌러 게임을 시작할 수 있는 버튼
  • 사용자가 눌러 게임을 다시 플레이할 수 있는 버튼

이 Codelab을 통해 완성한 작업에는 다음과 같은 대화 흐름이 생성됩니다.

어시스턴트: Welcome to Snow Pal! Would you like to start playing the game?

사용자: Yes

어시스턴트: Try guessing a letter in the word or guessing the word.

사용자: I guess the letter E

어시스턴트: Let's see if your guess is there...E is right. Right on! Good guess.

사용자는 게임이 끝날 때까지 계속해서 글자 또는 단어 자체를 추측합니다.

학습할 내용

  • Interactive Canvas 작업을 빌드하고 배포하는 방법
  • 사용자의 음성 및 터치 입력을 기반으로 단어 게임을 업데이트하는 방법
  • 다양한 메서드를 사용하여 웹 앱에 데이터를 전달하는 방법
  • Interactive Canvas 작업을 디버그하는 방법

필요한 항목

이 Codelab에 필요한 항목은 다음과 같습니다.

  • 웹브라우저(예: Chrome)
  • 원하는 IDE/텍스트 편집기
  • 시스템에 NodeJS, npm, git 설치

이 Codelab에서 사용되는 코드를 이해하려면 자바스크립트(ES6)를 능숙하게 다룰 줄 알아야 합니다.

선택사항: 전체 샘플 코드 가져오기

이 Codelab에서는 불완전한 버전의 샘플을 단계별로 빌드합니다. 원하는 경우 GitHub 저장소에서 완성된 샘플을 가져올 수도 있습니다.

Interactive Canvas는 Google 어시스턴트 위에 구축된 프레임워크로, 이를 통해 전체 화면 영상과 애니메이션을 대화형 작업에 추가할 수 있습니다.

Interactive Canvas를 사용하는 작업은 일반적인 대화형 작업과 유사하게 작동합니다. 하지만 Interactive Canvas 작업에는 전체 화면 웹 앱을 여는 기기에 응답을 보낼 수 있는 추가 기능이 있습니다.

사용자는 대화가 끝날 때까지 음성이나 터치를 통해 웹 앱에 입력합니다.

fa63a599f215aa81.gif

그림 2. Interactive Canvas로 빌드한 작업

이 Codelab에서 프로젝트는 다음과 같은 세 가지 주요 부분으로 구성됩니다.

  • 웹 앱: 웹 앱 파일에는 웹 앱의 영상 및 애니메이션용 코드는 물론, 사용자의 입력을 기반으로 웹 앱을 업데이트하는 로직이 포함됩니다.
  • 대화형 작업: 대화형 작업에는 사용자의 입력을 인식하고 처리하며 입력에 응답하는 대화 로직이 포함됩니다.
  • 웹훅: 웹훅은 게임의 로직을 처리합니다. 이 Codelab에서는 웹훅을 게임 서버로 생각하면 됩니다.

이 Codelab의 각 섹션에서는 웹 앱, 대화형 작업, 웹훅을 수정하여 Interactive Canvas 작업에 기능을 추가합니다.

Snow Pal 작업의 대화형 작업, 웹훅, 웹 앱은 개략적으로 다음과 같이 작동합니다.

  1. 대화형 작업이 사용자에게 단어의 글자나 전체 단어를 추측하라는 메시지를 표시합니다.
  2. 사용자가 스마트 디스플레이에서 Snow Pal 웹 앱에 "글자 i"라고 말합니다.
  3. 사용자의 입력이 Actions Builder 또는 Actions SDK 프로젝트에 정의된 대화형 작업으로 라우팅됩니다.
  4. 대화형 작업이 사용자의 입력을 처리하고 입력한 내용에 따라 웹훅에서 웹 앱을 업데이트하는 로직을 트리거하거나 메타데이터를 전송하여 웹 앱을 직접 업데이트합니다.
  5. 웹 앱이 업데이트되어 단어에 글자가 들어간 위치를 표시하고 사용자에게 다시 추측하도록 요청합니다.

'Interactive Canvas 인프라 이해' 섹션에서 Interactive Canvas의 작동 방식을 자세히 알아볼 것입니다. 기본사항을 알아봤으니 이제 이 Codelab을 위한 환경 설정을 시작할 수 있습니다.

Google 권한 설정 확인하기

이 Codelab용으로 빌드한 작업을 테스트하려면 Actions 콘솔 시뮬레이터가 작업에 액세스할 수 있도록 필요한 권한을 사용 설정해야 합니다. 권한을 사용 설정하려면 다음 단계를 따르세요.

  1. 활동 제어 페이지로 이동합니다.
  2. 필요한 경우 Google 계정으로 로그인합니다.
  3. 다음 권한을 사용 설정합니다.
  • 웹 및 앱 활동
  • 웹 및 앱 활동에서 Chrome 방문 기록 및 Google 서비스를 사용하는 사이트, 앱, 기기에서 이루어진 활동 포함 옆의 체크박스를 선택합니다.

gactions 명령줄 인터페이스 설치하기

이 Codelab에서는 gactions 명령줄 인터페이스(CLI) 도구를 사용하여 Actions 콘솔과 로컬 파일 시스템 간에 작업 프로젝트를 동기화합니다.

gactions CLI를 설치하려면 gactions 명령줄 도구 설치 섹션의 안내를 따르세요.

Firebase 명령줄 인터페이스 설치하기

Firebase 명령줄 인터페이스(CLI)를 사용하면 Cloud Functions에 작업 프로젝트를 배포하고 웹 앱을 호스팅할 수 있습니다.

이 Codelab에서는 npm을 사용하여 Firebase CLI를 설치합니다. 일반적으로 Node.js와 함께 제공되는 npm을 설치해야 합니다.

CLI를 설치하거나 업그레이드하려면 터미널을 열고 다음 npm 명령어를 실행합니다.

npm install -g firebase-tools

CLI가 제대로 설치되었는지 확인하려면 다음 명령어를 실행합니다.

firebase --version

Cloud Functions에 필요한 최신 기능이 모두 있을 수 있도록 Firebase CLI의 버전이 8 이상인지 확인합니다. 버전이 낮은 경우 npm install -g firebase-tools를 실행하여 업그레이드합니다.

Firebase에 로그인하려면 다음 명령어를 실행합니다.

firebase login

Firebase에 로그인할 때는 작업 프로젝트를 만들 때 사용하는 것과 동일한 Google 계정을 사용해야 합니다.

저장소 클론하기

이 섹션에서는 Codelab에 필요한 파일을 클론합니다. 파일을 가져오려면 다음 단계를 따르세요.

  1. 터미널을 열고 일반적으로 코딩 프로젝트를 저장하는 디렉터리로 변경합니다. 저장 디렉터리가 없다면 홈 디렉터리로 변경합니다.
  2. 이 저장소를 클론하려면 터미널에서 다음 명령어를 실행합니다.
git clone https://github.com/actions-on-google/actions-builder-canvas-codelab-nodejs

start/ 디렉터리를 엽니다. 저장소에는 다음과 같은 중요 디렉터리가 포함되며, 이 디렉터리를 사용해 작업합니다.

  • public/: 이 디렉터리는 웹 앱의 HTML, CSS, 자바스크립트 코드를 포함합니다.
  • sdk/custom/: 이 디렉터리는 대화형 작업(장면, 인텐트, 유형)의 로직을 포함합니다.
  • sdk/webhooks/: 이 디렉터리는 웹훅으로, 게임 로직을 포함합니다.

4864e8047bb2c8f6.png

그림 3. start 디렉터리 코드의 구조

이 섹션에서는 작업 프로젝트를 만들어 구성하고, 클론한 저장소의 코드를 gactions CLI를 사용해 Actions 콘솔에 푸시하고, 웹 앱과 웹훅을 배포합니다.

작업 프로젝트 만들기

작업 프로젝트는 작업을 담는 컨테이너 역할을 합니다. 이 Codelab에서 사용할 작업 프로젝트를 만들려면 다음 단계를 따르세요.

  1. Actions 콘솔을 엽니다.
  2. New Project를 클릭합니다.
  3. 프로젝트 이름(예: canvas-codelab)을 입력합니다. 이는 내부 참고용 이름으로, 나중에 프로젝트의 외부 이름을 설정할 수 있습니다.

7ea69f1990c14ed1.png

  1. Create Project를 클릭합니다.
  2. 어떤 종류의 작업을 빌드하고 싶으신가요? 화면에서 Game 카드를 선택합니다.
  3. Next를 클릭합니다.
  4. Blank project 카드를 선택한 다음 Start building을 클릭합니다.

작업의 프로젝트 ID 저장하기

프로젝트 ID는 작업의 고유 식별자입니다. 이 Codelab의 여러 단계에서 프로젝트 ID가 필요합니다.

프로젝트 ID를 검색하려면 다음 단계를 따르세요.

  1. Actions 콘솔에서 오른쪽 상단의 세로 점 3개 메뉴를 클릭합니다.
  2. Project Settings를 클릭합니다.

6f59050b85943073.png

  1. 프로젝트 ID를 복사합니다.

결제 계정 연결하기

나중에 Cloud Functions를 사용하여 이 Codelab에 처리를 배포하려면 결제 계정을 Google Cloud의 프로젝트와 연결해야 합니다. 이미 결제 계정이 있다면 다음 단계를 무시해도 됩니다.

결제 계정을 프로젝트에 연결하려면 다음 단계를 따르세요.

  1. Google Cloud Platform 결제 페이지로 이동합니다.
  2. 결제 계정 추가를 클릭합니다.
  3. 결제 정보를 입력하고 무료 체험판 시작하기 또는 결제 제출 및 사용 설정을 클릭합니다.
  4. 페이지 상단에서 내 프로젝트 탭을 클릭합니다.
  5. Codelab 작업 프로젝트 옆의 작업 아래에 있는 점 3개를 클릭합니다.
  6. 결제 변경을 클릭합니다.
  7. 드롭다운 메뉴에서 구성한 결제 계정을 선택합니다. 계정 설정을 클릭합니다.

요금이 청구되지 않도록 하려면 이 Codelab 끝에 있는 '다음 단계' 페이지에서 '프로젝트 지우기' 섹션의 단계를 따르세요.

웹 앱 배포하기

이 섹션에서는 Firebase CLI를 사용하여 웹 앱(Snow Pal 게임)을 배포합니다. 배포한 후에는 웹 앱의 URL을 검색하여 브라우저에서 게임이 어떻게 보이는지 확인할 수 있습니다.

웹 앱을 배포하려면 다음 단계를 따르세요.

  1. 터미널에서 start/ 디렉터리로 이동합니다.
  2. 다음 명령어를 실행합니다. 이때 {PROJECT_ID}를 프로젝트 ID로 바꿉니다.
firebase deploy --project {PROJECT_ID} --only hosting

몇 분 후에 'Deploy complete!'가 표시되어 Snow Pal 웹 앱이 Firebase에 배포되었음을 나타냅니다.

브라우저에서 Snow Pal 게임을 보려면 다음 단계를 따르세요.

  1. 터미널 출력에서 제공되는 호스팅 URL을 가져옵니다. URL 형식은 다음과 같습니다. https://{PROJECT_ID}.web.app
  1. 브라우저에 URL을 붙여넣습니다. Start Game 버튼이 있는 Snow Pal 게임 시작 화면이 표시됩니다.

68429faae5141ed0.png

작업 프로젝트에 웹 앱 URL 및 프로젝트 ID 추가하기

그런 다음 actions.intent.MAIN.yaml 파일에 웹 앱 URL과 프로젝트 ID를 추가합니다. 웹 앱 URL을 추가하면 어느 URL에 데이터를 전송할지를 대화형 작업에 알릴 수 있고, settings.yaml에 프로젝트 ID를 추가하면 다운로드한 파일을 Actions 콘솔의 올바른 프로젝트에 푸시할 수 있습니다.

웹 앱 URL과 프로젝트 ID를 추가하려면 다음 단계를 따르세요.

  1. 텍스트 편집기에서 start/sdk/custom/global/actions.intent.MAIN.yaml 파일을 엽니다.
  2. url 필드에서 자리표시자 문자열을 웹 앱 URL로 바꿉니다.
  3. 텍스트 편집기에서 start/sdk/settings/settings.yaml 파일을 엽니다.
  4. projectId 필드에서 자리표시자 문자열을 프로젝트 ID로 바꿉니다.

Actions 콘솔에 프로젝트 푸시하기

Actions 콘솔을 로컬 프로젝트로 업데이트하려면 작업 프로젝트를 Actions 콘솔에 푸시해야 합니다. 방법은 다음과 같습니다.

  1. sdk 디렉터리로 변경합니다.
cd sdk/
  1. 로컬 파일 시스템의 구성을 Actions 콘솔에 복사하려면 다음 명령어를 실행합니다.
gactions push

웹훅 배포하기

gactions push를 실행할 때 시작 웹훅 코드를 Actions 콘솔로 가져왔습니다. 이 Codelab의 나머지 부분에 사용할 웹훅 코드를 Actions 콘솔 내에서 편집해도 됩니다. 이때 Actions 콘솔에서 웹훅을 배포할 수 있습니다.

웹훅을 배포하려면 다음 단계를 따르세요.

  1. Actions 콘솔의 탐색 메뉴에서 Develop을 클릭합니다.
  2. 탐색 메뉴에서 Webhook 탭을 클릭합니다.
  3. Deploy Fulfillment를 클릭합니다.

Cloud Functions가 처리를 프로비저닝하고 배포하는 데 몇 분 정도 걸릴 수 있습니다. 코드 편집기 위에 Cloud Function deployment is progress...라는 메시지가 표시됩니다. 코드가 성공적으로 배포되면 메시지가 Your Cloud Function deployment is up to date로 바뀝니다.

시뮬레이터에서 테스트하기

이제 작업이 웹 앱에 연결되어 있습니다. Actions 콘솔 시뮬레이터를 사용하여 작업을 호출할 때 웹 앱이 표시되는지 확인할 수 있습니다.

작업을 테스트하려면 다음 단계를 따르세요.

  1. Actions 콘솔의 탐색 메뉴에서 Test를 클릭합니다.
  2. Input 필드에 Talk to Snow Pal sample을 입력하고 Enter 키를 누릅니다.
  3. Input 필드에 Yes를 입력하고 Enter 키를 누릅니다. 또는 화면 가운데에 있는 Start Game 버튼을 클릭합니다.

37f7bc4e550d817c.png

글자를 추측하거나 단어를 추측하는 로직을 아직 구성하지 않았기 때문에 단어나 글자를 추측하면 '...Incorrect. Keep on trying! It looks like we need to add more functionality to have this work properly.'라는 응답을 받게 됩니다.

이 프로젝트에서 기능은 대화형 작업, 웹 앱, 웹훅의 세 가지 주요 구성요소로 분류됩니다. 이는 작업을 설정할 수 있는 한 가지 모델로, Interactive Canvas의 핵심 기능을 강조하고자 이렇게 분류됩니다.

다음 섹션에서는 대화형 작업, 웹훅, 웹 앱이 연동되는 방식과 이외의 중요한 Interactive Canvas 요소에 관해 자세히 설명합니다.

대화형 작업

작업의 대화형 작업 구성요소는 사용자 입력을 인식 및 처리하고, 적절한 장면에 전송하는 작업을 처리합니다. 장면에서는 사용자에게 전달할 응답이 구성됩니다. 예를 들어 사용자가 Snow Pal 게임에서 "글자 e"라고 말하면 대화형 작업이 글자를 인텐트 매개변수로 추출하여 적절한 게임 로직에 전달하고, 로직에서는 추측이 옳은지 결정하여 결과에 따라 웹 앱을 업데이트합니다. 이 대화 로직은 Actions 콘솔의 웹 기반 IDE인 Actions Builder 내에서 보고 수정할 수 있습니다. 다음 스크린샷은 Actions Builder 내 대화형 작업의 일부입니다.

91d1c5300f015ff9.png

그림 4. Actions Builder의 Main invocation 시각화

이 스크린샷은 작업의 Main invocation을 보여줍니다. 여기에서 사용자가 "Hey Google, Snow Pal 샘플에 연결해 줘"라는 문구를 말하는 경우 인텐트와 연결됩니다. 사용자가 작업을 호출하면 Main invocation은 웹 앱의 URL이 포함된 canvas 응답으로 메시지를 전송합니다.

작업의 첫 번째 canvas 응답에는 웹 앱 URL이 포함되어야 합니다. 이 응답은 사용자 기기에서 URL 주소의 웹 앱을 렌더링하도록 어시스턴트에 알립니다. Actions Builder의 추가 canvas 응답에는 true로 설정된 send_state_data_to_canvas_app 필드가 포함될 수 있습니다. 이 필드는 인텐트와 연결될 때 인텐트 이름과 매개변수 값을 웹 앱에 전송하며, 웹 앱은 사용자 입력의 이 데이터를 기반으로 업데이트됩니다.

웹훅

이 Codelab에서는 웹훅에 게임 로직이 포함되어 있습니다. 웹훅을 게임 서버라고 생각하면 됩니다. 게임 로직에는 사용자 추측의 정답 여부나 사용자의 승패를 결정하는 요소 및 결과에 따라 응답을 생성하는 요소 등이 있습니다. Actions Builder 내에서 웹훅을 수정할 수 있습니다.

작업이 게임 로직을 실행해야 하는 경우 Actions Builder가 웹훅을 호출합니다. 예를 들어 Game 장면의 guess 인텐트가 guess 핸들러에 웹훅 호출을 실행하면 사용자의 추측이 옳은지를 결정하는 로직이 실행됩니다. 웹훅은 웹 앱 파일에 매핑되고 웹을 적절하게 업데이트하는 Canvas 응답을 핸들러 내에 포함할 수 있습니다.

웹 앱

ca564ef59e1003d4.png

그림 5. Interactive Canvas 작업에서 대화형 작업, 웹훅, 웹 앱 사이에 발생하는 상호작용의 시각화

웹 앱 파일에는 웹 앱의 영상 및 애니메이션용 코드는 물론, 사용자의 입력을 기반으로 웹 앱을 업데이트하는 로직이 포함됩니다. 텍스트 편집기에서 웹 앱 파일을 수정하고 이 변경사항을 Firebase CLI를 사용하여 배포합니다.

대화형 작업과 웹 앱 간의 통신

사용자 입력에 따라 웹 앱이 업데이트될 수 있도록 대화형 작업과 웹 앱 간에 통신을 사용 설정해야 합니다. 예를 들어 사용자가 "글자 f"라고 말하면

대화형 작업이 웹 앱에 글자 'f'를 제공해야 웹 앱이 적절하게 업데이트될 수 있습니다. 대화형 작업을 통한 사용자 입력을 웹 앱에 전달하려면 Interactive Canvas API로 로드해야 합니다.

이 API의 스크립트는 Snow Pal 게임의 기본 HTML 파일인 /public/index.html에 포함됩니다. 이 파일은 다음과 같은 스크립트에서 UI의 모양과 로드 방식을 정의합니다.

index.html

<!-- Load Assistant Interactive Canvas API -->
 <script type="text/javascript" src="https://www.gstatic.com/assistant/interactivecanvas/api/interactive_canvas.min.js"></script>

사용자 입력을 기반으로 웹 앱을 업데이트하려면 웹 앱 파일에서 콜백도 등록하고 구성해야 합니다. 콜백을 사용하면 웹 앱이 대화형 작업의 정보나 요청에 응답할 수 있습니다.

/public/js/action.js에는 콜백을 선언하고 등록하는 Action이라는 클래스가 사전 구성되어 있습니다. Action 클래스는 Interactive Canvas API의 래퍼입니다. scene.jscreate() 함수를 사용하여 웹 앱을 생성하면 다음 스니펫과 같이 새 Action 인스턴스가 생성되고 setCallbacks()가 호출됩니다.

scene.js

// Set assistant at game level.
this.assistant = new Action(this);
// Call setCallbacks to register assistant action callbacks.
this.assistant.setCallbacks();

setCallbacks() 함수는 /public/js/action.jsAction 클래스에서 정의됩니다. 이 함수는 콜백을 선언하고 게임 생성 시 Interactive Canvas API에 콜백을 등록합니다.

  setCallbacks() {
    // Declare the Interactive Canvas action callbacks.
    const callbacks = {
      onUpdate: (data) => {
     ...
    // Called by the Interactive Canvas web app once web app has loaded to
    // register callbacks.
    this.canvas.ready(callbacks);
  }

setCallbacks() 함수는 Canvas 응답을 전송할 때마다 호출되는 onUpdate() 콜백을 선언합니다.

다음 섹션에서는 대화형 작업의 데이터를 웹 앱에 전달하도록 이 프로젝트의 특정 코드를 구성하는 방법을 설명합니다.

사용자 입력을 기반으로 웹 앱 업데이트하기

이 Codelab에서는 사용자의 입력에 따라 웹 앱을 업데이트하는 데 명령어 맵을 사용합니다. 예를 들어 Welcome 장면에서 start_game 인텐트와 연결되면 프롬프트에 포함된 canvas 응답이 웹 앱으로 전송됩니다. onUpdate()canvas 응답의 메타데이터를 파싱하고 START_GAME 명령어를 호출합니다. 그러면 scene.js에서 start() 함수가 호출되고 웹 앱이 업데이트되어 새 게임 세션이 시작됩니다.

scene.jsstart() 함수는 updateCanvasState() 함수를 호출하고, 이 함수는 setCanvasState()라는 메서드를 사용하여 웹훅이 액세스할 수 있는 상태 데이터를 추가합니다.

updateCanvasState() 메서드는 모든 명령어(Codelab을 진행하면서 이 명령어를 추가하게 됨)의 끝에 호출되며 웹 앱의 상태를 업데이트합니다. updateCanvasState()가 호출될 때마다 현재 상태에 따라 displayedWordincorrectGuesses가 업데이트됩니다.

scene.js

...
  updateCanvasState() {
    window.interactiveCanvas.setCanvasState({
      correctWord: this.word.text,
      displayedWord: this.word.displayText.text,
      incorrectGuesses: this.incorrectGuesses,
    });

그러면 업데이트된 상태가 다음번 대화에서 사용될 수 있습니다. 웹훅에서 conv.context.canvas.state를 통해 이 상태에 액세스합니다. 다음의 코드 스니펫과 같습니다.

index.js

...
  let displayedWord = conv.context.canvas.state.displayedWord;
...

이 섹션에서는 사용자가 단어의 글자 또는 단어 자체를 추측하도록 하는 guess 기능을 작업에 추가합니다.

대화형 작업

'시뮬레이터에서 테스트' 섹션에서 'It looks like we need to add more functionality to have this work properly.'라는 응답을 받았습니다. 이제 웹훅만 호출하도록 Actions 콘솔에서 이 프롬프트를 삭제할 수 있습니다(Game 장면에서 guess 인텐트와 연결되면 웹훅을 호출하도록 이미 구성되어 있음).

guess 인텐트와 연결될 때의 정적 프롬프트를 삭제하려면 다음 단계를 따르세요.

  1. Actions 콘솔의 탐색 메뉴에서 Scenes를 클릭합니다.
  2. Game을 클릭하여 Game 장면으로 이동합니다.
  3. Custom intent handling에서 When guess is matched를 클릭합니다. Send prompts를 선택 해제하여 프롬프트를 삭제합니다.
  4. Save를 클릭합니다.

웹훅

이 섹션에서는 사용자의 옳은 추측과 틀린 추측을 웹 앱 파일의 로직과 매핑한 후 결과에 따라 웹 앱을 업데이트하는 로직으로 웹훅을 업데이트합니다. 웹훅에서 guess 인텐트 핸들러가 이미 구성되어 있으므로 이 인텐트에 웹 앱을 업데이트하는 로직을 트리거할 Canvas 응답을 추가하기만 하면 됩니다.

웹훅을 업데이트하려면 다음 단계를 따르세요.

  1. Actions 콘솔의 탐색 메뉴에서 Webhook을 클릭합니다.
  2. index.jsguess 핸들러 아래에서 다음 코드를 추가합니다.

index.js(섹션 A):

// Add SECTION A `conv.add(new Canvas({` content here
conv.add(new Canvas({
  data: {
    command: 'CORRECT_ANSWER',
    displayedWord: displayedWord
  },
}));

index.js(섹션 B):

// Add SECTION B `conv.add(new Canvas({` content here
conv.add(new Canvas({
  data: {
    command: 'INCORRECT_ANSWER',
  },
}));
  1. Save Fulfillment를 클릭합니다.
  2. Deploy Fulfillment를 클릭합니다. 배포가 완료되면 편집기 위에 Your Cloud Function deployment is up to date.라는 메시지가 표시됩니다.

웹 앱

이제 CORRECT_ANSWER 명령어와 INCORRECT_ANSWER 명령어를 처리하도록 웹 앱을 구성할 수 있습니다.

  1. 텍스트 편집기에서 public/js/action.js를 엽니다.
  2. CORRECT_ANSWER 명령어와 INCORRECT_ANSWER 명령어를 처리하도록 웹 앱을 업데이트합니다.

action.js(섹션 C):

// Add SECTION C `CORRECT_ANSWER: (params) => {` content here
      CORRECT_ANSWER: (params) => {
        this.gameScene.correctAnswer(params);
      },
      INCORRECT_ANSWER: (params) => {
        this.gameScene.incorrectAnswer();
      },
  1. 다음 명령어를 실행하여 웹 앱을 업데이트합니다.
firebase deploy --project {PROJECT_ID} --only hosting

시뮬레이터에서 작업 테스트하기

이제 작업이 사용자 추측의 정답 여부를 인식하고 결과에 따라 웹 앱을 업데이트할 수 있습니다.

작업을 테스트하려면 다음 단계를 따르세요.

  1. 탐색 메뉴에서 Test를 클릭합니다.
  2. Input 필드에 Talk to Snow Pal sample을 입력하고 Enter 키를 누릅니다.
  3. Input 필드에 Yes를 입력하고 Enter 키를 누릅니다. 또는 Yes 버튼을 클릭합니다.
  4. 추측할 글자를 입력란에 입력하고 Enter 키를 누릅니다.

1c2c2d59a418642b.png

코드 이해하기

이전 섹션에서는 사용자가 게임에서 글자를 추측하고 추측 내용이 단어나 Snow Pal에 반영된 것을 확인할 수 있는 코드를 추가했습니다. 개략적으로 말하면 guess 인텐트와 연결될 때 Actions Builder에서 웹훅을 호출하고, 이에 따라 웹 앱에 데이터가 전달되어 적절하게 웹 앱이 업데이트됩니다. 예를 들어 사용자가 Snow Pal 게임에서 추측한 글자가 단어에 있다면 웹 앱이 업데이트되어 이 글자를 단어의 올바른 위치에 배치하여 보여줍니다.

Interactive Canvas를 사용하는 작업의 경우, 웹훅에서 웹 앱으로 데이터가 전달되는 일반적인 흐름은 다음과 같습니다.

  1. 사용자 입력이 Canvas 응답이 포함된 인텐트와 연결됩니다.
  2. 대화형 작업 또는 웹훅이 onUpdate() 콜백을 트리거하는 Canvas 응답을 전송합니다.
  3. onUpdate() 콜백이 웹 앱을 적절하게 업데이트하는 맞춤 로직에 매핑됩니다.

이 프로젝트의 경우 코드는 다음과 같이 작동합니다.

  1. 사용자 입력이 guess 인텐트와 연결되면 Actions Builder가 사용자 입력의 글자를 매개변수로 추출합니다.
  2. Actions Builder가 웹훅의 guess 핸들러를 호출합니다. 여기에는 사용자가 추측한 글자가 단어에 있는지를 결정하는 로직이 포함되어 있습니다.
  3. guess 핸들러에는 Canvas 응답 두 개가 포함됩니다. 하나는 추측한 글자가 옳을 때 실행되고, 다른 하나는 글자가 틀렸을 때 실행됩니다. 각 Canvas 응답이 적절한 데이터, 즉 CORRECT_ANSWER 명령어나 INCORRECT_ANSWER 명령어를 웹 앱에 전달합니다.
  4. Canvas 응답의 data 필드 내에 포함된 데이터가 action.jsonUpdate() 메서드에 전달됩니다. onUpdate()scene.js의 명령어 맵에서 적절한 명령어를 호출합니다.
  5. 명령어 맵이 scene.jscorrectAnswer() 함수와 incorrectAnswer() 함수에 매핑됩니다. 이러한 함수는 사용자의 추측을 반영하여 웹 앱을 적절하게 업데이트하고 setCanvasState()를 호출하여 웹 앱에서 웹훅으로 상태 데이터를 전송합니다.

이 섹션에서는 사용자의 승패를 결정하는 로직과 사용자의 결과에 따라 웹 앱 이미지를 업데이트하는 로직이 포함된 승리/패배 기능을 작업에 추가합니다.

대화형 작업

사용자의 승패를 처리하는 기능은 guess 인텐트에서 구성되므로 Actions Builder에서 추가로 구성할 필요가 없습니다.

웹훅

이 섹션에서는 사용자가 게임에 승리 또는 패배했을 때 이를 처리하고 게임을 승리 또는 패배 화면으로 적절히 업데이트하는 웹 앱 로직에 매핑하는 로직으로 웹훅을 업데이트합니다.

웹훅을 업데이트하려면 다음 단계를 따르세요.

  1. Actions 콘솔의 탐색 메뉴에서 Webhook을 클릭합니다.
  2. index.jsguess 핸들러 아래에서 다음 코드를 추가합니다.

index.js(섹션 D):

// Add SECTION D `if (userHasWon)` content here
    if (userHasWon) {
      conv.add(`<speak>Let's see if your guess is there...<break
        time='2500ms'/> ${guess} is right. That spells ${correctWord}!
        ${randomArrayItem(WIN_RESPONSES)}</speak>`);
      conv.add(new Canvas({
        data: {
          command: 'WIN_GAME',
          displayedWord: displayedWord
        },
      }));
      conv.add(`<speak>${PLAY_AGAIN_INSTRUCTIONS}</speak>`);
    } else {

index.js(섹션 E):

// Add SECTION E `}` here
}

index.js(섹션 F):

// Add SECTION F `Check if the user has exceeded the maximum` content here
// Check if the user has exceeded the maximum amount of max guesses allowed.
    const userHasLost = conv.context.canvas.state.incorrectGuesses + 1 >= MAX_INCORRECT_GUESSES;
    if (userHasLost) {
      conv.add(`<speak>Let's see if your guess is there...<break
      time='2500ms'/> ${guess} is wrong. Sorry you lost. The word is ${correctWord}!</speak>`);
      conv.add(new Canvas({
        data: {
          command: 'LOSE_GAME',
        },
      }));
      conv.add(`<speak>${PLAY_AGAIN_INSTRUCTIONS}</speak>`);
    } else {

index.js(섹션 G):

// Add SECTION G `}` here
}
  1. Save Fulfillment를 클릭합니다.
  2. Deploy Fulfillment를 클릭합니다. 배포가 완료되면 편집기 위에 Your Cloud Function deployment is up to date.라는 메시지가 표시됩니다.

여기서는 사용자의 게임 승패를 처리하는 WIN_GAME 명령어와 LOSE_GAME 명령어를 사용하는 Canvas 응답 2개를 추가했습니다. 다음 섹션에서는 사용자의 승패에 따라 웹 앱을 업데이트하는 기능을 추가합니다.

웹 앱

이제 사용자의 승패에 따라 업데이트되도록 웹 앱을 구성할 수 있습니다. 웹 앱을 업데이트하려면 다음 단계를 따르세요.

  1. 텍스트 편집기에서 public/js/action.js를 엽니다.
  2. WIN_GAME 명령어와 LOSE_GAME 명령어를 처리하도록 웹 앱을 업데이트합니다.

action.js(섹션 H):

// Add SECTION H `WIN_GAME: (params) => {` content here
      WIN_GAME: (params) => {
        this.gameScene.winGame(params);
      },
      LOSE_GAME: (params) => {
        this.gameScene.loseGame();
      },
  1. 다음 명령어를 실행하여 웹 앱을 업데이트합니다.
firebase deploy --project {PROJECT_ID} --only hosting

시뮬레이터에서 작업 테스트하기

이제 작업이 사용자의 게임 승패를 처리하고 각 결과에 따라 적절한 화면을 표시할 수 있습니다.

작업을 테스트하려면 다음 단계를 따르세요.

  1. Actions 콘솔의 탐색 메뉴에서 Test를 클릭합니다.
  2. Input 필드에 Talk to Snow Pal sample을 입력하고 Enter 키를 누릅니다.
  3. Input 필드에 Yes를 입력하고 Enter 키를 누릅니다. 또는 Start Game 버튼을 클릭합니다.
  4. 승리하거나 패배할 때까지 글자와 단어를 추측합니다.

ee572870f9a7df36.png

다시 플레이하려고 요청하면 다시 플레이하는 데 필요한 기능이 아직 추가되지 않았음을 알리는 메시지가 표시됩니다. 이 기능은 다음 섹션에서 추가합니다.

코드 이해하기

승리/패배 기능은 추측 기능과 동일한 방식으로 작동합니다. 즉, 사용자 입력이 guess 인텐트와 연결되면 웹훅에서 사용자의 추측을 평가합니다. 추측이 옳으면 코드에서 사용자가 승리했는지를 확인하고, 승리했으면 WIN_GAME 명령어가 웹 앱에 전송됩니다. 추측이 틀렸으면 코드에서 사용자가 패배했는지 확인하고, 패배했으면 LOSE_GAME 명령어가 웹 앱에 전송됩니다. 이러한 명령어는 scene.js에서 winGame() 함수와 loseGame() 함수를 트리거하여 웹 앱을 업데이트함으로써 승리 또는 패배 화면을 표시하고 게임의 상태를 업데이트합니다.

이 섹션에서는 사용자가 "다시 플레이해 줘"라고 말하거나 웹 앱에서 Play Again 버튼을 클릭하여 새로운 게임을 시작할 수 있는 기능을 추가합니다. 웹 앱을 적절히 업데이트하는 canvas 응답을 전송하도록 Actions Builder의 play_again 인텐트를 수정하고, 사용자가 Play Again 버튼을 클릭할 때 play_again 인텐트를 트리거하는 로직을 추가합니다.

대화형 작업

이전 섹션에서 작업을 테스트할 때 게임을 다시 플레이하려고 하면 다음과 같은 프롬프트가 나타났습니다. 'That would be great, but we will build this functionality in a later section. For now, just reset the Action.' 이제 이 메시지를 삭제한 후 이를 다른 프롬프트(예: 'Okay, here's another game!')로 바꿉니다. 이는 한 번 더 게임을 요청하는 사용자에게 응답하며, 웹 앱에서 새로운 게임이 시작되도록 트리거하는 canvas 응답을 포함합니다.

사용자가 다시 플레이하려고 할 때의 프롬프트를 업데이트하려면 다음 단계를 따르세요.

  1. Actions 콘솔에서 Scene 드롭다운을 클릭합니다.
  2. Game 장면을 클릭합니다.
  3. Custom intent handling에서 When play_again is matched를 클릭합니다.
  4. 프롬프트를 다음으로 바꿉니다.
candidates:
  - first_simple:
      variants:
        - speech: 'Okay, here's another game!'
    canvas:
      sendStateDataToCanvasApp: true
  1. Save를 클릭합니다.

웹훅

이 Codelab에서 웹훅은 게임 로직을 관리합니다. '다시 플레이하기' 기능은 어떤 종류의 로직 유효성 검사도 필요하지 않으므로, 웹훅을 호출하지 않아도 됩니다. 대신, Actions Builder에서 바로 canvas 응답을 전송하여 필요한 데이터를 웹 앱에 전달할 수 있습니다(이전 섹션에서 구성함).

웹 앱

이제 사용자가 다시 플레이하려고 요청할 때 적절하게 업데이트되도록 웹 앱 파일을 수정할 수 있습니다. 이 기능을 추가하려면 다음 단계를 따르세요.

  1. 텍스트 편집기에서 public/js/action.js를 엽니다.
  2. PLAY_AGAIN 명령어를 처리하도록 웹 앱을 업데이트합니다.

action.js(섹션 I):

// Add SECTION I `PLAY_AGAIN: (params) => {` content here
      PLAY_AGAIN: (params) => {
        this.gameScene.start();
      },
  1. 텍스트 편집기에서 public/js/scene.js를 엽니다.
  2. 사용자가 'Play Again' 버튼을 클릭하면 새 게임 세션을 시작하도록 웹 앱을 업데이트합니다.

scene.js(섹션 J):

// Add SECTION J `sendTextQuery` content here
     window.interactiveCanvas.sendTextQuery('Play again');
  1. 다음 명령어를 실행하여 웹 앱을 업데이트합니다.
firebase deploy --project {PROJECT_ID} --only hosting

시뮬레이터에서 작업 테스트하기

이제 사용자가 "다시 플레이해 줘"라고 말하거나 'Play Again' 버튼을 누르면 작업이 새 게임 세션을 시작할 수 있습니다.

작업을 테스트하려면 다음 단계를 따르세요.

  1. 탐색 메뉴에서 Test를 클릭합니다.
  2. Input 필드에 Talk to Snow Pal sample을 입력하고 Enter 키를 누릅니다.
  3. Input 필드에 Yes를 입력하고 Enter 키를 누릅니다. 또는 Start Game 버튼을 클릭합니다.
  4. 승리하거나 패배할 때까지 글자와 단어를 추측합니다.
  5. Input 필드에 Play Again을 입력하고 Enter 키를 누릅니다. 또는 Play Again 버튼을 클릭합니다.

1fbc7193f7a9d0f5.png

코드 이해하기

작업을 테스트할 때 음성 입력("다시 플레이해 줘")이나 터치 입력('Play Again' 버튼 클릭)을 통해 새 게임을 시작할 수 있습니다.

음성 입력 옵션의 경우 사용자가 "다시 플레이해 줘"라고 말하거나 약간 변형된 표현으로 말하면 play_again 인텐트와 연결되고 프롬프트 큐에 프롬프트(예: 'Okay, here's another game!')가 추가됩니다. 프롬프트에 포함된 canvas 응답은 인텐트 이름 및 기타 메타데이터를 웹 앱에 전송합니다. 인텐트 이름은 onUpdate() 콜백에 전달되고, 이 콜백은 해당하는 명령어 PLAY_AGAINaction.js의 명령어 맵에 매핑합니다. PLAY_AGAIN 명령어는 scene.jsstart() 함수를 트리거하고 새 게임 세션으로 웹 앱을 업데이트합니다.

터치 입력 옵션의 경우 터치 입력을 통해 인텐트를 트리거하는 Interactive Canvas API인 sendTextQuery(),를 사용하여 버튼을 작동할 수 있습니다.

이 Codelab에서는 사용자가 'Play Again' 버튼을 클릭하면 play_again 인텐트를 호출하도록 sendTextQuery()를 사용합니다. Play again 인수는 play_again 인텐트의 학습 문구와 연결되어 사용자가 "다시 플레이해 줘"라고 말할 때와 동일한 방식으로 이 인텐트를 트리거합니다. 그러면 play_again 인텐트는 웹 앱을 업데이트하고 새 게임 세션을 시작하는 로직을 트리거합니다.

이 섹션에서는 PLAY_GAME 암시적 호출을 업데이트합니다.

PLAY_GAME 암시적 호출을 사용하면 사용자가 "게임 플레이하고 싶어"와 같은 일반적인 요청으로 작업을 호출할 수 있습니다.

소스 코드에는 /sdk/custom/global/actions.intent.PLAY_GAME.yaml에 있는 PLAY_GAME 전역 인텐트가 포함되어 있습니다. 이 인텐트는 다음 스크린샷과 같이 콘솔에서 Invocation 아래에 PLAY_GAME으로 반영됩니다.

b4a73c0ddd88f6d5.png

사용자가 이 암시적 호출을 통해 작업을 호출할 수 있게 하려면 웹 앱 URL이 포함된 canvas 응답을 PLAY_GAME 암시적 호출에 추가해야 합니다. 방법은 다음과 같습니다.

  1. Actions 콘솔의 탐색 메뉴에서 PLAY_GAME을 클릭합니다.
  2. 다음 스니펫과 같이 웹 앱 URL을 포함하도록 프롬프트를 업데이트합니다.
candidates:
  - canvas:
      url: 'https://<PROJECT_ID>.web.app'
  1. Save를 클릭합니다.

시뮬레이터에서 작업 테스트하기

이제 작업이 PLAY_GAME 암시적 호출을 지원합니다.

작업을 테스트하려면 다음 단계를 따르세요.

  1. 탐색 메뉴에서 Test를 클릭합니다.
  2. Test fulfillment for system intents를 클릭합니다.
  3. Invoke Action을 클릭합니다.

1a4f647e17ebab53.png

시뮬레이터에서 작업이 호출됩니다.

이 섹션에서는 Interactive Canvas 작업이 제대로 작동하지 않을 때 디버그하는 방법을 알아봅니다. Snow Pal 프로젝트는 사용 설정할 수 있는 디버깅 오버레이와 함께 사전 패키징되어 제공됩니다. 이 오버레이는 다음 스크린샷과 같이 모든 console.log()console.error() 출력을 디스플레이 오른쪽 하단에 표시합니다.

4c8531d24366b5df.png

이 오버레이를 사용 설정하려면 /public/css/main.css 파일을 열고 다음 스니펫과 같이 display: none !important; 줄을 주석 처리합니다.

main.css

.debug {
 display: flex;
 flex-direction: column;

/* Comment below to view debug overlay */
/* display: none !important; */

 width: 500px;
 height: 150px;
 right: 0;
 bottom: 0;
 position: absolute;
}

축하합니다

Interactive Canvas 입문 Codelab을 완료하여 이제 자신만의 Interactive Canvas 작업을 빌드하는 데 필요한 기술을 갖추게 되었습니다.

학습한 내용

  • Interactive Canvas 작업을 빌드, 배포, 테스트하는 방법
  • Canvas 응답을 사용하여 웹 앱을 업데이트하는 방법
  • 다양한 메서드를 사용하여 sendTextQuery()setCanvasState()와 같은 작업을 개선하는 방법
  • 작업을 디버그하는 방법

추가 학습 리소스

Interactive Canvas에 관해 자세히 알아보려면 다음 리소스를 확인하세요.

프로젝트 정리하기[권장]

요금이 청구되지 않도록 하려면 사용하지 않을 프로젝트를 삭제하는 것이 좋습니다. 이 Codelab에서 만든 프로젝트를 삭제하려면 다음 단계를 따르세요.

  1. 클라우드 프로젝트 및 리소스를 삭제하려면 프로젝트 종료(삭제) 섹션에 나열된 단계를 완료합니다.
  1. 선택사항: Actions 콘솔에서 프로젝트를 즉시 삭제하려면 프로젝트 삭제 섹션에 나열된 단계를 완료하세요. 이 단계를 완료하지 않으면 프로젝트가 약 30일 후에 자동으로 삭제됩니다.

의견 설문조사

종료하기 전에 간단한 설문조사에 참여해 주세요.