

지원 종료 공지: 2025년 9월 15 AWS 일에는 Amazon Lex V1에 대한 지원을 중단할 예정입니다. 2025년 9월 15일 이후에는 Amazon Lex V1 콘솔 또는 Amazon Lex V1 리소스에 더 이상 액세스할 수 없습니다. Amazon Lex V2를 사용하는 경우 대신 [Amazon Lex V2 가이드를](https://docs.aws.amazon.com/lexv2/latest/dg/what-is.html) 참조하세요.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 스케쥴 예약
<a name="ex1-sch-appt"></a>

이번 봇 예제에서는 치과에서 사용하는 스케쥴 예약을 연습합니다. 또한 이 예제에서는 응답 카드를 사용하여 버튼으로 사용자 입력을 가져오는 방법을 보여줍니다. 특히 예제에서는 런타임에서 동적으로 응답 카드를 생성하는 방법을 보여 줍니다.

빌드 시 응답 카드(정적 응답 카드라고도 함)를 구성하거나 AWS Lambda 함수에서 동적으로 생성할 수 있습니다. 이 예제에서 봇은 다음의 응답 카드를 사용합니다.
+ 예약 유형에 대한 버튼을 목록화하는 응답 카드. 다음 이미지를 예시로 참조하세요.  
![\[예약할 스케쥴의 유형과 클리닝(30분), 신경 치료(60분), 미백(90분)의 세 가지 옵션을 묻는 응답 카드.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/respcard-10.png)
+ 예약 날짜에 대한 버튼을 목록화하는 응답 카드. 다음 이미지를 예시로 참조하세요.  
![\[예약 날짜와 2-15, 2-16, 2-17의 세 가지 옵션을 묻는 응답 카드.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/respcard-20.png)
+ 재안된 예약 시간을 확인하기 위한 버튼을 목록화하는 응답 카드. 다음 이미지를 예시로 참조하세요.  
![\[예약 시간 및 날짜 확인을 요청하는 응답 카드. 예 및 아니요의 두 옵션 제공.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/respcard-30.png)

  

예약 가능한 약속 날짜와 시간이 변하므로 런타임 시에 응답 카드를 생성해야 합니다. AWS Lambda 함수를 사용하여 이러한 응답 카드를 동적으로 생성합니다. Lambda 함수는 Amazon Lex에 대한 응답으로 응답 카드를 반환합니다. Amazon Lex에는 클라이언트에 대한 응답 카드가 포함되어 있습니다.

클라이언트(예: Facebook Messenger)가 응답 카드를 지원하는 경우, 사용자는 버튼 목록에서 선택하거나 응답을 입력할 수 있습니다. 그 외의 경우에는, 단순히 응답을 입력합니다.

앞의 예제에 표시된 버튼 외에도 응답 카드에 표시할 이미지, 첨부 파일, 기타 유용한 정보를 포함시킬 수 있습니다. 응답 카드에 대한 자세한 내용은 [응답 카드](howitworks-manage-prompts.md#msg-prompts-resp-card)을 참조하십시오.

이번 연습에서는, 다음 작업을 수행합니다.
+ 봇 생성 및 테스트(ScheduleAppointment 청사진 사용). 이 연습에서는 봇 청사진을 사용하여 봇을 빠르게 설정하고 테스트합니다. 사용 가능한 청사진 목록은 [Amazon Lex 및 AWS Lambda 블루프린트](lex-lambda-blueprints.md)을 참조하십시오. 이 봇은 하나의 의도(`MakeAppointment`)로 미리 구성되어 있습니다.

   
+ Lambda 함수 생성 및 테스트(Lambda에서 제공한 lex-make-appointment-python 청사진 사용). 이 Lambda 함수를 코드 후크로 사용하도록 `MakeAppointment` 의도를 구성하여 초기화, 검증 및 이행 작업을 수행합니다.
**참고**  
제시된 Lambda 함수 예제에서는 가상의 치과 진료 예약 가용성을 기반으로 한 동적 대화를 보여 줍니다. 실제 application에서는 실제 달력을 사용하여 예약할 수 있습니다.
+ Lambda 함수를 코드 후크로 사용하도록 `MakeAppointment` 의도 구성을 업데이트합니다. 그런 다음 종합 경험을 테스트합니다.
+ 실행 중인 응답 카드를 볼 수 있도록 Facebook Messenger에 일정 약속 봇을 게시합니다(Amazon Lex 콘솔의 클라이언트는 현재 응답 카드를 지원하지 않음).

다음 섹션에서는 이 연습에서 사용하는 블루프린에 대한 요약 정보를 제공합니다.

**Topics**
+ [봇 청사진(ScheduleAppointment) 개요](#ex1-sch-appt-bp-summary-bot)
+ [Lambda 함수 청사진(lex-make-appointment-python) 개요](#ex1-sch-appt-summary-lambda)
+ [1단계: Amazon Lex 봇 생성](ex1-sch-appt-create-bot.md)
+ [2단계: Lambda 함수 생성](ex1-sch-appt-create-lambda-function.md)
+ [3단계: 의도 업데이트: 코드 후크 구성](ex1-sch-appt-create-integrate.md)
+ [4단계: Facebook Messenger 플랫폼에 봇 배포](ex-sch-appt-fb-integration.md)
+ [정보 흐름의 세부 정보](ex1-sch-appt-info-flow-details.md)

## 봇 청사진(ScheduleAppointment) 개요
<a name="ex1-sch-appt-bp-summary-bot"></a>

이번 연습에서 봇을 생성하는 데 사용하는 ScheduleAppointment 청사진은 다음과 같이 미리 구성되어 있습니다.
+ **슬롯 유형** – `AppointmentTypeValue`란 이름의 1개의 사용자 지정 슬롯 유형과 다음과 같은 열거 값: `root canal`, `cleaning`및 `whitening`
+ **의도** – 다음과 같이 미리 구성된 의도 한 개(`MakeAppointment`)
  + **슬롯** – 의도는 다음 슬롯으로 구성되어 있습니다.
    + `AppointmentTypes` 사용자 지정 유형의 슬롯 `AppointmentType`.
    + `AMAZON.DATE` 기본 제공 유형의 슬롯 `Date`.
    + `AMAZON.TIME` 기본 제공 유형의 슬롯 `Time`.
  + **표현** – 의도는 다음 표현으로 미리 구성되어 있습니다.
    + "예약을 진행하고 싶습니다"
    + "예약 진행"
    + "\$1AppointmentType\$1 예약"

    사용자가 이러한 표현을 하면 Amazon Lex는 `MakeAppointment`가 의도라고 판단하고 프롬프트를 사용하여 슬롯 데이터를 유도합니다.
  + **프롬프트** – 의도는 다음 프롬프트로 미리 구성되어 있습니다.
    + `AppointmentType` 슬롯에 대한 프롬프트 – "어떤 유형의 예약을 진행하고 싶으세요?"
    + `Date` 슬롯에 대한 프롬프트 – "\$1AppointmentType\$1 예약을 언제 진행할까요?”
    + `Time` 슬롯에 대한 프롬프트 – "\$1AppointmentType\$1 예약을 몇시로 할까요?" 및 

      "\$1Date\$1의 몇시인가요?"
    + 확인 프롬프트 – "\$1Time\$1에 가능합니다. 예약을 진행할까요?"
    + 취소 메시지 – "네, 더 이상 진행하지 않겠습니다."

## Lambda 함수 청사진(lex-make-appointment-python) 개요
<a name="ex1-sch-appt-summary-lambda"></a>

Lambda 함수 청사진(lex-make-appointment-python)는 ScheduleAppointment 봇 청사진을 사용하여 생성한 봇의 코드 후크입니다.

이 Lambda 함수 청사진 코드는 초기화/검증 및 이행 작업을 모두 수행할 수 있습니다.
+ 이 Lambda 함수 코드에서는 치과 진료 예약의 예를 토대로 한 동적 대화를 보여 줍니다(실제 애플리케이션에서는 달력을 사용할 수 있음). 사용자가 지정하는 요일 또는 날짜에 대해 이 코드는 다음과 같이 구성됩니다.
  +  예약 가능한 요일 또는 날짜가 없는 경우, Lambda 함수는 Amazon Lex 로 다이렉팅하여 사용자에게 다른 요일 또는 날짜를 선택하도록 하는 응답을 반환합니다(`dialogAction` 유형을 `ElicitSlot)`로 설정하여). 자세한 내용은 [응답 형식](lambda-input-response-format.md#using-lambda-response-format)을 참조하세요.
  + 지정된 요일 또는 날짜에 예약 가능한 시간이 하나 뿐인 경우, Lambda 함수는 응답으로서 예약 가능한 시간을 제안하고 Amazon Lex를 다이렉팅하여 사용자의 확인을 얻습니다(`ConfirmIntent`에 대한 응답으로 `dialogAction`을 설정하여). 이는 예약 가능한 약속 시간을 사전에 제시하여 사용자 경험을 향상시킬 수 있는 방법을 보여 줍니다.
  + 예약 가능한 시간이 여러 개인 경우, Lambda 함수는 Amazon Lex에 대한 응답으로 예약 가능한 시간 목록을 반환합니다. Amazon Lex는 Lambda 함수부터 받은 메시지가 포함된 응답을 반환합니다.
+ 이행 코드 후크로서 Lambda 함수는 약속이 예약되었음(즉, 의도가 이행됨)을 나타내는 요약 메시지를 반환합니다.

**참고**  
이 예제에서는 응답 카드를 사용하는 방법을 보여 줍니다. Lambda 함수는 Amazon Lex에 대한 응답 카드를 구성하고 반환합니다. 응답 카드에는 예약 가능한 날짜와 시간이 선택할 수 있는 버튼으로 나열되어 있습니다. Amazon Lex 콘솔에서 제공한 클라이언트를 사용하여 봇을 테스트하는 경우 응답 카드가 표시되지 않습니다. 응답 카드를 보려면 봇을 Facebook Messenger와 같은 메시징 플랫폼에 통합해야 합니다. 지침은 [Amazon Lex 봇을 Facebook Messenger와 통합하기](fb-bot-association.md)을 참조하세요. 응답 카드에 대한 자세한 내용은 [메시지 관리](howitworks-manage-prompts.md)을 참조하십시오.

Amazon Lex가 Lambda 함수를 간접 호출할 때 이벤트 데이터를 입력으로 전달합니다. 이벤트 필드 중 하나는 `invocationSource`이며, Lambda 함수는 이 필드를 사용하여 입력 검증과 이행 활동 중 하나를 선택합니다. 자세한 내용은 [입력 이벤트 형식](lambda-input-response-format.md#using-lambda-input-event-format)을 참조하세요.

**다음 단계**  
[1단계: Amazon Lex 봇 생성](ex1-sch-appt-create-bot.md)

# 1단계: Amazon Lex 봇 생성
<a name="ex1-sch-appt-create-bot"></a>

이 섹션에서는 Amazon Lex 콘솔에 제공된 ScheduleAppointment 청사진을 사용하여 Amazon Lex 봇을 생성합니다.

1. 에 로그인 AWS Management Console 하고 [https://console.aws.amazon.com/lex/](https://console.aws.amazon.com/lex/) Amazon Lex 콘솔을 엽니다.

1. **봇** 페이지에서 **생성**을 선택합니다.

1. **Lex bot 생성** 페이지에서 다음 작업을 수행합니다.
   + **ScheduleAppointment** 청사진을 선택합니다.
   + 봇 이름의 기본값(ScheduleAppointment)을 그대로 둡니다.

1. **생성(Create)**을 선택합니다.

   이 단계에서는 봇을 저장하고 구축합니다. 콘솔은 빌드 프로세스 중에 Amazon Lex에 다음 요청을 보냅니다.
   + 슬롯 유형의 새 버전을(\$1LATEST 버전으로부터) 생성합니다. 이 봇 청사진에서 정의된 슬롯 유형에 대한 자세한 내용은 [봇 청사진(ScheduleAppointment) 개요](ex1-sch-appt.md#ex1-sch-appt-bp-summary-bot)을 참조하십시오.
   + `MakeAppointment` 의도의 버전을(\$1LATEST 버전으로부터) 생성합니다. 경우에 따라 콘솔은 새 버전을 생성하기 전에 `update` API 작업에 대한 요청을 보냅니다.
   + \$1LATEST 버전의 봇을 업데이트합니다.

     이때, Amazon Lex가 봇을 위한 기계 학습 모델을 구축합니다. 콘솔에서 봇을 테스트할 경우, 콘솔은 런타임 API를 사용하여 사용자 입력을 Amazon Lex에 되돌려 보냅니다. 그 뒤에 Amazon Lex는 기계 학습 모델을 사용하여 사용자 입력을 해석합니다.

1. 콘솔에 ScheduleAppointment 봇이 표시됩니다. **편집기** 탭에서, 미리 구성된 의도(`MakeAppointment`)의 세부 정보를 검토합니다.

1. 테스트 창에서 봇을 테스트합니다. 다음 스크린샷을 사용하여 사용자의 봇을 상대로 테스트 대화에 참여합니다.  
![\[에이전트와의 대화. 에이이전트는 예약 유형, 예약 날짜 및 시간을 물어본 다음 예약 세부 정보를 확인합니다.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/appt-test-no-lambda.png)

   참고사항
   + 초기 사용자 입력("예약 진행")에서 봇은 의도(`MakeAppointment`)를 유추합니다.
   + 그러면 봇은 구성된 프롬프트를 사용하여 사용자로부터 슬롯 데이터를 얻습니다.
   + 봇 청사진에는 다음 확인 프롬프트로 구성된 `MakeAppointment` 의도가 있습니다.

     ```
     {Time} is available, should I go ahead and book your appointment?
     ```

     사용자가 모든 슬롯 데이터를 제공하면, Amazon Lex는 확인 프롬프트가 포함된 응답을 클라이언트에 메시지로 반환합니다. 클라이언트는 사용자에게 다음 메시지를 표시합니다.

     ```
     16:00 is available, should I go ahead and book your appointment? 
     ```

   사용자 데이터를 초기화하거나 검증할 코드가 없으므로 봇은 모든 약속 날짜 및 시간 값을 수락합니다. 다음 섹션에서는 Lambda 함수를 추가하여 이를 수행합니다.

**다음 단계**  
[2단계: Lambda 함수 생성](ex1-sch-appt-create-lambda-function.md)

# 2단계: Lambda 함수 생성
<a name="ex1-sch-appt-create-lambda-function"></a>

이 섹션에서는 콘솔에서 제공된 청사진(lex-make-appointment-python)을 사용하여 Lambda 함수를 생성합니다. 또한 콘솔에서 제공하는 샘플 Amazon Lex 이벤트 데이터를 사용하여 함수를 호출함으로써 이 Lambda 함수를 테스트합니다.

1. 에 로그인 AWS Management Console 하고 [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) AWS Lambda 콘솔을 엽니다.

1. **Lambda 함수 생성**을 선택합니다.

1. **청사진 선택**에 **lex**를 입력하여 청사진을 찾은 다음, **lex-make-appointment-python** 청사진을 선택합니다.

1. Lambda 함수를 다음과 같이 구성합니다.
   + Lambda 함수(`MakeAppointmentCodeHook`)를 입력합니다.
   + 역할의 경우 **템플릿에서 새 역할 생성(Create a new role from template(s))**을 선택한 다음 역할 이름을 입력합니다.
   + 다른 기본값을 그대로 둡니다.

1. **함수 생성**을 선택합니다.

1. 영어(미국)(en-US) 이외의 지역을 사용하는 경우 [특정 로캘에 대한 청사진 업데이트](lex-lambda-blueprints.md#blueprint-update-locale)에 설명된 대로 의도 이름을 업데이트하십시오. 

1. Lambda 함수 테스트.

   1. **액션(Actions)**과 **테스트 이벤트 구성(Configure test event)**을 차례로 선택합니다.

   1. **샘플 이벤트 템플릿** 목록에서 **Lex-Make Appointment(미리보기)**를 선택합니다. 이 샘플 이벤트는 Amazon Lex 봇의 요청과 일치하도록 값이 설정된 Amazon Lex 요청 및 응답 모델을 사용합니다. Amazon Lex 요청 및 응답 모델에 대한 자세한 내용은 [Lambda 함수 사용](using-lambda.md)을 참조하십시오.

   1. **저장 및 테스트**를 선택합니다.

   1. Lambda 함수가 성공적으로 실행되었는지 확인합니다. 이 경우 응답은 Amazon Lex 응답 모델과 일치합니다.





**다음 단계**  
[3단계: 의도 업데이트: 코드 후크 구성](ex1-sch-appt-create-integrate.md)

# 3단계: 의도 업데이트: 코드 후크 구성
<a name="ex1-sch-appt-create-integrate"></a>

이 섹션에서는 Lambda 함수를 검증 및 이행 활동을 위한 코드 후크로 사용하도록 `MakeAppointment` 의도의 구성을 업데이트합니다.



1. Amazon Lex 콘솔에서 ScheduleAppointment 봇을 선택합니다. 콘솔은 **MakeAppointment** 의도를 보여줍니다. 의도 구성을 다음과 같이 수정합니다.
**참고**  
의도를 포함하여 모든 Amazon Lex 리소스 중 하나의 \$1LATEST 버전만 업데이트할 수 있습니다. 의도 버전이 \$1LATEST로 설정되어 있어야 합니다. 아직 봇의 버전을 게시하지 않았으므로 콘솔에서 여전히 \$1LATEST 버전일 것입니다.

   1. **옵션** 섹션에서 **초기화 및 검증 코드 후크**를 선택한 다음, 목록에서 Lambda 함수를 선택합니다.

   1. **이행** 섹션에서 **AWS Lambda 함수**를 선택한 다음, 목록에서 Lambda 함수를 선택합니다.

   1. **종료 메시지**를 선택하고 메시지를 입력합니다.

1. **저장**을 선택한 후 **빌드**를 선택합니다.

1. 다음 이미지와 같이 봇을 테스트하십시오.  
![\[에이전트와의 대화. 에이전트는 예약 유형, 예약 날짜, 시간을 묻고 약속을 확인합니다.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/appt-test-with-lambda.png)

**다음 단계**  
[4단계: Facebook Messenger 플랫폼에 봇 배포](ex-sch-appt-fb-integration.md)

# 4단계: Facebook Messenger 플랫폼에 봇 배포
<a name="ex-sch-appt-fb-integration"></a>

이전 섹션에서는 Amazon Lex 콘솔의 클라이언트를 사용하여 ScheduleAppointment 봇을 테스트했습니다. 현재 Amazon Lex 콘솔은 응답 카드를 지원하지 않습니다. 봇이 지원하는 동적으로 생성된 응답 카드를 테스트하려면, Facebook Messenger 플랫폼에 봇을 배포하여 테스트합니다.

지침은 [Amazon Lex 봇을 Facebook Messenger와 통합하기](fb-bot-association.md)을 참조하세요.

**다음 단계**  
[정보 흐름의 세부 정보](ex1-sch-appt-info-flow-details.md)

# 정보 흐름의 세부 정보
<a name="ex1-sch-appt-info-flow-details"></a>

`ScheduleAppointment` 봇 청사진은 주로 동적으로 생성된 응답 카드의 사용을 보여 줍니다. 이 실습의 Lambda 함수 에는 Amazon Lex에 대한 응답 카드가 포함되어 있습니다. Amazon Lex에는 클라이언트에 대한 회신 응답 카드가 포함되어 있습니다. 이 섹션에서는 다음 두 가지에 대해 설명합니다.
+ 클라이언트와 Amazon Lex 간의 데이터 흐름.

   

  이 섹션에서는 클라이언트가 `PostText` 런타임 API를 사용하여 Amazon Lex에 요청을 전송하고 그에 따라 요청 및 응답의 세부 정보를 보여 준다고 가정합니다. `PostText` 런타임 API에 대한 자세한 내용은 [PostText](API_runtime_PostText.md)를 참조하십시오.
**참고**  
클라이언트가 `PostContent` API를 사용할 때의 클라이언트와 Amazon Lex 간의 정보 흐름의 예는 [2a단계(선택 사항): 음성 정보 흐름의 세부 정보 검토(콘솔)](gs-bp-details-postcontent-flow.md)를 참조하십시오.

   
+ Amazon Lex와 Lambda 함수 간의 데이터 흐름. 자세한 내용은 [Lambda 함수 입력 이벤트 및 응답 형식](lambda-input-response-format.md)을 참조하세요.

**참고**  
이 예제에서는 요청에서 세션 속성을 Amazon Lex에 전달하지 않는 Facebook Messenger 클라이언트를 사용한다고 가정합니다. 따라서, 이 섹션에 나와 있는 예제 요청은 빈 `sessionAttributes`을 표시합니다. Amazon Lex 콘솔에 제공된 클라이언트를 사용하여 봇을 테스트할 경우, 클라이언트에 세션 속성이 포함됩니다.

이 섹션에서는 각 사용자가 입력한 후에 일어나는 상황을 설명합니다.

1. 사용자: 유형 **Book an appointment**.

   1. 클라이언트(콘솔)는 Amazon Lex에 다음 [PostContent](API_runtime_PostContent.md) 요청을 보냅니다.

      ```
      POST /bot/ScheduleAppointment/alias/$LATEST/user/bijt6rovckwecnzesbthrr1d7lv3ja3n/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText":"book appointment",
         "sessionAttributes":{}
      }
      ```

      요청 URI 및 본문 모두 Amazon Lex에 다음 정보를 제공합니다.
      + URI 요청 – 봇 이름(ScheduleAppointment), 봇 별칭(\$1LATEST), 사용자 이름 ID를 제공합니다. 후행 `text`은 이것이 `PostText`(`PostContent` 아님) API 요청임을 나타냅니다.
      + 요청 본문 – 사용자 입력(`inputText`)과 빈 `sessionAttributes`를 포함합니다.

   1. `inputText`에서 Amazon Lex는 의도(`MakeAppointment`)를 감지합니다. 이 서비스는 코드 후크로 구성된 Lambda 함수를 간접 호출하여 다음 이벤트를 전달함으로써 초기화 및 검증을 수행합니다. 자세한 내용은 [입력 이벤트 형식](lambda-input-response-format.md#using-lambda-input-event-format)을 참조하세요.

      ```
      {
          "currentIntent": {
              "slots": {
                  "AppointmentType": null,
                  "Date": null,
                  "Time": null
              },
              "name": "MakeAppointment",
              "confirmationStatus": "None"
          },
          "bot": {
              "alias": null,
              "version": "$LATEST",
              "name": "ScheduleAppointment"
          },
          "userId": "bijt6rovckwecnzesbthrr1d7lv3ja3n",
          "invocationSource": "DialogCodeHook",
          "outputDialogMode": "Text",
          "messageVersion": "1.0",
          "sessionAttributes": {}
      }
      ```

      클라이언트가 보낸 정보 외에도 Amazon Lex에는 다음 데이터가 포함되어 있습니다.
      + `currentIntent` – 현재 의도 정보를 제공합니다.
      + `invocationSource` - Lambda 함수 간접 호출의 목적을 나타냅니다. 이 경우 목적은 사용자 데이터 초기화 및 검증을 수행하는 것입니다. (Amazon Lex는 사용자가 아직 의도를 이행하기 위한 모든 슬롯 데이터를 제공하지 않았음을 알고 있습니다.)
      + `messageVersion` - Amazon Lex는 현재 1.0 버전만 지원합니다.

   1. 이때 모든 슬롯 값은 null(검증할 값이 없음)입니다. Lambda 함수는 Amazon Lex에 다음 응답을 반환하여 `AppointmentType` 슬롯에 대한 정보를 유도하도록 서비스에 지시합니다. 응답 형식에 대한 자세한 내용은 [응답 형식](lambda-input-response-format.md#using-lambda-response-format)을 참조하십시오.

      ```
      {
          "dialogAction": {
              "slotToElicit": "AppointmentType",
              "intentName": "MakeAppointment",
              "responseCard": {
                  "genericAttachments": [
                      {
                          "buttons": [
                              {
                                  "text": "cleaning (30 min)",
                                  "value": "cleaning"
                              },
                              {
                                  "text": "root canal (60 min)",
                                  "value": "root canal"
                              },
                              {
                                  "text": "whitening (30 min)",
                                  "value": "whitening"
                              }
                          ],
                          "subTitle": "What type of appointment would you like to schedule?",
                          "title": "Specify Appointment Type"
                      }
                  ],
                  "version": 1,
                  "contentType": "application/vnd.amazonaws.card.generic"
              },
              "slots": {
                  "AppointmentType": null,
                  "Date": null,
                  "Time": null
              },
              "type": "ElicitSlot",
              "message": {
                  "content": "What type of appointment would you like to schedule?",
                  "contentType": "PlainText"
              }
          },
          "sessionAttributes": {}
      }
      ```

      응답에는 `dialogAction` 및 `sessionAttributes` 필드가 포함되어 있습니다. 이 중 `dialogAction` 필드는 다음 필드를 반환합니다.
      + `type` – Lambda 함수는 이 필드를 `ElicitSlot`으로 설정하여 `slotToElicit` 필드에 지정된 슬롯의 값을 유도하도록 Amazon Lex에 지시합니다. 또한 Lambda 함수는 사용자에게 전달할 `message`를 제공합니다.
      + `responseCard` – `AppointmentType` 슬롯의 가능한 값 목록을 식별합니다. 응답 카드를 지원하는 클라이언트(예: Facebook Messenger)는 사용자가 예약 유형을 선택할 수 있도록 다음 이미지와 같은 응답 카드를 표시합니다.  
![\[예약할 예약 유형과 클리닝(30분), 신경치료(60분), 미백(30분)의 세 가지 옵션을 묻는 응답 카드.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/respcard-10.png)

   1. Lambda 함수 응답 내의 `dialogAction.type`에서 지정된 바에 따라, Amazon Lex는 클라이언트에 다음 응답을 다시 보냅니다.  
![\[예약을 잡으려는 의도와 유도하려는 약속 유형 슬롯에 대한 정보가 포함된 JSON 응답.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/appt-10.png)

      클라이언트는 응답을 읽은 다음 "어떤 유형의 예약을 진행하고 싶으세요?"라는 메시지를 표시한 뒤에. 응답 카드(클라이언트가 응답 카드를 지원하는 경우)를 표시합니다.

1. 사용자: 클라이언트에 따라 사용자에게는 다음과 같은 두 가지 옵션이 있습니다.
   + 응답 카드가 표시되는 경우 **신경치료(60 분)**을 선택하거나 **root canal**을 입력합니다.
   + 클라이언트가 응답 카드를 지원하지 않는 경우 **root canal**을 입력합니다.

   1. 클라이언트는 다음 `PostText` 요청을 Amazon Lex에 전송합니다(가독성을 위해 줄 바꿈이 추가됨).

      ```
      POST /bot/BookTrip/alias/$LATEST/user/bijt6rovckwecnzesbthrr1d7lv3ja3n/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText": "root canal",
          "sessionAttributes": {}
      }
      ```

   1. Amazon Lex는 다음 이벤트를 파라미터로 전송하여 사용자 데이터 검증을 위한 Lambda 함수를 간접 호출합니다.

      ```
      {
          "currentIntent": {
              "slots": {
                  "AppointmentType": "root canal",
                  "Date": null,
                  "Time": null
              },
              "name": "MakeAppointment",
              "confirmationStatus": "None"
          },
          "bot": {
              "alias": null,
              "version": "$LATEST",
              "name": "ScheduleAppointment"
          },
          "userId": "bijt6rovckwecnzesbthrr1d7lv3ja3n",
          "invocationSource": "DialogCodeHook",
          "outputDialogMode": "Text",
          "messageVersion": "1.0",
          "sessionAttributes": {}
      }
      ```

      이벤트 데이터에서 다음 사항에 유의하십시오.
      + `invocationSource`는 `DialogCodeHook`로 계속됩니다. 이 단계에서는 사용자 데이터만 검증합니다.
      + Amazon Lex는 `currentIntent.slots` 슬롯의 `AppointmentType` 필드를 `root canal`로 설정합니다.
      + Amazon Lex는 단순히 클라이언트와 Lambda 함수 사이에 `sessionAttributes` 필드를 전달합니다.

   1. Lambda 함수는 사용자 입력을 검증하고 Amazon Lex에 다음 응답을 반환하여 약속 날짜의 값을 유도하도록 서비스에 지시합니다.

      ```
      {
          "dialogAction": {
              "slotToElicit": "Date",
              "intentName": "MakeAppointment",
              "responseCard": {
                  "genericAttachments": [
                      {
                          "buttons": [
                              {
                                  "text": "2-15 (Wed)",
                                  "value": "Wednesday, February 15, 2017"
                              },
                              {
                                  "text": "2-16 (Thu)",
                                  "value": "Thursday, February 16, 2017"
                              },
                              {
                                  "text": "2-17 (Fri)",
                                  "value": "Friday, February 17, 2017"
                              },
                              {
                                  "text": "2-20 (Mon)",
                                  "value": "Monday, February 20, 2017"
                              },
                              {
                                  "text": "2-21 (Tue)",
                                  "value": "Tuesday, February 21, 2017"
                              }
                          ],
                          "subTitle": "When would you like to schedule your root canal?",
                          "title": "Specify Date"
                      }
                  ],
                  "version": 1,
                  "contentType": "application/vnd.amazonaws.card.generic"
              },
              "slots": {
                  "AppointmentType": "root canal",
                  "Date": null,
                  "Time": null
              },
              "type": "ElicitSlot",
              "message": {
                  "content": "When would you like to schedule your root canal?",
                  "contentType": "PlainText"
              }
          },
          "sessionAttributes": {}
      }
      ```

      이번에도 응답에는 `dialogAction` 및 `sessionAttributes`필드가 포함되어 있습니다. 이 중 `dialogAction` 필드는 다음 필드를 반환합니다.
      + `type` – Lambda 함수는 이 필드를 `ElicitSlot`으로 설정하여 `slotToElicit` 필드에 지정된 슬롯의 값을 유도하도록 Amazon Lex에 지시합니다. 또한 Lambda 함수는 사용자에게 전달할 `message`를 제공합니다.
      + `responseCard` – `Date` 슬롯의 가능한 값 목록을 식별합니다. 응답 카드를 지원하는 클라이언트(예: Facebook Messenger)는 사용자가 약속 날짜를 선택할 수 있도록 다음과 같은 응답 카드를 표시합니다.  
![\[신경치료 예약 날짜를 유도하는 응답 카드와 2-15, 2-16, 2-17의 세 가지 옵션.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/respcard-20.png)

        Lambda 함수는 날짜 다섯 개를 반환했지만 클라이언트(Facebook Messenger)에는 응답 카드의 버튼이 세 개로 제한되어 있습니다. 따라서 스크린샷에서 첫 세 개의 값만 볼 수 있습니다.

        이러한 날짜는 Lambda 함수 에 하드 코딩 됩니다. 프로덕션 애플리케이션에서는 달력을 사용하여 실시간으로 예약 가능한 날짜를 가져올 수 있습니다. 날짜가 동적이므로 Lambda 함수 에서 응답 카드를 동적으로 생성해야 합니다.

   1. Amazon Lex는 `dialogAction.type`을 공지하고 Lambda 함수 응답에서 얻은 정보가 포함된 응답을 클라이언트에게 반환합니다.  
![\[예약을 하겠다는 의도, 입력된 약속 유형, 예약 날짜를 유도하는 메시지가 포함된 JSON 응답.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/appt-20.png)

      클라이언트는 **언제 신경치료를 예약하시겠어요?** 메시지와 응답 카드(클라이언트가 응답 카드를 지원하는 경우)를 표시합니다.

1. 사용자: 유형 **Thursday**.

   1. 클라이언트는 다음 `PostText` 요청을 Amazon Lex에 전송합니다(가독성을 위해 줄 바꿈이 추가됨).

      ```
      POST /bot/BookTrip/alias/$LATEST/user/bijt6rovckwecnzesbthrr1d7lv3ja3n/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText": "Thursday",
          "sessionAttributes": {}
      }
      ```

   1. Amazon Lex는 다음 이벤트를 파라미터로 전송하여 사용자 데이터 검증을 위한 Lambda 함수를 간접 호출합니다.

      ```
      {
          "currentIntent": {
              "slots": {
                  "AppointmentType": "root canal",
                  "Date": "2017-02-16",
                  "Time": null
              },
              "name": "MakeAppointment",
              "confirmationStatus": "None"
          },
          "bot": {
              "alias": null,
              "version": "$LATEST",
              "name": "ScheduleAppointment"
          },
          "userId": "u3fpr9gghj02zts7y5tpq5mm4din2xqy",
          "invocationSource": "DialogCodeHook",
          "outputDialogMode": "Text",
          "messageVersion": "1.0",
          "sessionAttributes": {}
      }
      ```

      이벤트 데이터에서 다음 사항에 유의하십시오.
      + `invocationSource`는 `DialogCodeHook`로 계속됩니다. 이 단계에서는 사용자 데이터를 검증만 합니다.
      + Amazon Lex는 `currentIntent.slots` 슬롯의 `Date` 필드를 `2017-02-16`로 설정합니다.
      + Amazon Lex는 단순히 클라이언트와 Lambda 함수 사이에 `sessionAttributes`를 전달합니다.

   1. Lambda 함수는 사용자 입력을 검증합니다. 이때 Lambda 함수는 지정된 날짜에 예약 가능한 시간이 없음을 확인합니다. Amazon Lex에 다음 응답을 반환하여 예약 날짜의 값을 다시 유도하도록 이 서비스에 지시합니다.

      ```
      {
          "dialogAction": {
              "slotToElicit": "Date",
              "intentName": "MakeAppointment",
              "responseCard": {
                  "genericAttachments": [
                      {
                          "buttons": [
                              {
                                  "text": "2-15 (Wed)",
                                  "value": "Wednesday, February 15, 2017"
                              },
                              {
                                  "text": "2-17 (Fri)",
                                  "value": "Friday, February 17, 2017"
                              },
                              {
                                  "text": "2-20 (Mon)",
                                  "value": "Monday, February 20, 2017"
                              },
                              {
                                  "text": "2-21 (Tue)",
                                  "value": "Tuesday, February 21, 2017"
                              }
                          ],
                          "subTitle": "When would you like to schedule your root canal?",
                          "title": "Specify Date"
                      }
                  ],
                  "version": 1,
                  "contentType": "application/vnd.amazonaws.card.generic"
              },
              "slots": {
                  "AppointmentType": "root canal",
                  "Date": null,
                  "Time": null
              },
              "type": "ElicitSlot",
              "message": {
                  "content": "We do not have any availability on that date, is there another day which works for you?",
                  "contentType": "PlainText"
              }
          },
          "sessionAttributes": {
           "bookingMap": "{\"2017-02-16\": []}"
         }
      }
      ```

      이번에도 응답에는 `dialogAction` 및 `sessionAttributes` 필드가 포함되어 있습니다. 이 중 `dialogAction`은 다음 필드를 반환합니다.
      + `dialogAction` 필드
        + `type` – Lambda 함수는 이 값을 `ElicitSlot`으로 설정하고, `slotToElicit` 필드를 `Date`로 재설정합니다. 또한 Lambda 함수는 사용자에게 전달할 적절한 `message`를 제공합니다.
        + `responseCard` – `Date` 슬롯의 값 목록을 반환합니다.
      + `sessionAttributes` - 이때 Lambda 함수 에는 `bookingMap` 세션 속성이 포함되어 있습니다. 이 값은 요청된 약속 날짜와 예약 가능한 약속입니다(빈 객체는 예약이 불가함을 나타냄).

   1. Amazon Lex는 `dialogAction.type`을 공지하고 Lambda 함수 응답에서 얻은 정보가 포함된 응답을 클라이언트에게 반환합니다.  
![\[약속을 잡겠다는 의도를 보여주는 JSON 응답 및 고객이 요청한 날짜에 예약이 불가능하다는 점을 명확히 하는 메시지.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/appt-30.png)

      클라이언트는 **해당 날짜에는 예약할 수 없으니, 다른 가능한 날이 있을까요?** 메시지와 응답 카드(클라이언트가 응답 카드를 지원하는 경우)를 표시합니다.

1. 사용자: 클라이언트에 따라 사용자에게는 다음과 같은 두 가지 옵션이 있습니다.
   + 응답 카드가 표시되는 경우 **2-15(수)** 또는 유형 **Wednesday**를 선택합니다.
   + 클라이언트가 응답 카드를 지원하지 않는 경우 **Wednesday**을 입력합니다.

   1. 클라이언트는 Amazon Lex에 다음 `PostText` 요청을 보냅니다.

      ```
      POST /bot/BookTrip/alias/$LATEST/user/bijt6rovckwecnzesbthrr1d7lv3ja3n/text
      "Content-Type":"application/json"
      "Content-Encoding":"amz-1.0"
      
      {
         "inputText": "Wednesday",
          "sessionAttributes": {
         }
      }
      ```

      
**참고**  
Facebook Messenger 클라이언트는 세션 속성을 설정하지 않습니다. 요청 간의 세션 상태를 유지하려면 Lambda 함수 에서 그렇게 해야 합니다. 실제 어플리케이션에서는 백엔드 데이터베이스에서 이러한 세션 속성을 유지해야 할 수 있습니다.

   1. Amazon Lex는 다음 이벤트를 파라미터로 전송하여 사용자 데이터 검증을 위한 Lambda 함수를 간접 호출합니다.

      ```
      {
          "currentIntent": {
              "slots": {
                  "AppointmentType": "root canal",
                  "Date": "2017-02-15",
                  "Time": null
              },
              "name": "MakeAppointment",
              "confirmationStatus": "None"
          },
          "bot": {
              "alias": null,
              "version": "$LATEST",
              "name": "ScheduleAppointment"
          },
          "userId": "u3fpr9gghj02zts7y5tpq5mm4din2xqy",
          "invocationSource": "DialogCodeHook",
          "outputDialogMode": "Text",
          "messageVersion": "1.0",
          "sessionAttributes": {
          }
      }
      ```

      Amazon Lex는 `Date`슬롯을 `2017-02-15`로 설정하여 `currentIntent.slots`를 업데이트했습니다.

   1. Lambda 함수는 사용자 입력을 검증하고 Amazon Lex에 다음 응답을 반환하여 약속 시간의 값을 유도하도록 이 서비스에 지시합니다.

      ```
      {
          "dialogAction": {
              "slots": {
                  "AppointmentType": "root canal",
                  "Date": "2017-02-15",
                  "Time": "16:00"
              },
              "message": {
                  "content": "What time on 2017-02-15 works for you? 4:00 p.m. is our only availability, does that work for you?",
                  "contentType": "PlainText"
              },
              "type": "ConfirmIntent",
              "intentName": "MakeAppointment",
              "responseCard": {
                  "genericAttachments": [
                      {
                          "buttons": [
                              {
                                  "text": "yes",
                                  "value": "yes"
                              },
                              {
                                  "text": "no",
                                  "value": "no"
                              }
                          ],
                          "subTitle": "Is 4:00 p.m. on 2017-02-15 okay?",
                          "title": "Confirm Appointment"
                      }
                  ],
                  "version": 1,
                  "contentType": "application/vnd.amazonaws.card.generic"
              }
          },
          "sessionAttributes": {
              "bookingMap": "{\"2017-02-15\": [\"10:00\", \"16:00\", \"16:30\"]}"
          }
      }
      ```

      이번에도 응답에는 `dialogAction` 및 `sessionAttributes` 필드가 포함되어 있습니다. 이 중 `dialogAction`은 다음 필드를 반환합니다.
      + `dialogAction` 필드:
        + `type` – `Lambda` 함수는 이 값을 `ConfirmIntent`로 설정하여 `message`에 제시된 약속 시간에 대한 사용자 확인을 받도록 Amazon Lex에 지시합니다.
        + `responseCard` – 사용자가 선택할 수 있는 예 혹은 아니오 값 목록을 반환합니다. 클라이언트가 응답 카드를 지원하는 경우, 다음 예와 같이 응답 카드를 표시합니다.  
![\[예약 확인과 두 가지 옵션 (예, 아니요)가 표시된 응답 카드.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/respcard-30.png)
      + `sessionAttributes` - Lambda 함수는 해당 예약 날짜와 그 예약 날짜에 가능한 예약 시간으로 값을 지정하여 `bookingMap` 세션 속성을 설정합니다. 이 예에서는 30분 진료 예약입니다. 진료 시간이 1시간 걸리는 신경 치료의 경우에는, 4:00 p.m만 예약할 수 있습니다.

        

   1. Lambda 함수 의 응답 내의 `dialogAction.type`에 지정된 설정에 따라 Amazon Lex는 클라이언트에 다음 응답을 반환합니다.  
![\[예약 의도가 표시되고 모든 칸이 채워진 JSON 응답.\]](http://docs.aws.amazon.com/ko_kr/lex/latest/dg/images/appt-40.png)

      클라이언트는 다음과 같은 메시지를 표시합니다. **2017-02-15 중 언제가 괜찮나요? 이용 가능 시간은 4:00 p.m 뿐입니다. 가능한가요?**

   

1. 사용자: **yes**를 선택합니다.

   Amazon Lex는 다음 이벤트 데이터로 Lambda 함수를 간접 호출합니다. 사용자가 **yes**를 회신했기 때문에 Amazon Lex는 `confirmationStatus`를 `Confirmed`으로 설정하고, `currentIntent.slots ` 필드 내의 `Time`를 `4 p.m`으로 설정합니다.

   ```
   {
       "currentIntent": {
           "slots": {
               "AppointmentType": "root canal",
               "Date": "2017-02-15",
               "Time": "16:00"
           },
           "name": "MakeAppointment",
           "confirmationStatus": "Confirmed"
       },
       "bot": {
           "alias": null,
           "version": "$LATEST",
           "name": "ScheduleAppointment"
       },
       "userId": "u3fpr9gghj02zts7y5tpq5mm4din2xqy",
       "invocationSource": "FulfillmentCodeHook",
       "outputDialogMode": "Text",
       "messageVersion": "1.0",
       "sessionAttributes": {
      }
   }
   ```

   `confirmationStatus`가 확인되었으므로 Lambda 함수는 의도(치과 진료 예약)를 처리하고 Amazon Lex에 다음 응답을 반환합니다.

   ```
   {
       "dialogAction": {
           "message": {
               "content": "Okay, I have booked your appointment.  We will see you at 4:00 p.m. on 2017-02-15",
               "contentType": "PlainText"
           },
           "type": "Close",
           "fulfillmentState": "Fulfilled"
       },
       "sessionAttributes": {
           "formattedTime": "4:00 p.m.",
           "bookingMap": "{\"2017-02-15\": [\"10:00\"]}"
       }
   }
   ```

   참고사항
   + Lambda 함수는 `sessionAttributes`를 업데이트했습니다.
   + `dialogAction.type`은 `Close`로 설정됩니다. 이는 사용자 응답을 기대하지 않도록 Amazon Lex에 지시합니다.
   + `dialogAction.fulfillmentState`는 `Fulfilled`로 설정됩니다. 이는 의도가 이행되었음을 나타냅니다.

   클라이언트는 **네, 예약을 처리했습니다. 메시지를 표시합니다. 2017-02-15 4:00 p.m에 뵙겠습니다.** 메시지를 표시합니다.





