Google 어시스턴트용 작업으로 사용자 참여 유도하기

1. 개요

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

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

액션의 성공 여부를 측정하는 중요한 방법 중 하나는 사용자 참여 또는 액션이 첫 번째 상호작용 후에 사용자를 다시 유도하는 데 얼마나 효과적인지입니다. 이를 위해 사용자가 대화로 돌아올 수 있는 기능을 제공하는 여러 기능을 작업에 구현하면 됩니다.

이 Codelab에서는 Actions on Google의 사용자 참여 기능 및 권장사항을 다룹니다.

A3fc0061bd01a75.png 961ef6e27dc73da2.png

빌드할 항목

다음을 사용하여 이미 빌드된 기능을 향상할 수 있습니다.

  • 사용자가 탭하여 작업에 액세스할 수 있도록 매일 업데이트 전송
  • 작업에 다시 연결되는 푸시 알림을 사용자에게 보냅니다.
  • 사용자를 모바일 웹브라우저에서 액션으로 연결하는 링크 만들기

학습할 내용

  • 사용자 참여가 무엇이며 액션의 성공에 중요한 이유
  • 작업을 수정하여 사용자 참여를 늘리는 방법
  • 다양한 종류의 작업에서 사용할 수 있는 사용자 참여 기능
  • Actions API를 사용하여 어시스턴트를 통해 알림을 보내는 방법

필요한 항목

다음 도구가 있어야 합니다.

  • WebStorm, Atom 또는 Sublime 등 원하는 IDE/텍스트 편집기
  • Node.js, npm, git이 설치된 셸 명령어를 실행하는 터미널
  • 웹브라우저(예: Chrome)
  • Firebase 명령줄 인터페이스가 있는 로컬 개발 환경
  • 어시스턴트가 지원되는 휴대기기 (Android 또는 iOS)(이 프로젝트를 빌드할 때 사용하는 Google 계정으로 어시스턴트에 로그인해야 함)

웹훅 코드를 이해하려면 자바스크립트 (ES6)를 능숙하게 다루는 것이 좋지만, 필수사항은 아닙니다.

2. 프로젝트 설정

이 섹션에서는 이전에 구축한 전체 작업에 사용자 참여 기능을 추가하는 방법을 설명합니다.

샘플 이해하기

이 Codelab의 샘플은 "Action Gym."라는 가상 체육관을 위한 간단한 작업입니다. 이 작업은 매일 순환되는 수업 목록을 비롯하여 헬스장에 관한 정보를 제공합니다. 이와 같은 정보를 제공하는 작업은 순환 클래스 목록이 매일 다른 정보를 제공하므로 모든 사용자 참여 기능에 적합합니다.

다음 다이어그램은 액션 Gym 대화 흐름을 보여줍니다.

e2d6e4ad98948cf3.png

추가한 참여 기능에 더 잘 맞도록 대화상자를 약간 수정합니다. 하지만 대화의 일반적인 설계는 크게 변경되지 않았습니다.

기본 파일 다운로드

다음 명령어를 실행하여 Codelab용 GitHub 저장소를 클론합니다.

git clone https://github.com/actions-on-google/user-engagement-codelab-nodejs

프로젝트 및 에이전트 설정

작업 프로젝트 및 Dialogflow 에이전트를 설정하려면 다음 단계를 완료하세요.

  1. Actions 콘솔을 엽니다.
  2. 새 프로젝트를 클릭합니다.
  3. 프로젝트 이름을 입력합니다(예: engagement-codelab).
  4. 프로젝트 만들기를 클릭합니다.
  5. 카테고리를 선택하는 대신 옵션 더보기 섹션까지 아래로 스크롤한 다음 대화 카드를 클릭합니다.
  6. Build your Action을 클릭하여 옵션을 펼치고 Add Action(s)을 선택합니다.
  7. 첫 번째 작업 추가를 클릭합니다.
  8. 작업 만들기 대화상자에서 커스텀 인텐트를 선택하고 빌드를 클릭하여 Dialogflow 콘솔을 실행합니다.
  9. Dialogflow 콘솔 에이전트 만들기 페이지에서 만들기를 클릭합니다.
  10. 왼쪽 탐색 메뉴에서 6bf56243a8a11a3b.png(톱니바퀴 아이콘)을 클릭합니다.
  11. 내보내기 및 가져오기를 클릭한 다음 Zip 파일에서 복원을 클릭합니다.
  12. 앞서 다운로드한 /user-engagement-codelab-nodejs/start/ 디렉터리에서 agent.zip 파일을 업로드합니다.
  13. RESTORE를 입력하고 복원을 클릭합니다.
  14. 완료를 클릭합니다.

처리 배포

이제 작업 프로젝트와 Dialogflow 에이전트가 준비되었으므로 Firebase Functions CLI를 사용하여 로컬 index.js 파일을 배포합니다.

기본 파일 클론의 /user-engagement-codelab-nodejs/start/functions/ 디렉터리에서 다음 명령어를 실행합니다.

firebase use <PROJECT_ID>
npm install
firebase deploy

몇 분 후에 웹훅을 Firebase에 배포했음을 나타내는 'Deploy complete!'가 표시됩니다.

배포 URL 가져오기

Dialogflow에 클라우드 함수의 URL을 제공해야 합니다. 이 URL을 가져오려면 다음 단계를 따르세요.

  1. Firebase Console을 엽니다.
  2. 옵션 목록에서 작업 프로젝트를 선택합니다.
  3. 왼쪽 탐색 메뉴에서 Develop > Functions로 이동합니다. '데이터 공유 설정 선택' 메시지가 표시되면 나중에 하기를 클릭하여 이 옵션을 무시해도 됩니다.
  4. 대시보드 탭의 트리거 아래에 URL이 포함된 "fulfillment" 항목이 표시됩니다. 이 URL을 저장합니다. 이 URL은 다음 섹션에서 Dialogflow에 복사해야 합니다.

1741a329947975db.png

Dialogflow에서 웹훅 URL 설정하기

이제 fulfillment에 웹훅을 사용하도록 Dialogflow 에이전트를 업데이트해야 합니다. 이를 위해 다음 단계를 따르시기 바랍니다.

  1. Dialogflow 콘솔을 엽니다. 원하는 경우 Firebase Console을 닫을 수 있습니다.
  2. 왼쪽 탐색 메뉴에서 Fulfillment를 클릭합니다.
  3. 웹훅을 사용 설정합니다.
  4. 아직 표시되지 않은 경우 Firebase 대시보드에서 복사한 URL을 붙여넣습니다.
  5. 저장을 클릭합니다.

프로젝트가 올바르게 설정되었는지 확인하기

사용자는 영업시간을 포함하여 하드 코딩된 텍스트 응답 및 요일별 수업 일정이 나와 있는 텍스트 응답을 비롯한 작업 체육관에 대한 정보를 호출할 수 있어야 합니다.

작업 시뮬레이터에서 작업을 테스트하려면 다음 단계를 따르세요.

  1. Dialogflow 콘솔 왼쪽 탐색 메뉴에서 통합 &gt Google 어시스턴트를 클릭합니다.
  2. 자동 미리보기 변경이 사용 설정되어 있는지 확인하고 테스트를 클릭하여 작업 프로젝트를 업데이트합니다.
  3. 작업 시뮬레이터는 작업 프로젝트를 로드합니다. 작업을 테스트하려면 입력 필드에 Talk to my test app을 입력하고 Enter 키를 누릅니다.
  4. Action Gym에 오신 것을 환영하는 응답이 표시됩니다. 표시되는 메시지에 따라 대화를 계속하면서 처리에서 각 입력에 관한 응답을 있는지 확인합니다.

60acf1ff87b1a87f.png

3. 일일 업데이트 구독 추가

사용자와 소통하는 일반적인 방법은 가장 유용한 시점에 정보를 제공하는 것입니다. 이렇게 하려면 사용자에게 인텐트에 관한 일일 업데이트를 구독하여 인텐트의 처리로 직접 연결되는 어시스턴트 알림을 전송해야 합니다.

이 단계에서는 일일 업데이트 구독을 알아보고 작업의 클래스 목록 인텐트에 추가합니다. 이 안내를 따르면 작업 대화가 다음 다이어그램과 같이 표시됩니다.

f48891c8128f7436.png

사용자의 참여를 유도하려면 어떻게 해야 할까요?

스마트폰 사용자는 앱별 정보와 업데이트를 제공하는 푸시 알림에 익숙할 수 있습니다. 일일 업데이트 정기 결제는 사용자가 업데이트를 계속 전송할 의도가 있는 경우 어시스턴트 외부의 휴대기기 사용자에게 간단하게 액세스할 수 있는 방법입니다.

일일 업데이트는 유용한 참여 도구가 될 수 있지만 모든 작업에 통합되어서는 안 됩니다. 작업에 일일 업데이트 정기 결제를 추가할지 결정할 때 다음 도움말을 고려하세요.

  • 일일 업데이트를 통해 사용자에게 매일 새롭고 유용한 정보가 표시되는지 확인하세요. 일일 업데이트를 탭하면 매번 같은 메시지가 표시되는 경우 사용자는 며칠 후 수신 거부할 수 있습니다.
  • 대화상자가 일일 업데이트의 의도로 바로 이동하는 경우 사용자가 이를 이해할 수 있어야 합니다. 사용자가 대화의 시작 부분에서 시작할 필요는 없기 때문에 맥락이 넓어야 합니다.
  • 사용자에게 일일 업데이트를 구독하라는 메시지를 표시하기 전에 작업의 이점을 보여주세요. 사용자는 구독 옵션이 제공되면 '매일 이 콘텐츠를 보고 싶다'고 생각해야 합니다.
  • 사용자에게 정기 결제 추천 항목을 반복해서 제시하지 마세요. 사용자에게 구독 항목을 즉시 표시한 후 매일 업데이트 구독을 제공하고 다른 곳에는 구독을 강요하지 마세요.
  • 업데이트 인텐트가 트리거된 후 대화를 짧게 유지합니다. 대부분의 일일 업데이트는 단일 응답으로만 구성되어야 하며 그런 다음 사용자의 입력 없이 닫아야 합니다.

일일 업데이트 사용

일일 업데이트 정기 결제는 사용자를 대화 시작 부분에 배치하는 시작 인텐트나 대화 내 특정 위치로 사용자를 딥 링크하는 보다 구체적인 인텐트에 추가할 수 있습니다. 이 Codelab에서는 Class List 인텐트가 가장 적합합니다. 대화상자가 매일 변경되고 사용자는 어떤 클래스를 사용할 수 있는지 다시 알릴 수 있기 때문입니다.

다음 단계를 따라 Class List 인텐트의 일일 업데이트를 사용 설정합니다.

  1. Actions 콘솔에서 Develop 탭을 클릭하고 왼쪽 탐색 메뉴에서 Actions를 선택합니다.
  2. Actions 목록에서 Class List를 클릭합니다.
  3. 사용자 참여 섹션에서 사용자에게 일일 업데이트를 제공하시겠습니까? 옵션을 전환합니다.
  4. 일일 업데이트를 설명하는 콘텐츠 제목을 설정합니다. 맥락은 "몇 시에 매일 보내드릴까요?"라는 문장이 있으므로, 소리 내어 말할 때 제목이 정확하고 소리 나는지 확인해야 합니다. 이 예에서는 콘텐츠 제목list of upcoming Action Gym classes로 설정합니다.
  5. 페이지 상단의 저장을 클릭합니다.

C00885cc30e14d68.png

Dialogflow 설정

Dialogflow 콘솔에서 다음 단계에 따라 일일 업데이트 구독 흐름의 인텐트를 만듭니다.

사용자에게 구독 요청 메시지

  1. 사용자가 일일 업데이트 구독을 요청하는 새 인텐트를 설정합니다. Dialogflow 콘솔에서 왼쪽 탐색 메뉴의 인텐트 옆에 있는 + 버튼을 클릭하여 새 인텐트를 만듭니다.
  2. 새 인텐트의 이름을 Setup Updates로 지정합니다.
  3. 학습 문구 섹션에서 다음 사용자 표현식을 추가합니다.
  • Send daily reminders
  • Reminder
  • Remind me
  • Updates
  • Upcoming classes
  1. Fulfillment 섹션에서 Enable webhook call for thisintent 옵션을 전환합니다.
  2. 페이지 상단의 저장을 클릭합니다.

5c70faa02151da0.png

사용자의 결정 처리

  1. 일일 업데이트 구독 프롬프트에 대한 사용자의 응답을 처리할 새 인텐트를 설정합니다. 왼쪽 탐색 메뉴에서 Intents 옆에 있는 + 버튼을 클릭하여 새 인텐트를 만듭니다.
  2. 새 인텐트의 이름을 Confirm Updates로 지정합니다.
  3. 이벤트 섹션에서 actions_intent_REGISTER_UPDATE를 추가합니다. 이 Dialogflow 이벤트는 사용자가 서비스를 구독했는지 여부와 관계없이 일일 업데이트 구독 절차를 완료하면 트리거됩니다.
  4. Fulfillment 섹션에서 Enable webhook call for thisintent 옵션을 전환합니다.
  5. 페이지 상단의 저장을 클릭합니다.

b871c2bdadac8abc.png

처리 구현하기

웹훅에 처리를 구현하려면 다음 단계를 완료하세요.

종속 항목 로드

b2f84ff91b0e1396.png index.js 파일에서 require() 함수를 업데이트하여 actions-on-google 패키지의 RegisterUpdate 패키지를 추가하여 가져오기가 다음과 같이 되도록 합니다.

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
} = require('actions-on-google');

추천 검색어 칩 업데이트하기

b2f84ff91b0e1396.png 파일에서 index.js DAILY 항목을 추천 칩 제목 목록에 추가하면 Suggestion 정의가 다음과 같이 됩니다.

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
};

새 인텐트에 fulfillment 추가

사용자가 정기 결제를 신청했다고 말하면 업데이트의 대상 인텐트 (클래스 목록) 및 유형 (DAILY)을 사용하여 RegisterUpdate 도우미를 호출하여 일일 업데이트 정기 결제 흐름을 시작합니다. 정기 결제 흐름이 완료되면 어시스턴트는 정기 결제의 성공 여부를 설명하는 status 인수로 actions_intent_REGISTER_UPDATE 이벤트를 트리거합니다. 정기 결제 상태에 따라 변경되는 후속 메시지를 사용자에게 제공합니다.

b2f84ff91b0e1396.png index.js 파일에 다음 코드를 추가합니다.

index.js

// Start opt-in flow for daily updates
app.intent('Setup Updates', (conv) => {
  conv.ask(new RegisterUpdate({
    intent: 'Class List',
    frequency: 'DAILY',
  }));
});

// Confirm outcome of opt-in for daily updates
app.intent('Confirm Updates', (conv, params, registered) => {
  if (registered && registered.status === 'OK') {
     conv.ask(`Gotcha, I'll send you an update everyday with the ` +
     'list of classes. Can I help you with anything else?');
  } else {
    conv.ask(` I won't send you daily reminders. Can I help you with anything else?`);
  }
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS, Suggestion.CLASSES]));
  }
});

사용자에게 대체 메시지 제공

클래스 목록 응답에서는 마지막에 일일 업데이트 구독을 제공하지만, 이는 문제가 됩니다. 사용자가 일일 업데이트 알림을 탭하면 동일한 응답이 트리거되기 때문에 업데이트를 방금 수신하더라도 계속 업데이트하라는 메시지가 표시됩니다. 사용자가 다시 구독해야 한다고 생각하지 못하게 하려면 어떻게 해야 하나요?

다행히 conv 객체의 인수에 사용자가 대화를 시작한 위치에 대한 정보가 포함되어 있습니다. conv 인수를 확인하여 일일 업데이트 알림에서 사용자가 대화를 시작했음을 나타내는 UPDATES 섹션을 포함하는지 확인하고 그에 따라 응답을 변경할 수 있습니다. 또한, 이 대화 분기를 사용하여 클래스 목록을 제공한 직후 대화상자를 닫을 수 있습니다. 이는 일일 업데이트를 짧게 유지하는 권장사항을 따릅니다.

b2f84ff91b0e1396.png index.js 파일에서 다음 코드를 바꿉니다.

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  const classesMessage =
  `On ${day} we offer the following classes: ${classes}. ` +
  `Can I help you with anything else?`;
  conv.ask(classesMessage);
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS]));
  }
});

다음과 같이 바꿉니다.

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

일일 업데이트 테스트하기

터미널에서 다음 명령어를 실행하여 업데이트된 웹훅 코드를 Firebase에 배포합니다.

firebase deploy

Actions 시뮬레이터에서 맞춤 프롬프트를 테스트하려면 다음 단계를 따르세요.

  1. Actions 콘솔에서 Test로 이동합니다.
  2. 입력 필드에 Talk to my test app를 입력하고 Enter 키를 누릅니다.
  3. Learn about classes을 입력하고 Enter 키를 누릅니다. 이제 작업 응답이 일일 알림을 보내도록 제안할 것입니다.
  4. Send daily reminders을 입력하고 Enter 키를 누릅니다.
  5. 업데이트를 보려는 시간을 입력하고 Enter 키를 누릅니다. 테스트를 위해 현재 시간보다 3~5분 늦게 응답하는 것이 좋습니다.

83a15ecac8c71787.png

설정한 시간이 되면 휴대기기에서 어시스턴트로부터 알림을 받게 됩니다. 이 알림이 표시되는 데 몇 분 정도 걸릴 수 있습니다. 알림을 탭하면 딥 러닝이 어시스턴트의 수업 목록 인텐트로 바로 연결되는데, 여기에는 예정된 수업 목록이 표시됩니다.

8582482eafc67d5b.png

4. 푸시 알림 추가

작업 외부에서 사용자의 참여를 유도하는 또 다른 방법은 Actions API를 호출하여 사용자에게 푸시 알림을 전송하는 것입니다. 일일 업데이트와 달리 이러한 알림은 어시스턴트에서 자동으로 예약하지 않으므로 자발적으로 전송할 수 있습니다.

이 단계에서는 새로운 수업 취소됨 인텐트를 추가하고 사용자에게 수업 취소를 알리는 알림을 전송하여 작업에 푸시 알림을 구현하는 방법을 알아봅니다. 또한 알림을 보내는 데 필요한 다음 3가지 구성요소도 설정합니다.

  • Actions API 계정: API에 POST 요청을 전송하여 사용자에게 알림을 전송하므로 이 API와 상호작용하려면 서비스 계정과 사용자 인증 정보를 설정해야 합니다.
  • 권한 도우미 - 푸시 알림을 보내는 데 필요한 사용자 ID에 액세스하려면 사용자 권한이 필요합니다. 이 예에서는 클라이언트 라이브러리 함수를 사용하여 권한 도우미를 호출하고 이 ID를 요청합니다.
  • 저장용량 - 대화 외부의 사용자에게 푸시 알림을 보내려면 리콜할 수 있는 위치에 사용자 ID를 저장해야 합니다. 이 예시에서는 각 사용자의 정보를 저장하도록 Firestore 데이터베이스를 설정합니다.

이 안내를 따른 후 작업 대화에 다음 대화상자를 추가하세요.

7c9d4b633c547823.png

사용자의 참여를 유도하려면 어떻게 해야 할까요?

스마트폰 사용자는 앱별 정보와 업데이트를 제공하는 푸시 알림에 익숙할 수 있습니다. 사용자에게 푸시 알림을 제공하는 합당한 이유가 있는 경우 푸시 알림을 사용하여 어시스턴트 외부의 휴대기기에서 사용자에게 액세스할 수 있습니다. 일일 업데이트를 통해 사용자는 이미 하루 단위로 알림을 받게 됩니다. 하지만 푸시 알림을 통해 사용자는 빈번한 알림을 수신하기로 선택하는지, 하루에 여러 개의 알림을 받는지 알 수 없습니다.

푸시 알림은 유용한 참여 도구일 수 있지만 모든 작업에 반드시 통합되어서는 안 됩니다. 작업에 푸시 알림을 추가할지 결정할 때 다음 도움말을 고려하세요.

  • 푸시 알림의 몇 가지 일정 예시를 계획하세요. 하루에 한 개의 푸시 알림만 보낼 계획이라면 일일 업데이트를 사용하는 것이 좋습니다.
  • 푸시 알림이 수신될 때마다 유용한 정보를 제공해야 합니다. 알림은 작업 인텐트 중 하나에도 딥 링크를 연결할 수 있으므로 인텐트가 유용하고 관련성이 있는지 확인하세요.
  • 사용자에게 푸시 알림 구독을 요청할 때 분명하게 알립니다. 각 푸시 알림에서 예상되는 상황을 이해하고 알림이 전송되는 빈도를 예상해야 합니다.

Actions API 사용 설정

  1. Google Cloud Console을 열고 드롭다운에서 작업 프로젝트 이름을 선택합니다.

D015c1520b99e3db.png

  1. 탐색 메뉴(☰)에서 API & Services > 라이브러리로 이동합니다.
  2. Actions API를 검색하고 사용 설정을 클릭합니다.

6d464f49c88e70b4.png

서비스 계정 만들기

Actions API에는 인증이 필요하므로 요청을 보내려면 서비스 계정을 만들어야 합니다. 다음 단계에 따라 Actions API용 서비스 계정 키를 만들고 설치합니다.

  1. Google Cloud Console의 탐색 메뉴()에서 API 및 서비스 인증으로 이동합니다.
  2. 사용자 인증 정보 및 서비스 계정 키 만들기를 클릭합니다.
  3. 서비스 계정 드롭다운 메뉴에서 새 서비스 계정을 선택합니다.
  4. 다음 정보를 입력합니다.
  • 서비스 계정 이름: service-account
  • 역할: 프로젝트 및 소유자
  • 서비스 계정 ID: service-account(항상 @<project_id>.iam.gserviceaccount.com)
  • 키 유형: JSON
  1. '만들기'를 클릭합니다.
  2. 다운로드한 JSON 파일을 프로젝트의 /user-engagement-codelab/start/functions/ 디렉터리로 이동합니다.
  3. JSON 파일의 이름을 service-account.json로 바꿉니다.

d9bd79d35691de3a.png

Firestore 사용 설정

대화 외부로 알림을 보내려면 알림 코드에서 참조할 수 있는 사용자 ID를 저장할 방법이 필요합니다. 이 예시에서는 Firestore 데이터베이스를 사용하여 구독한 사용자의 사용자 ID를 저장합니다.

작업을 위해 Firestore 데이터베이스를 만들려면 다음 단계를 따르세요.

  1. Firebase Console에서 작업 프로젝트 이름을 선택합니다.
  2. 왼쪽 탐색 메뉴에서 Develop > Database로 이동하여 Create Database를 클릭합니다.
  3. 테스트 모드에서 시작을 선택합니다.
  4. 사용 설정을 클릭합니다.

6dfc386413954caa.png

Dialogflow 설정

Dialogflow 콘솔에서 다음 단계에 따라 푸시 알림 수신 동의 흐름을 만듭니다.

사용자에게 구독 요청 메시지

  1. 취소된 클래스의 푸시 알림 구독을 요청하는 사용자를 처리할 새 인텐트를 설정합니다. Dialogflow 콘솔에서 왼쪽 탐색 메뉴의 인텐트 옆에 있는 + 버튼을 클릭하여 새 인텐트를 만듭니다.
  2. 새 인텐트의 이름을 Setup Push Notifications로 지정합니다.
  3. 학습 문구 섹션에서 다음 사용자 표현식을 추가합니다.
  • Subscribe to notifications
  • Send notification
  • Notify me
  • Send class notifications
  • Cancelled notifications
  1. Fulfillment 섹션에서 Enable webhook call for thisintent 옵션을 전환합니다.
  2. 페이지 상단의 저장을 클릭합니다.

3d99bc41d0492552.png

사용자의 결정 처리

  1. 푸시 알림 구독 프롬프트에 대한 사용자의 응답을 처리할 새 인텐트를 설정합니다. 왼쪽 탐색 메뉴에서 Intents 옆에 있는 + 버튼을 클릭하여 새 인텐트를 만듭니다.
  2. 새 인텐트의 이름을 Confirm Push Notifications로 지정합니다.
  3. 이벤트 섹션에서 actions_intent_PERMISSION를 추가합니다. 이 Dialogflow 이벤트는 사용자가 구독하게 되었는지와 상관없이 푸시 알림 구독 흐름을 완료하여 트리거됩니다.
  4. Fulfillment 섹션에서 Enable webhook call for thisintent 옵션을 전환합니다.
  5. 페이지 상단의 저장을 클릭합니다.

D37f550c5e07cb73.png

푸시 알림 처리

푸시 알림을 특정 인텐트에 연결하면 푸시 알림을 탭하는 사용자가 작업의 해당 인텐트로 바로 딥 링크를 연결할 수 있습니다. 이 예시에서는 취소된 클래스에 관한 세부정보를 제공하는 푸시 알림을 위한 새 인텐트를 추가합니다.

사용자가 푸시 알림을 탭하여 트리거할 인텐트를 추가하려면 다음 단계를 따르세요.

  1. Dialogflow 콘솔에서 왼쪽 탐색 메뉴의 인텐트 옆에 있는 + 버튼을 클릭하여 새 인텐트를 만듭니다.
  2. 새 인텐트의 이름을 Class Canceled로 지정합니다.
  3. 학습 문구 섹션에서 Cancelations사용자 표현으로 추가합니다.
  4. Fulfillment 섹션에서 Enable webhook call for thisintent 옵션을 전환합니다.
  5. 페이지 상단의 저장을 클릭합니다.

940379556f559631.png

대화 중 테스트 알림 보내기

프로덕션에는 푸시 알림을 보내는 작업 처리 코드와 별도로 스크립트가 있어야 합니다. 이 예에서는 작업과 대화하면서 푸시 알림을 보내기 위해 호출할 수 있는 인텐트를 만듭니다. 이 인텐트는 디버그 목적으로만 사용됩니다. 실제로 푸시 알림은 처리로 처리하거나 작업 대화의 일부로 트리거되어서는 안 됩니다.

푸시 알림 테스트를 위한 인텐트를 만들려면 다음 단계를 따르세요.

  1. 테스트 및 디버깅 목적으로 구독 중인 사용자에게 푸시 알림을 보낼 수 있는 새 인텐트를 설정합니다. Dialogflow 콘솔에서 왼쪽 탐색 메뉴의 인텐트 옆에 있는 + 버튼을 클릭하여 새 인텐트를 만듭니다.
  2. 새 인텐트의 이름을 Test Notification로 지정합니다.
  3. 학습 문구 섹션에서 Test notification사용자 표현으로 추가합니다.
  4. Fulfillment 섹션에서 Enable webhook call for thisintent 옵션을 전환합니다.
  5. 페이지 상단의 저장을 클릭합니다.

6967f5a997643eb8.png

푸시 알림 사용

Class Canceled 인텐트에 푸시 알림을 사용 설정하려면 다음 단계를 따르세요.

  1. Dialogflow 콘솔의 탐색 메뉴에서 Integrations로 이동합니다.
  2. Google 어시스턴트 카드에서 통합 설정을 클릭합니다.
  3. 클래스 취소됨암시적 호출 인텐트로 추가합니다. 이 단계는 Dialogflow에서 사용자가 푸시 알림을 탭하여 Class Canceled 인텐트로 대화를 시작할 수 있음을 인식하기 위해 필요합니다.
  4. 닫기를 클릭합니다.

1ac725231ed279a1.png

  1. Actions 콘솔에서 Develop 탭을 클릭하고 왼쪽 탐색 메뉴에서 Actions를 선택합니다.
  2. 작업 목록에서 취소된 수업을 클릭합니다.
  3. 사용자 참여 섹션에서 푸시 알림을 보내시겠습니까? 옵션을 선택합니다.
  4. 푸시 알림을 설명하는 콘텐츠 제목을 설정합니다. 컨텍스트는 &: 이 예에서는 콘텐츠 제목class cancelations로 설정합니다.
  5. 페이지 상단의 저장을 클릭합니다.

4304c7cd575f6de3.png

처리 구현하기

웹훅에 처리를 구현하려면 다음 단계를 완료하세요.

종속 항목 로드

b2f84ff91b0e1396.png index.js 파일에서 require() 함수를 업데이트하여 actions-on-google 패키지의 UpdatePermission 패키지를 추가하여 가져오기가 다음과 같이 되도록 합니다.

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
  UpdatePermission,
} = require('actions-on-google');

추천 검색어 칩 업데이트하기

b2f84ff91b0e1396.png 파일에서 index.js NOTIFICATIONS 항목을 추천 칩 제목 목록에 추가하면 Suggestion 정의가 다음과 같이 됩니다.

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
  NOTIFICATIONS: 'Get notifications',
};

새 가져오기 설정

Firestore 데이터베이스에 연결하려면 firebase-admin 패키지를 추가하고 데이터베이스에 저장된 필드의 상수를 추가합니다. 또한 google-auth-libraryrequest 패키지를 가져와 Actions API에 대한 인증 및 요청을 처리합니다.

b2f84ff91b0e1396.png index.js 파일에서 다음 코드를 가져오기에 추가합니다.

index.js

// Firebase admin import
const admin = require('firebase-admin');

// Initialize Firestore
admin.initializeApp();
const db = admin.firestore();

// Firestore constants
const FirestoreNames = {
 INTENT: 'intent',
 USER_ID: 'userId',
 USERS: 'users',
};

// Actions API authentication imports
const {auth} = require('google-auth-library');
const request = require('request');

수업 취소 알림 설정 제안

b2f84ff91b0e1396.png index.js 파일에서 다음 코드를 바꿉니다.

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

다음과 같이 바꿉니다.

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like to receive daily reminders of upcoming classes, subscribe to notifications about cancelations, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.NOTIFICATIONS,
Suggestion.HOURS]));
    };
  };
});

새 인텐트에 fulfillment 추가

사용자가 푸시 알림을 구독하고 싶다고 하면 UpdatePermission 도우미를 호출하여 사용자에게 권한을 요청합니다. 성공하는 경우 PERMISSION 인수는 conv 객체 인수에 추가됩니다. 이 인수를 확인하여 대화를 피봇팅할 수 있습니다.

사용자 권한이 부여되면 conv 객체 인수에서 사용자 ID를 가져와 데이터베이스에 저장합니다. 나중에 이 사용자 ID를 Actions API로 보내 어시스턴트가 알림을 받을 사용자를 결정합니다.

마지막으로, 푸시 알림을 탭하여 트리거된 Class Canceled 인텐트의 처리를 추가합니다. 이 예시에서는 자리표시자인 응답이 있지만, 이 작업의 프로덕션 준비 버전에서는 알림 스크립트가 취소된 클래스에 관한 동적 정보를 더 많이 제공합니다.

b2f84ff91b0e1396.png index.js 파일에 다음 코드를 추가합니다.

index.js

// Call the User Information helper for permission to send push notifications
app.intent('Setup Push Notifications', (conv) => {
 conv.ask('Update permission for setting up push notifications');
 conv.ask(new UpdatePermission({intent: 'Class Canceled'}));
});

// Handle opt-in or rejection of push notifications
app.intent('Confirm Push Notifications', (conv) => {
 if (conv.arguments.get('PERMISSION')) {
   let userId = conv.arguments.get('UPDATES_USER_ID');
   if (!userId) {
     userId = conv.request.conversation.conversationId;
   }
   // Add the current conversation ID and the notification's
   // target intent to the Firestore database.
   return db.collection(FirestoreNames.USERS)
   .add({
     [FirestoreNames.INTENT]: 'Class Canceled',
     [FirestoreNames.USER_ID]: userId,
   })
   .then(() => {
     conv.ask(`Great, I'll notify you whenever there's a class cancelation. ` +
     'Can I help you with anything else?');
   });
 } else {
   conv.ask(`Okay, I won't send you notifications about class cancelations. ` +
     'Can I help you with anything else?');
 }
 if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.CLASSES, Suggestion.HOURS]));
  }
});

// Intent triggered by tapping the push notification
app.intent('Class Canceled', (conv) => {
 conv.ask('Classname at classtime has been canceled.');
});

테스트 알림 추가하기

사용자에게 푸시 알림을 보내려면 사용자 ID, 알림 제목, 대상 인텐트와 함께 POST 요청을 Actions API에 보냅니다. 이 예시에서는 테스트 알림 인텐트를 트리거하면 Firestore 데이터베이스를 반복하고 알림을 구독하는 모든 사용자에게 푸시 알림을 보냅니다.

이 예에서는 웹훅 처리에서 푸시 알림을 전송하는 코드를 포함하고, 대화에서 테스트 인텐트를 호출하여 코드를 트리거하는 것을 포함합니다. 게시하려는 작업에서 푸시 알림 코드는 처리와 분리된 스크립트에 있어야 합니다.

b2f84ff91b0e1396.png index.js 파일에 다음 코드를 추가합니다.

index.js

// Debug intent to trigger a test push notification
app.intent('Test Notification', (conv) => {
 // Use the Actions API to send a Google Assistant push notification.
 let client = auth.fromJSON(require('./service-account.json'));
 client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation'];
 let notification = {
   userNotification: {
     title: 'Test Notification from Action Gym',
   },
   target: {},
 };
 client.authorize((err, tokens) => {
   if (err) {
     throw new Error(`Auth error: ${err}`);
   }
   // Iterate through Firestore and send push notifications to every user
   // who's currently opted in to canceled class notifications.
   db.collection(FirestoreNames.USERS)
       .where(FirestoreNames.INTENT, '==', 'Class Canceled')
       .get()
       .then((querySnapshot) => {
         querySnapshot.forEach((user) => {
           notification.target = {
             userId: user.get(FirestoreNames.USER_ID),
             intent: user.get(FirestoreNames.INTENT),
           };
           request.post('https://actions.googleapis.com/v2/conversations:send', {
             'auth': {
               'bearer': tokens.access_token,
             },
             'json': true,
             'body': {'customPushMessage': notification, 'isInSandbox': true},
           }, (err, httpResponse, body) => {
             if (err) {
               throw new Error(`API request error: ${err}`);
             }
             console.log(`${httpResponse.statusCode}: ` +
               `${httpResponse.statusMessage}`);
             console.log(JSON.stringify(body));
           });
         });
       })
       .catch((error) => {
         throw new Error(`Firestore query error: ${error}`);
       });
 });
 conv.ask('A notification has been sent to all subscribed users.');
});

푸시 알림 테스트

터미널에서 다음 명령어를 실행하여 업데이트된 웹훅 코드를 Firebase에 배포합니다.

firebase deploy

Actions 시뮬레이터에서 알림을 테스트하려면 다음 단계를 따르세요.

  1. Actions 콘솔에서 Test 탭으로 이동합니다.
  2. 입력 필드에 Talk to my test app를 입력하고 Enter 키를 누릅니다.
  3. Learn about classes을 입력하고 Enter 키를 누릅니다.
  4. Get notifications을 입력하고 Enter 키를 누릅니다.
  5. 아직 푸시 알림을 보낼 작업 권한을 부여하지 않은 경우 yes를 입력하고 Enter 키를 누릅니다.
  6. yes을 입력하고 Enter 키를 누릅니다. 이제 Google 작업이 이 작업에 대한 푸시 알림을 구독해야 합니다.

3a8704bdc0bcbb17.png

  1. no 입력을 입력하고 Enter 키를 눌러 종료합니다.
  2. Talk to my test app을 입력하고 Enter 키를 눌러 새 대화를 시작합니다.
  3. Test notification을 입력하고 Enter 키를 누릅니다.

634dfcb0be8dfdec.png

몇 분 이내에 모바일 기기로 'Action Gym의 어시스턴트 알림 푸시' 알림이 표시됩니다. 이 알림을 탭하면 작업의 수업 취소됨 인텐트로 딥 링크가 연결됩니다.

33cbde513c10122e.png

5. 어시스턴트 연결 만들기

지금까지는 사용자가 액션으로 돌아가도록 하기 위해 구현할 수 있는 참여 기능에 대해 알아보았습니다. 하지만 이러한 기능은 사용자가 액션을 발견하고 사용하는 데에만 목적이 있습니다.

휴대기기 사용자를 어시스턴트의 작업에 직접 연결하는 어시스턴트 링크를 만들 수 있습니다. 어시스턴트 링크는 표준 하이퍼링크이므로 블로그나 소셜 미디어 게시물 같은 웹 마케팅 자료에 추가할 수 있습니다.

이 단계에서는 어시스턴트 링크의 정의, 작업 환영 인텐트를 위한 어시스턴트 링크 생성 방법, 테스트를 위해 간단한 웹사이트에 링크를 추가하는 방법을 알아봅니다.

사용자의 참여를 유도하려면 어떻게 해야 할까요?

특히 어시스턴트에서 작업을 명시적으로 호출해야 하는 경우 사용자를 작업에 처음으로 그리기가 어려울 수 있습니다. 어시스턴트 링크는 사용자에게 액션으로 직접 연결되는 링크를 제공하여 이러한 불편을 줄입니다. 사용자가 어시스턴트 지원 기기에서 내 어시스턴트 링크를 클릭하면 내 작업으로 바로 연결됩니다. 사용자가 휴대기기가 아닌 기기 또는 어시스턴트를 지원하지 않는 다른 기기에서 링크를 열더라도, 사용자가 여전히 작업 디렉터리 등록정보로 이동 (게시된 경우)되므로 해당 사용자에게 작업을 마케팅할 수 있습니다.

어시스턴트 링크는 유용한 참여 도구일 수 있습니다. 따라서 웹사이트나 소셜 미디어를 통해 작업을 광고할 계획이라면 어시스턴트 링크를 만들어야 합니다. 어시스턴트 링크를 만들고 배포하기 전에 다음 도움말을 참고하세요.

  • 어시스턴트 링크는 작업이 게시된 후에만 작동합니다. 프로젝트가 초안 상태일 때 링크는 내 기기에서만 작동합니다. 그 외의 사용자는 Actions 디렉터리에서 404 페이지로 이동합니다.
  • 알파 또는 베타 환경에서 작업을 실행하여 사용자가 게시하기 전에 어시스턴트 링크를 테스트하도록 할 수 있습니다. 알파 또는 베타에 참여하는 사용자만 어시스턴트 링크를 테스트할 수 있습니다.
  • 어시스턴트 링크의 대상 의도가 신규 사용자에게 좋은 첫인상을 주도록 하세요. 시작 인텐트는 어시스턴트 링크의 기본 대상입니다. 작업을 이미 소개해야 하기 때문입니다.

환영 인텐트에 어시스턴트 링크를 만들려면 다음 단계를 따르세요.

  1. Actions 콘솔에서 Develop 탭을 클릭하고 왼쪽 탐색 메뉴에서 Actions를 선택합니다.
  2. 작업 목록에서 actions.intent.MAIN을 클릭합니다.
  3. 링크 섹션에서 이 작업에 URL을 사용 설정하시겠습니까? 옵션을 전환합니다.
  4. 작업을 설명하는 링크 제목을 설정합니다. 제목은 사용자가 작업으로 할 수 있는 행동을 설명하는 간단한 동사 명사 쌍으로 만드세요. 이 예에서는 Link titlelearn about Action Gym로 설정합니다.
  5. 이 페이지 하단에서 HTML 스니펫을 복사한 후 나중에 사용할 수 있도록 저장합니다.
  6. 페이지 상단의 저장을 클릭합니다.

55341b8102b71eab.png

테스트 웹사이트 배포

어시스턴트 링크를 테스트하려면 Firebase 도구를 사용하여 처리와 함께 테스트 웹사이트를 배포하면 됩니다. 이 예에서는 이미 간단한 테스트 웹사이트를 구축했으므로 어시스턴트 링크를 추가하기만 하면 됩니다.

처리의 /user-engagement-codelab-nodejs/start/public/ 디렉터리로 이동하여 텍스트 편집기에서 index.html 파일을 엽니다.

b2f84ff91b0e1396.png index.html 파일에 어시스턴트 링크의 HTML 스니펫을 본문 요소에 붙여넣습니다. 파일은 아래의 스니펫과 같이 표시됩니다.

index.html

<body>
    <p>
     <a href="https://assistant.google.com/services/invoke/uid/000000efb5f2fd97">🅖 Ask my test app to learn about Action Gym
     </a>
    </p>
</body>

터미널에서 다음 명령어를 실행하여 Firebase에 테스트 웹사이트를 배포합니다.

firebase deploy

배포 명령어 실행이 완료되면 출력에서 호스팅 URL을 기록해 둡니다.

b01e8d322fb5d623.png

휴대기기에서 이 URL로 이동하면 테스트 웹사이트에 어시스턴트 링크가 표시됩니다. 휴대기기에서 이 링크를 클릭하면 어시스턴트의 작업 시작 인텐트로 이동합니다.

599845d647f5b624.png

데스크톱 브라우저에서 호스팅 URL로 이동해도 작업이 게시되지 않으므로 어시스턴트 디렉터리의 404 페이지로 이동할 수 있습니다.

6. 다음 단계

수고하셨습니다.

지금까지 작업을 개발할 때 사용자 참여의 중요성, 플랫폼에서 사용할 수 있는 사용자 참여 기능, 각 기능을 작업에 추가하는 방법을 배웠습니다.

추가 학습 리소스

다음 리소스를 살펴보고 작업의 사용자 참여에 관해 자세히 알아보세요.

Twitter에서 @ActionsOnGoogle을 팔로우하여 최신 소식을 확인하고 #AoGDevs로 트윗을 보내 내가 빌드한 결과물을 공유하세요.

의견 설문조사

종료하기 전에 이 양식을 작성해 주세요.