SlideShare a Scribd company logo
1 of 75
Download to read offline
Clova Extension AtoZ
Clova Platform Evangelist
옥상훈
2018-04-27
발표자료: https://www.slideshare.net/ClovaPlatform/
목차
• Clova Platform 개요
• Clova extension 개발 준비 개요
• Clova extension 등록 – 호출명, 서버정보, 배포정보
• 인터렉션모델 등록
• Clova extension 서버 API 개발
• Clova 앱과 스피커에서 익스텐션 호출 테스트
Clova Plaform & extension 개요
Clova Platform Overview
Clova Interface Connect
Clova Interface Connect 적용 사례
LG U+ 블루콤 스피커 LG 전자 스마트씽큐
LG전자 가전기기 제어가능IoT 제품 제어가능
LG U+ IPTV STB
- LG U+ IPTV UHD급 이상의 STB 내 Clova 제공 (2017년 12월 적용)
시청 중,
리모콘 side음성버튼
or (음성) LGU플러스야
로 음성명령 수행
‘효리네민박 틀어줘’ ‘스릴러영화 추천해줘’전면 검색키>
전체화면모드, 클로바스러운 검색홈으로 제안
Clova Interface Connect 적용 사례
Clova Interface Connect 적용 사례 (Friends +)
스피커로 '셋탑을 컨트롤' 할 수 있습니다.
브라운과 샐리에게 "유플티비"라는 호출어로 지시해보세요.
"유플티비, 눈물 쏙 빼는 영화 찾아줘"
"유플티비, tvN 틀어줘"
Clova Extensions Kit
Clova extension 이란?
• Clova 플랫폼에서 작동하는 3rd party 애플리케이션으로서, 예를 들면 음성명령으로 음악을 재
생하거나 쇼핑, IoT기기 제어 등이 가능합니다.
• 사용자의 의도(예: 음성명령)에 따라 extension이정확하게 동작할 수 있도록 Clova 플랫폼 내부
적으로 음성인식, 대화분석 등 Clova 인공지능 기술이 적용되어 있습니다.
extension으로 무엇을 할 수 있나요?
• Extension 종류
• (서비스중) Custom extension: 3rd party 서버에서 제공하는 응답(예: 음성,
이미지 등)을 제공할 수 있습니다.
• 예) "팟빵에서 뉴스공장 틀어줘" 라고 하면 "팟빵 extension"이 해당 음원을 들
려줍니다.
• (예정) Chatbot extension: 고객이 자주 묻는 질문(FAQ)과 답변을 등록하여
사업자 대신 챗봇이 답변을 하게 하는 extension입니다.
• 예) ”네이버고객센터 실행해줘 à 네이버 쇼핑 가격 비교하는 방법
알려줄래?”
• (제휴문의) Clova Home extension: IoT 기기제어가 가능
• 예) "클로바, TV 좀 켜줘" 라고 하면 클로바가 TV를 켭니다
Clova Extension 예시
• https://blog.naver.com/clova_ai/221199482419
Clova extension 사례 – ‘체리쉬’ 모션베드제어
https://www.youtube.com/watch?v=kpkRRLWHySc
대표발화: 1) 체리쉬에게 자자 2) 체리쉬에게 무중력 모드 해줘 3) 체리쉬에게 첫번째 메모리 해줘
Clova extension 사례 – ‘배송지킴이’ 택배조회
https://www.youtube.com/watch?v=27NWVG0yhTQ
대표발화: 1) 배송지키미 시작해줘 2) 배송지키미에서 내 택배 조회해줘 3) 배송지키미 내 택배 언제와
Clova extension 사례 – ‘라마마’ 연애운
https://www.youtube.com/watch?v=uCqQem8_LyQ
대표발화: 1) 라마마 시작해줘 2) 라마마에게 연애운 물어봐줘 3) 라마마에게 남친 언제생길지 물어봐줘
Clova 챗봇 extension 사례 – ‘멍멍이’ 동물소리 번역기
https://www.facebook.com/ClovaAI/photos/a.1639371196371443.1073741828.1637903373184892/1783396565302238/
대표발화: 1) 멍멍이 시작해줘
Clova extension 예제
마법 구슬(Magic ball)
• 개요
• 마법 구슬은 사용자의 물음에 미리 정의해놓은 20가지의 긍정 또
는 부정 표현 중 하나를 응답으로 돌려주는 extension입니다.
• 실행 방법
• 마법구슬 시작해줘 à 아무거나 소원, 희망 사항을 얘기하면 됨
• 마법구슬에게 로또 당첨될지 물어봐줘
https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#MagicBall
마법 구슬(Magic ball)
• 인터렉션 모델
• 사용자의 발화와 관계없이 응답을 선택해서 내려주기 때문에 interaction 모델이 간단합니다.
마법 구슬(Magic ball)
• API 소스코드
• https://github.com/naver/clova-extension-sample-magicball
• 익스텐션 응답
• https://github.com/naver/clova-extension-sample-magicball/blob/github-public/intent/answer.go
빗소리(Rain sound)
• 개요
• 빗소리는 사용자의 요청에 미리 녹음해둔 빗소리 음원 파일(.mp3)를 클라이
언트가 재생하도록 응답하는 extension입니다.
• 사용자는 빗소리를 몇 번 반복해서 들을지 결정할 수 있으며, 이 extension의
interaction 모델은 반복 횟수에 대한 값을 slot으로 정의하고 있습니다.
• 클라이언트가 음원을 재생할 수 있도록 응답 메시지에 안내 문구 뿐만 아니
라 AudioPlayer.Play 지시 메시지를 포함시켜 CEK로 보내줍니다.
• 실행 방법
• 빗소리 시작해줘
• 빗소리 열어줘
• 빗소리한테 2번 반복해달라고 해줘
https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#RainSound
빗소리(Rain sound)
• 인터렉션 모델
• 사용자는 빗소리를 몇 번 반복해서 들을지 결정할 수 있으며, 이 extension의 interaction 모델은 반복 횟수에 대한 값을 slot으로 정의
하고 있습니다.
빗소리(Rain sound)
• 인터렉션 모델
빗소리(Rain sound)
• API 소스코드
• https://github.com/naver/clova-extension-sample-rainsound
• 익스텐션 응답
• https://github.com/naver/clova-extension-sample-rainsound/blob/github-public/clova/index.js
주사위 놀이(Dice drawer)
• 개요
• 주사위 놀이는 사용자의 요청에 가상의 주사위를 굴려 나온 주사위의 눈과 눈
의 합계를 알려주는 extension입니다.
• 굴릴 주사위 개수가 하나인지 두 개 이상 인지에 따라 응답으로 돌려주는 표현
이 달라집니다.
• 실행 방법
• 주사위 놀이 시작해줘
• 주사위 놀이에서 주사위 2개 던져줘
• 주사위 놀이에게 5개 굴려달라고 해
https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#DiceDrawer
주사위 놀이(Dice drawer)
• 인터렉션 모델
• 사용자는 주사위를 몇 개 던질 지 결정할 수 있으며, 이 extension의 interaction 모델은 주사위 개수에 대한 값을 slot으로 정의하고 있
습니다.
주사위 놀이(Dice drawer)
• 인터렉션 모델
주사위 놀이(Dice drawer)
• API 소스코드
• https://github.com/naver/clova-extension-sample-dice
• 익스텐션 응답
• https://github.com/naver/clova-extension-sample-rainsound/blob/github-public/clova/index.js
코인 헬퍼(Coin helper)
• 개요
• 코인 헬퍼는 사용자의 요청에 외부 가상 화폐 거래소에서 제공하는 RESTAPI
를 호출하여 시세 정보를 돌려주는 extension입니다.
• 실행 방법
• 코인헬퍼 시작해줘
• 코인헬퍼에서 시세 알려줘
• 코인헬퍼에서 비트코인 시세 물어봐줘
https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#CoinHelper
코인 헬퍼(Coin helper)
• 인터렉션 모델
• 사용자는 어떤 거래소의 정보를 이용할지 어떤 가상화폐의 시세를 조회할지 결정할 수 있으며, 이 extension의 interaction 모델은 거
래소와 가상 화폐 종목에 대한 값을 slot으로 정의하고 있습니다.
코인 헬퍼(Coin helper)
• API 소스코드
• https://github.com/naver/clova-extension-sample-coinhelper
• 익스텐션 응답
• https://github.com/naver/clova-extension-sample-coinhelper/blob/github-public/intent/ask.go
Clova extension 개발 준비 개요
Clova extension 개발 준비 – 1 (필수)
• 익스텐션서버
• REST API 서버로서, Clova platform은 Clova console에 등록한 REST API 서버URL로 응답과 요청을 주
고 받습니다.
• Clova platform은 1) 익스텐션 실행 2) 인텐트 실행 3) 익스텐션 종료라는 3가지 type의 요청을 보내고,
익스텐션 서버는 여기에 맞게 응답을 하면 됩니다.
• 익스텐션 서버는 https로 외부망으로 통신할 수 있는 서버이어야 하며, 포트는 80 또는 443로만 통신
합니다.
Clova extension 개발 준비 – 1 (필수)
• 익스텐션서버
Clova extension 개발 준비 – 2 (필수)
• 인터렉션 모델
• 일종의 대화시나리오와 비슷합니다만, 기계인 익스텐션 서버가 사람의 대화를 이해하여 작동할 수 있
도록 Clova console에 입력하는 문장 및 메타정보들입니다.
• 인터렉션 모델에는 사용자로부터 입력될 만한 문장들과 각 문장이 어떤 실행 명령(이를 '인텐트'라고
합니다.)으로 연결될 지를 설정합니다.
• 인텐트를 실행할 때 필요한 정보들은 '슬롯'이라는 것으로 정의하여 처리합니다.
• 예를 들면, 피자주문하는 익스텐션의 경우 인텐트와 슬롯은 아래와 같습니다.
• 예) 사용자의 대화: "페퍼로니 피자 2판 주문해줘" --> 'OrderPizza'라는 이름으로 피자주문 처리용 인텐트로 정
의
• 예) 'OrderPizza'인텐트가 실제 피자를 주문하기 위해 필요한 정보는 '피자명'과 '수량'이며, 이는 각기
'pizzaType', 'pizzaAmount'라는 슬롯으로 정의
Clova extension 개발 준비 – 3 (선택)
• OAuth 인증 서버
• 만약 익스텐션이 써드파티 계정
인증이 필요하다면 익스텐션 서버
와 함께 OAuth 인증을 구현하셔야
필요합니다.
• OAuth 인증 서버는 Clova console
에 등록된 인증정보를 이용하여
인증을 처리하고, 인증이 완료되
면 접근토큰을 반환해야 합니다.
• 인증서버 구축 예) 배달의 민족,
LG 전자, LGU +
관련 가이드: https://www.slideshare.net/ClovaPlatform/clova-tech-summit-3-clova-extension-oauth-89597569
Clova extension 등록
익스텐션 기본 정보 등록하기
• Clova console에 접속해서 'Clova Extensions Kit'을 클릭한 다음 '새로운 익스텐션 만들기'를 누릅니다.
• URL: https://developers.naver.com/console/clova/
• 익스텐션 정보 설정
• type은 Custom Extension으로 선택하고, 나머지 값들도 입력합니다.
• 오디오플레이어 사용 여부는 '아니오'로 합니다. '예'로 하는 경우는 음원을 재생하는 경우에 사용합니다.
Clova extension 호출명 설정
• 가전기기를 제어하는 Custom extension (이하 '익스텐션') 서비스를 그려 보도록
하겠습니다.
• 먼저 익스텐션 실행할 때 부르는 이름, 즉 '호출명'을 정해야하는데, 몇 가지 제
약이 있습니다.
• 일반적인 명사는 안됨 (예: 박사 (X) )
• 브랜드나 유니크한 명사가 접목된 단어 가능: (예: 짱구박사(O))
• 혹시나 음성인식이 잘 안되는 경우는 다른 호출명으로 하셔야 할 수 있으니, Clova앱에서 인
식이 잘 되는지 확인해보시길 바랍니다.
서버 연동 설정
• 외부에서 접근가능한 RESTAPI 서버의 endpoint URL을 입력합니다. 계정연결 여부는 '아니요'로 둡니다.
배포정보 설정
• 여기서 테스트용 지시어와 대표 표현 문장은 아까 작동 시나리오에서 나왔던 문장에 호출명을
붙여서 사용자가 테스트할 수 있는 문장을 입력합니다.
• 짱구박사를 시작해줘
• 짱구박사에서 거실 전등 켜줘
• 짱구박사에서 거실 전등 꺼줘
인터렉션 모델 등록
익스텐션의 작동 시나리오
• 첫번째는 익스텐션에게 바로 질문하고 답을 받는 것입니다. (싱글턴, single-turn)
• 사용자: 클로바, 짱구박사에서 거실 전등 켜줘
• 익스텐션: 거실 전등이 켜졌습니다.
• 두번째는 익스텐션을 실행한 다음에 질문하고 답을 받는 것입니다. (멀티턴,
multi-turn)
• 사용자: 클로바, 짱구박사를 시작해줘
• 익스텐션: 안녕하세요. 짱구박사가 시작되었습니다. 제어하고 싶은 가전기기와 동작 방법
을 말씀하세요.
• 사용자: 거실 전등 켜줘.
• 익스텐션: 거실 전등이 켜졌습니다.
익스텐션 작동 시나리오 고려사항
• 이제 해야할 일은 시나리오가 클로바 플랫폼에서 작동하도록 하는 것인데요.
• 문제는 사용자가 같은 말을 물어보더라도, 위에서 정의한 글자그대로 말하지는
않는다는 점입니다.
• 예) 거실 전등 켜줘
• 예) 거실 점등 해줘
• 예) 거실 불켜줘
• 이렇게 같은 의도이지만 다양한 표현을 입력하고 인터렉션 모델에 이러한 여러
문장 케이스들을 잘 정리해놔야 더 똑똑한 익스텐션을 만들 수 있겠습니다.
인터렉션 모델 등록하기 – 슬롯 등록
• 짱구박사는 집안의 지역 IoT기기를 제어
할 것이므로 인텐트는 하나만 등록하면 되
고, 슬롯은 ’집안의 다양한 장소들이'이 되
겠습니다.
• 슬롯 등록하기 전에
• 슬롯에는 커스텀 슬롯과 빌트인 슬롯 2가
지가 있습니다.
• 빌트인 슬롯은 아래와 같이 사람들이 이미
인지하는 용어들을 모아둔 것으로, 사용하
겠다고 체크하면 편리하게 사용하실 수 있
습니다.
• 집안의 다양한 장소들은 커스텀 슬롯
으로 등록합니다.
• IOT_TYPE
• 거실: 리빙룸
• 안방: 침실
• 부억: 키친
• 베란다
인터렉션 모델 등록하기 – 슬롯 등록
• 슬롯이 등록되면 아래와 같이 나타납니다.
인터렉션 모델 등록하기 – 인텐트 등록
• 우측의 '사용중인 Intent' 옆의 + 버튼을 눌러서 ‘turnOnIntent’입력하고 '만들기' 버튼을 누릅니다.
• 사용자 표현 리스트에 사용자들이 입력할 것 같은 대화들을 입력하는데, slot과 의도에 해당하는
문장들은 다양하게 입력합니다.
• 문장의 가짓수는 많을 수록 더욱 대화의도 파악은 잘 됩니다.
• 거실 전등 켜줘
• 안방 불 켜줘
• 침실 점등 해줘
https://developers.naver.com/console/clova/guide/Design/Des
ign_Guideline_For_Extension.md#DefineInteractionModel
인터렉션 모델 등록하기 – 인텐트 슬롯 등록
• 사용자 표현 리스트에서 ’거실'이라는 단어를 드래그한 다음 앞에서 입력한 ‘homeSlotType’이란 이름으로
매핑해줍니다.
• 매핑이 완료되면 Slot 에 해당하는 글씨들이 아래와 같이 하이라이트 됩니다.
인터렉션 모델 빌드하기
• ‘저장’ 버튼을 누른 다음
• 우측 상단의 '빌드' 버튼을 눌러 인터렉션 모델을 빌드합니다. 빌드가 완료되면 다시 '빌드'라는 버튼으로 바뀝니다.
인터렉션 모델 테스트
• 아직 REST API 서버 개발전이지만, 등록한 인터렉션 모델이 잘 동작하는지 확
인합니다.
• '빌드' 버튼 아래에 '테스트'를 누릅니다.
인터렉션 모델 테스트
• 체크할 포인트는 인터렉션 모델에 등록한 문장과 비슷한 문장을 입력하더라도 slot과 intent값을 리턴하는지 확인하는
것입니다.
• 예)
• 거실 전등 켜줘 (인터렉션 모델에 있는 문장)
• 부억 점등 해줘 (인터렉션 모델에 있는 문장과 비슷한 유형이지만, slot 이 다른 문장)
• 침실 불 켜줘 (비슷한 문장)
Clova extension 서버 API 개발
개발 환경 구성
• 개발 도구
• IntelliJ ( with Java )
• 프로젝트 생성
• Spring Initializr로 프로젝트 생성
• 프로젝트 설정
• pom에 api test (rest-assured)에 필요한 dependency 설정
개발환경 세팅 – Spring Initailzr로 프로젝트 생성
개발환경 세팅 – group 명 설정
개발환경 세팅 – Web컴포넌트 선택
개발환경 세팅 – 프로젝트 이름 설정
rest-assured 관련 pom.xml 설정 추가
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.0.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-path</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>xml-path</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>3.0.5</version>
<scope>test</scope>
</dependency>
Application - Run
실행 상태 확인
• http://localhost:8080/
* 주의:
Clova 서버 포트는 80 또는 443만 가능
application.properties 에 아래 내용 추가
server.port=80
아주 간단한 Rest API 작성 - Controller
• 코드
• 실행 결과
@RestController
@RequestMapping("/clova")
public class DemoApiController {
@ResponseBody
@RequestMapping(value = "/v1/hello", method= RequestMethod.GET, produces = "application/json" )
public String hello() {
return "hello clova api!";
}
}
http://localhost:8080/clova/v1/hello
첫 RestAssured 테스트 케이스 작성
• src-test-java 밑에 HelloWorldRestAssured class 추가후 아래와 같이 메소드 입력
• 주요 API 설명
• given()
• 입력값 설정 (파라미터, 헤더 등 )
• when()
• get(path) : 지정된 path로 get 요청
• post(path) : 지정된 path로 post 요청
• … 등등
• then()
• 호출 결과 검증 ( statusCode(), body(), equals() 등등…)
@Test
public void naverShouldBeOK() {
given().when().get("/v1/hello").then().statusCode(200);
}
서버가 처리해야할 작업 - 1
• Clova 요청 메시지의 request type에 따라 지정된 포맷의 응답 리턴
• Request type
• LaunchRequest : 익스텐션의 시작 (“짱구박사 시작해줘” 했을 경우)
• SessionEndedRequest : 익스텐션의 종료 (“종료해줘” )
• IntentRequest
• Custom Intent à 개발자 콘솔에 입력한 Intent 와 Slot
• Built-in Intent à
https://developers.naver.com/console/clova/guide/CEK/References/CEK_API.md#cek-api-레퍼런스
서버가 처리해야할 작업 – 2
https://developers.naver.com/console/clova/guide/CE
K/References/CEK_API.md#cek-api-레퍼런스
응답메시지 구조
서버가 처리해야할 작업 – 3
• 멀티턴 처리
• 응답 메시지의 shouldEndSession은 false
• 계속 유지해야 할 값은 sessionAttribute에 담아서 전송
http://stg.developers.naver.com/console/clova/guide/CEK/Guide
s/Build_Custom_Extension.md#DoMultiturnDialog
컨트롤러 api
@RequestMapping(value = "/extension", method= RequestMethod.POST, produces = "application/json" )
@ResponseBody
public ResponseEntity<MyExtensionMessage> weather (@RequestBody Map<String, Object> map) {
Map m = (HashMap)map.get("request");
String type = (String) m.get("type");
MyExtensionMessage mm = null;
if(type.equals("LaunchRequest")) { // extension 시작
mm = new MyExtensionMessage("turnOnIntent", "안녕 짱구 박사를 시작합니다. 제어하려는 전등을 말씀 하세요. ", false, "PlainText");
} else if (type.equals("IntentRequest")) { // extension의 인텐트 시작
Map intent = (HashMap) m.get("intent");
String intentName = (String) intent.get("name");
Map slots = (HashMap) intent.get("slots");
String slotName = "";
String slotValue = "";
if (intentName.equals("turnOnIntent")) {
if (slots != null) {
Map myslot = (HashMap) slots.get("homeSlotType");
slotName = (String) myslot.get("name");
slotValue = (String) myslot.get("value");
System.out.println("slotName===" + slotName);
System.out.println("slotValue===" + slotValue);
}
mm= new MyExtensionMessage("turnOnIntent", slotValue + "의 전등을 켰습니다. ", true, "PlainText");
// Built-in Intent 처리
} else if (intentName.equals("Clova.YesIntent")) {
mm = new MyExtensionMessage(intentName, "예 라고 하셨나요?", true, "PlainText");
} else if (intentName.equals("Clova.NoIntent")) {
mm = new MyExtensionMessage(intentName, "노 라고 하셨나요?", true, "PlainText");
} else if (intentName.equals("Clova.GuideIntent")) {
mm = new MyExtensionMessage("hearTestIntent", "부산 날씨는 어때라고 해보세요", false, "PlainText");
} else if (intentName.equals("Clova.CancelIntent")) {
mm = new MyExtensionMessage("hearTestIntent", "짱구 박사 실행을 취소합니다. 안녕", true, "PlainText");
}
} else if (type.equals("SessionEndedRequest")) { // extension 종료
mm = new MyExtensionMessage("turnOnIntent", "짱구 박사를 종료합니다. ", false, "PlainText");
}
return new ResponseEntity<MyExtensionMessage>(mm, HttpStatus.OK);
}
Extension message 구조
http://developers.naver.com/console/clova/guide/#/C
EK/References/CEK_API.md#message-structure-2
Extension 응답 message 처리 클래스
public class MyExtensionMessage {
public String version = "1.0";
public Map<String, Object> sessionAttributes = new HashMap();
public MyResponse response = null;
public MyExtensionMessage(String INTENT_NAME, boolean session, ArrayList<Map> myResponseValue) {
if(!session) {
sessionAttributes.put("intent", INTENT_NAME);
}
MyResponse response = new MyResponse();
response.shouldEndSession= session;
response.outputSpeech.put("type", "SpeechList");
response.outputSpeech.put("values", myResponseValue);
this.response = response;
}
public MyExtensionMessage(String INTENT_NAME, String message, boolean session, String type) {
// MyResponseValue 객체
Map<String, String> myResponseValue = new HashMap<String, String>();
myResponseValue.put("type", type);
myResponseValue.put("lang", "ko");
myResponseValue.put("value", message);
if(!session) {
sessionAttributes.put("intent", INTENT_NAME);
}
MyResponse response = new MyResponse();
response.shouldEndSession= session;
response.outputSpeech.put("type", "SimpleSpeech");
response.outputSpeech.put("values", myResponseValue);
this.response = response;
}
public static class MyResponse {
public Map<String, Object> outputSpeech = new HashMap<String, Object>();
public Map<String, Map> card = new HashMap<String, Map>();
public ArrayList<String> directives = new ArrayList<String>();
public boolean shouldEndSession = false;
}
}
Api test
private final String LaunchRequest = "LaunchRequest";
private final String IntentRequest = "IntentRequest";
private final String SessionEndedRequest = "SessionEndedRequest";
private final String INTENT_NAME = "turnOnIntent";
private final String SLOT_NAME = "homeSlotType";
@Test
public void extensionShouldReturnLaunchRequest() {
given()
.header("Content-Type", "application/json")
.body(getClovaJson(LaunchRequest, INTENT_NAME, SLOT_NAME))
.when().post("/clova/extension")
.then().body("response.outputSpeech.values.value",containsString("안녕"));
}
@Test
public void extensionShouldReturnIntentRequest() {
given()
.header("Content-Type", "application/json")
.body(getClovaJson(IntentRequest, INTENT_NAME, SLOT_NAME))
.when().post("/clova/extension")
.then().body("response.outputSpeech.values.value",containsString("전등"));
}
@Test
public void extensionShouldReturnEndRequest() {
given()
.header("Content-Type", "application/json")
.body(getClovaJson(SessionEndedRequest, INTENT_NAME, SLOT_NAME))
.when().post("/clova/extension")
.then().body("response.outputSpeech.values.value",containsString("종료"));
}
Api test
private String getClovaJson(String type, String intentName, String slotName) {
String jsonReq = "{n" +
" "version": "0.1.0",n" +
" "session": {n" +
" "sessionId": "ff5db3a3-0f67-4b24-830f-cfa785556a71",n" +
" "user": {n" +
" "userId": "azvjPlQkSCuV8LmItY2VrQ",n" +
" "accessToken": "66e7e019-cda9-4826-acdd-b1671b551e97"n" +
" },n" +
" "new": truen" +
" },n" +
" "context": {n" +
" "System": {n" +
" "user": {n" +
" "userId": "azvjPlQkSCuV8LmItY2VrQ",n" +
" "accessToken": "66e7e019-cda9-4826-acdd-b1671b551e97"n" +
" },n" +
" "device": {n" +
" "deviceId": "4a0307d4-0674-4cdb-890e-be29f049339d"n" +
" }n" +
" }n" +
" },n" +
" "request": {n" +
" "type": ""+ type +"",n" +
" "intent": {n" +
" "name": ""+ intentName +"",n"+
" "slots": {n" +
" ""+ slotName +"": {n" +
" "name": ""+ slotName +"",n" +
" "value": “거실"n"+
" }n" +
" }n" +
" }n" +
" }n" +
"}";
return jsonReq;
}
Clova 앱과 스피커에서 익스텐션 호출 테스트
테스트 단계
• 개발자 콘솔에 test할 네이버 계정 등록
• 음성 테스트 방법1 – Clova 앱
• Clova 앱에 해당 아이디로 로그인 후
• à “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인
• 음성 테스트 방법2 – Friends 스피커
• 테스터로 등록된 아이디로 Clova앱을 이용해서 스피커 설정
• à “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인
Appendix.
• Clova 플랫폼 개발자 문서 : https://developers.naver.com/console/clova/guide/
• Design 챕터 / Clova Extensions Kit 챕터 / Clova Developer Console 챕터 참고
• 튜토리얼 및 샘플 코드 참고
• 샘플 코드 Github
• 마법 구슬 : https://github.com/naver/clova-extension-sample-magicball
• 빗소리 : https://github.com/naver/clova-extension-sample-rainsound
• 주사위 놀이 : https://github.com/naver/clova-extension-sample-dice
• 코인 헬퍼 : https://github.com/naver/clova-extension-sample-coinhelper
Thank you.
교육피드백: http://bit.ly/clova-dev-days
제휴문의: dl_clova_partnership@navercorp.com

More Related Content

What's hot

Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험
Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험
Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험Clova Platform
 
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안Clova Platform
 
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기Clova Platform
 
Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기성일 한
 
Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발Clova Platform
 
Bluemix 23th meetup 실습 자료
Bluemix 23th meetup 실습 자료Bluemix 23th meetup 실습 자료
Bluemix 23th meetup 실습 자료HyeonJeong Jo
 
PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기Changwan Jun
 
티켓몬스터를 위한 PHP 개발 방법
티켓몬스터를 위한 PHP 개발 방법티켓몬스터를 위한 PHP 개발 방법
티켓몬스터를 위한 PHP 개발 방법Young D
 
Dialogflow로 카카오톡 챗봇 만들기
Dialogflow로 카카오톡 챗봇 만들기Dialogflow로 카카오톡 챗봇 만들기
Dialogflow로 카카오톡 챗봇 만들기deepseaswjh
 
iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기iFunFactory Inc.
 
유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기Young D
 
문돌이가 가르치는 서버사이드 PHP
문돌이가 가르치는 서버사이드 PHP문돌이가 가르치는 서버사이드 PHP
문돌이가 가르치는 서버사이드 PHP동현 조
 
Netty 시작하기 (1)
Netty 시작하기 (1)Netty 시작하기 (1)
Netty 시작하기 (1)Daehyun Kim
 
XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기
XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기
XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기XpressEngine
 
xecon-phpfest2014composer
xecon-phpfest2014composerxecon-phpfest2014composer
xecon-phpfest2014composerjhyeon1010
 
PHPStorm - tool for php
PHPStorm - tool for phpPHPStorm - tool for php
PHPStorm - tool for phpSungbum Hong
 
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까영석 양
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드KwangSeob Jeong
 

What's hot (19)

Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험
Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험
Clova Tech Summit 2: 코오롱베니트의 Clova Extension 계정연동 및 IoT 개발경험
 
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
 
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
 
Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기
 
Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발
 
Bluemix 23th meetup 실습 자료
Bluemix 23th meetup 실습 자료Bluemix 23th meetup 실습 자료
Bluemix 23th meetup 실습 자료
 
PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기
 
티켓몬스터를 위한 PHP 개발 방법
티켓몬스터를 위한 PHP 개발 방법티켓몬스터를 위한 PHP 개발 방법
티켓몬스터를 위한 PHP 개발 방법
 
Dialogflow로 카카오톡 챗봇 만들기
Dialogflow로 카카오톡 챗봇 만들기Dialogflow로 카카오톡 챗봇 만들기
Dialogflow로 카카오톡 챗봇 만들기
 
iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기
 
유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기
 
문돌이가 가르치는 서버사이드 PHP
문돌이가 가르치는 서버사이드 PHP문돌이가 가르치는 서버사이드 PHP
문돌이가 가르치는 서버사이드 PHP
 
Netty 시작하기 (1)
Netty 시작하기 (1)Netty 시작하기 (1)
Netty 시작하기 (1)
 
XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기
XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기
XECon2015 :: [1-1] 안정수 - XE3 구조 및 기본기
 
Modern PHP
Modern PHPModern PHP
Modern PHP
 
xecon-phpfest2014composer
xecon-phpfest2014composerxecon-phpfest2014composer
xecon-phpfest2014composer
 
PHPStorm - tool for php
PHPStorm - tool for phpPHPStorm - tool for php
PHPStorm - tool for php
 
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
 
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드
 

Similar to Clova extension A to Z

Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Gosu Ok
 
[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술NAVER D2
 
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...Amazon Web Services Korea
 
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?nexusz99
 
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차Jongwon Han
 
[ETHCon Korea 2019] Kim hyojun 김효준
[ETHCon Korea 2019] Kim hyojun 김효준[ETHCon Korea 2019] Kim hyojun 김효준
[ETHCon Korea 2019] Kim hyojun 김효준ethconkr
 
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...Amazon Web Services Korea
 
현대암호화 통신에서 Ca인증서의 위험성과 중요성
현대암호화 통신에서 Ca인증서의 위험성과 중요성현대암호화 통신에서 Ca인증서의 위험성과 중요성
현대암호화 통신에서 Ca인증서의 위험성과 중요성GooBeom Jeoung
 
NDC17 장창완(최종)
NDC17 장창완(최종)NDC17 장창완(최종)
NDC17 장창완(최종)창완 장
 
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라MinKyu Kim
 
셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영Nalee Jang
 
ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼Jihyun Lee
 
Creating autoscaling web server
Creating autoscaling web serverCreating autoscaling web server
Creating autoscaling web serverSoojin Lee
 
20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debuggingJongwon Han
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성NAVER D2
 
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차Jongwon Han
 
오픈 소스 사용 매뉴얼
오픈 소스 사용 매뉴얼오픈 소스 사용 매뉴얼
오픈 소스 사용 매뉴얼Kenu, GwangNam Heo
 
if kakao dev 2019_Ground X_Session 02
if kakao dev 2019_Ground X_Session 02if kakao dev 2019_Ground X_Session 02
if kakao dev 2019_Ground X_Session 02Klaytn
 
왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법
왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법
왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법HyeonJeong Jo
 

Similar to Clova extension A to Z (20)

Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현
 
[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술
 
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...
 
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
 
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
 
[ETHCon Korea 2019] Kim hyojun 김효준
[ETHCon Korea 2019] Kim hyojun 김효준[ETHCon Korea 2019] Kim hyojun 김효준
[ETHCon Korea 2019] Kim hyojun 김효준
 
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
 
현대암호화 통신에서 Ca인증서의 위험성과 중요성
현대암호화 통신에서 Ca인증서의 위험성과 중요성현대암호화 통신에서 Ca인증서의 위험성과 중요성
현대암호화 통신에서 Ca인증서의 위험성과 중요성
 
NDC17 장창완(최종)
NDC17 장창완(최종)NDC17 장창완(최종)
NDC17 장창완(최종)
 
쉽고 빠르게 접하는 오픈스택
쉽고 빠르게 접하는 오픈스택쉽고 빠르게 접하는 오픈스택
쉽고 빠르게 접하는 오픈스택
 
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
 
셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영
 
ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼ModelSim 기초 매뉴얼
ModelSim 기초 매뉴얼
 
Creating autoscaling web server
Creating autoscaling web serverCreating autoscaling web server
Creating autoscaling web server
 
20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
 
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
 
오픈 소스 사용 매뉴얼
오픈 소스 사용 매뉴얼오픈 소스 사용 매뉴얼
오픈 소스 사용 매뉴얼
 
if kakao dev 2019_Ground X_Session 02
if kakao dev 2019_Ground X_Session 02if kakao dev 2019_Ground X_Session 02
if kakao dev 2019_Ground X_Session 02
 
왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법
왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법
왓슨 컨버세이션으로 챗봇 만들기 ! WCS 활용법
 

More from Clova Platform

Clova ai-business-day-session-3
Clova ai-business-day-session-3Clova ai-business-day-session-3
Clova ai-business-day-session-3Clova Platform
 
Clova ai-business-day-session-4
Clova ai-business-day-session-4Clova ai-business-day-session-4
Clova ai-business-day-session-4Clova Platform
 
Clova ai-business-day-session-2
Clova ai-business-day-session-2Clova ai-business-day-session-2
Clova ai-business-day-session-2Clova Platform
 
Clova ai-business-day-session-1
Clova ai-business-day-session-1Clova ai-business-day-session-1
Clova ai-business-day-session-1Clova Platform
 
Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현Clova Platform
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2Clova Platform
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1Clova Platform
 
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우Clova Platform
 
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기Clova Platform
 

More from Clova Platform (9)

Clova ai-business-day-session-3
Clova ai-business-day-session-3Clova ai-business-day-session-3
Clova ai-business-day-session-3
 
Clova ai-business-day-session-4
Clova ai-business-day-session-4Clova ai-business-day-session-4
Clova ai-business-day-session-4
 
Clova ai-business-day-session-2
Clova ai-business-day-session-2Clova ai-business-day-session-2
Clova ai-business-day-session-2
 
Clova ai-business-day-session-1
Clova ai-business-day-session-1Clova ai-business-day-session-1
Clova ai-business-day-session-1
 
Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
 
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
 
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
 

Clova extension A to Z

  • 1. Clova Extension AtoZ Clova Platform Evangelist 옥상훈 2018-04-27 발표자료: https://www.slideshare.net/ClovaPlatform/
  • 2. 목차 • Clova Platform 개요 • Clova extension 개발 준비 개요 • Clova extension 등록 – 호출명, 서버정보, 배포정보 • 인터렉션모델 등록 • Clova extension 서버 API 개발 • Clova 앱과 스피커에서 익스텐션 호출 테스트
  • 3. Clova Plaform & extension 개요
  • 6. Clova Interface Connect 적용 사례 LG U+ 블루콤 스피커 LG 전자 스마트씽큐 LG전자 가전기기 제어가능IoT 제품 제어가능
  • 7. LG U+ IPTV STB - LG U+ IPTV UHD급 이상의 STB 내 Clova 제공 (2017년 12월 적용) 시청 중, 리모콘 side음성버튼 or (음성) LGU플러스야 로 음성명령 수행 ‘효리네민박 틀어줘’ ‘스릴러영화 추천해줘’전면 검색키> 전체화면모드, 클로바스러운 검색홈으로 제안 Clova Interface Connect 적용 사례
  • 8. Clova Interface Connect 적용 사례 (Friends +) 스피커로 '셋탑을 컨트롤' 할 수 있습니다. 브라운과 샐리에게 "유플티비"라는 호출어로 지시해보세요. "유플티비, 눈물 쏙 빼는 영화 찾아줘" "유플티비, tvN 틀어줘"
  • 10. Clova extension 이란? • Clova 플랫폼에서 작동하는 3rd party 애플리케이션으로서, 예를 들면 음성명령으로 음악을 재 생하거나 쇼핑, IoT기기 제어 등이 가능합니다. • 사용자의 의도(예: 음성명령)에 따라 extension이정확하게 동작할 수 있도록 Clova 플랫폼 내부 적으로 음성인식, 대화분석 등 Clova 인공지능 기술이 적용되어 있습니다.
  • 11. extension으로 무엇을 할 수 있나요? • Extension 종류 • (서비스중) Custom extension: 3rd party 서버에서 제공하는 응답(예: 음성, 이미지 등)을 제공할 수 있습니다. • 예) "팟빵에서 뉴스공장 틀어줘" 라고 하면 "팟빵 extension"이 해당 음원을 들 려줍니다. • (예정) Chatbot extension: 고객이 자주 묻는 질문(FAQ)과 답변을 등록하여 사업자 대신 챗봇이 답변을 하게 하는 extension입니다. • 예) ”네이버고객센터 실행해줘 à 네이버 쇼핑 가격 비교하는 방법 알려줄래?” • (제휴문의) Clova Home extension: IoT 기기제어가 가능 • 예) "클로바, TV 좀 켜줘" 라고 하면 클로바가 TV를 켭니다
  • 12. Clova Extension 예시 • https://blog.naver.com/clova_ai/221199482419
  • 13. Clova extension 사례 – ‘체리쉬’ 모션베드제어 https://www.youtube.com/watch?v=kpkRRLWHySc 대표발화: 1) 체리쉬에게 자자 2) 체리쉬에게 무중력 모드 해줘 3) 체리쉬에게 첫번째 메모리 해줘
  • 14. Clova extension 사례 – ‘배송지킴이’ 택배조회 https://www.youtube.com/watch?v=27NWVG0yhTQ 대표발화: 1) 배송지키미 시작해줘 2) 배송지키미에서 내 택배 조회해줘 3) 배송지키미 내 택배 언제와
  • 15. Clova extension 사례 – ‘라마마’ 연애운 https://www.youtube.com/watch?v=uCqQem8_LyQ 대표발화: 1) 라마마 시작해줘 2) 라마마에게 연애운 물어봐줘 3) 라마마에게 남친 언제생길지 물어봐줘
  • 16. Clova 챗봇 extension 사례 – ‘멍멍이’ 동물소리 번역기 https://www.facebook.com/ClovaAI/photos/a.1639371196371443.1073741828.1637903373184892/1783396565302238/ 대표발화: 1) 멍멍이 시작해줘
  • 18. 마법 구슬(Magic ball) • 개요 • 마법 구슬은 사용자의 물음에 미리 정의해놓은 20가지의 긍정 또 는 부정 표현 중 하나를 응답으로 돌려주는 extension입니다. • 실행 방법 • 마법구슬 시작해줘 à 아무거나 소원, 희망 사항을 얘기하면 됨 • 마법구슬에게 로또 당첨될지 물어봐줘 https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#MagicBall
  • 19. 마법 구슬(Magic ball) • 인터렉션 모델 • 사용자의 발화와 관계없이 응답을 선택해서 내려주기 때문에 interaction 모델이 간단합니다.
  • 20. 마법 구슬(Magic ball) • API 소스코드 • https://github.com/naver/clova-extension-sample-magicball • 익스텐션 응답 • https://github.com/naver/clova-extension-sample-magicball/blob/github-public/intent/answer.go
  • 21. 빗소리(Rain sound) • 개요 • 빗소리는 사용자의 요청에 미리 녹음해둔 빗소리 음원 파일(.mp3)를 클라이 언트가 재생하도록 응답하는 extension입니다. • 사용자는 빗소리를 몇 번 반복해서 들을지 결정할 수 있으며, 이 extension의 interaction 모델은 반복 횟수에 대한 값을 slot으로 정의하고 있습니다. • 클라이언트가 음원을 재생할 수 있도록 응답 메시지에 안내 문구 뿐만 아니 라 AudioPlayer.Play 지시 메시지를 포함시켜 CEK로 보내줍니다. • 실행 방법 • 빗소리 시작해줘 • 빗소리 열어줘 • 빗소리한테 2번 반복해달라고 해줘 https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#RainSound
  • 22. 빗소리(Rain sound) • 인터렉션 모델 • 사용자는 빗소리를 몇 번 반복해서 들을지 결정할 수 있으며, 이 extension의 interaction 모델은 반복 횟수에 대한 값을 slot으로 정의 하고 있습니다.
  • 24. 빗소리(Rain sound) • API 소스코드 • https://github.com/naver/clova-extension-sample-rainsound • 익스텐션 응답 • https://github.com/naver/clova-extension-sample-rainsound/blob/github-public/clova/index.js
  • 25. 주사위 놀이(Dice drawer) • 개요 • 주사위 놀이는 사용자의 요청에 가상의 주사위를 굴려 나온 주사위의 눈과 눈 의 합계를 알려주는 extension입니다. • 굴릴 주사위 개수가 하나인지 두 개 이상 인지에 따라 응답으로 돌려주는 표현 이 달라집니다. • 실행 방법 • 주사위 놀이 시작해줘 • 주사위 놀이에서 주사위 2개 던져줘 • 주사위 놀이에게 5개 굴려달라고 해 https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#DiceDrawer
  • 26. 주사위 놀이(Dice drawer) • 인터렉션 모델 • 사용자는 주사위를 몇 개 던질 지 결정할 수 있으며, 이 extension의 interaction 모델은 주사위 개수에 대한 값을 slot으로 정의하고 있 습니다.
  • 27. 주사위 놀이(Dice drawer) • 인터렉션 모델
  • 28. 주사위 놀이(Dice drawer) • API 소스코드 • https://github.com/naver/clova-extension-sample-dice • 익스텐션 응답 • https://github.com/naver/clova-extension-sample-rainsound/blob/github-public/clova/index.js
  • 29. 코인 헬퍼(Coin helper) • 개요 • 코인 헬퍼는 사용자의 요청에 외부 가상 화폐 거래소에서 제공하는 RESTAPI 를 호출하여 시세 정보를 돌려주는 extension입니다. • 실행 방법 • 코인헬퍼 시작해줘 • 코인헬퍼에서 시세 알려줘 • 코인헬퍼에서 비트코인 시세 물어봐줘 https://developers.naver.com/console/clova/guide/CEK/Examples/Extension_Examples.md#CoinHelper
  • 30. 코인 헬퍼(Coin helper) • 인터렉션 모델 • 사용자는 어떤 거래소의 정보를 이용할지 어떤 가상화폐의 시세를 조회할지 결정할 수 있으며, 이 extension의 interaction 모델은 거 래소와 가상 화폐 종목에 대한 값을 slot으로 정의하고 있습니다.
  • 31. 코인 헬퍼(Coin helper) • API 소스코드 • https://github.com/naver/clova-extension-sample-coinhelper • 익스텐션 응답 • https://github.com/naver/clova-extension-sample-coinhelper/blob/github-public/intent/ask.go
  • 32. Clova extension 개발 준비 개요
  • 33. Clova extension 개발 준비 – 1 (필수) • 익스텐션서버 • REST API 서버로서, Clova platform은 Clova console에 등록한 REST API 서버URL로 응답과 요청을 주 고 받습니다. • Clova platform은 1) 익스텐션 실행 2) 인텐트 실행 3) 익스텐션 종료라는 3가지 type의 요청을 보내고, 익스텐션 서버는 여기에 맞게 응답을 하면 됩니다. • 익스텐션 서버는 https로 외부망으로 통신할 수 있는 서버이어야 하며, 포트는 80 또는 443로만 통신 합니다.
  • 34. Clova extension 개발 준비 – 1 (필수) • 익스텐션서버
  • 35. Clova extension 개발 준비 – 2 (필수) • 인터렉션 모델 • 일종의 대화시나리오와 비슷합니다만, 기계인 익스텐션 서버가 사람의 대화를 이해하여 작동할 수 있 도록 Clova console에 입력하는 문장 및 메타정보들입니다. • 인터렉션 모델에는 사용자로부터 입력될 만한 문장들과 각 문장이 어떤 실행 명령(이를 '인텐트'라고 합니다.)으로 연결될 지를 설정합니다. • 인텐트를 실행할 때 필요한 정보들은 '슬롯'이라는 것으로 정의하여 처리합니다. • 예를 들면, 피자주문하는 익스텐션의 경우 인텐트와 슬롯은 아래와 같습니다. • 예) 사용자의 대화: "페퍼로니 피자 2판 주문해줘" --> 'OrderPizza'라는 이름으로 피자주문 처리용 인텐트로 정 의 • 예) 'OrderPizza'인텐트가 실제 피자를 주문하기 위해 필요한 정보는 '피자명'과 '수량'이며, 이는 각기 'pizzaType', 'pizzaAmount'라는 슬롯으로 정의
  • 36. Clova extension 개발 준비 – 3 (선택) • OAuth 인증 서버 • 만약 익스텐션이 써드파티 계정 인증이 필요하다면 익스텐션 서버 와 함께 OAuth 인증을 구현하셔야 필요합니다. • OAuth 인증 서버는 Clova console 에 등록된 인증정보를 이용하여 인증을 처리하고, 인증이 완료되 면 접근토큰을 반환해야 합니다. • 인증서버 구축 예) 배달의 민족, LG 전자, LGU + 관련 가이드: https://www.slideshare.net/ClovaPlatform/clova-tech-summit-3-clova-extension-oauth-89597569
  • 38. 익스텐션 기본 정보 등록하기 • Clova console에 접속해서 'Clova Extensions Kit'을 클릭한 다음 '새로운 익스텐션 만들기'를 누릅니다. • URL: https://developers.naver.com/console/clova/ • 익스텐션 정보 설정 • type은 Custom Extension으로 선택하고, 나머지 값들도 입력합니다. • 오디오플레이어 사용 여부는 '아니오'로 합니다. '예'로 하는 경우는 음원을 재생하는 경우에 사용합니다.
  • 39. Clova extension 호출명 설정 • 가전기기를 제어하는 Custom extension (이하 '익스텐션') 서비스를 그려 보도록 하겠습니다. • 먼저 익스텐션 실행할 때 부르는 이름, 즉 '호출명'을 정해야하는데, 몇 가지 제 약이 있습니다. • 일반적인 명사는 안됨 (예: 박사 (X) ) • 브랜드나 유니크한 명사가 접목된 단어 가능: (예: 짱구박사(O)) • 혹시나 음성인식이 잘 안되는 경우는 다른 호출명으로 하셔야 할 수 있으니, Clova앱에서 인 식이 잘 되는지 확인해보시길 바랍니다.
  • 40. 서버 연동 설정 • 외부에서 접근가능한 RESTAPI 서버의 endpoint URL을 입력합니다. 계정연결 여부는 '아니요'로 둡니다.
  • 41. 배포정보 설정 • 여기서 테스트용 지시어와 대표 표현 문장은 아까 작동 시나리오에서 나왔던 문장에 호출명을 붙여서 사용자가 테스트할 수 있는 문장을 입력합니다. • 짱구박사를 시작해줘 • 짱구박사에서 거실 전등 켜줘 • 짱구박사에서 거실 전등 꺼줘
  • 43. 익스텐션의 작동 시나리오 • 첫번째는 익스텐션에게 바로 질문하고 답을 받는 것입니다. (싱글턴, single-turn) • 사용자: 클로바, 짱구박사에서 거실 전등 켜줘 • 익스텐션: 거실 전등이 켜졌습니다. • 두번째는 익스텐션을 실행한 다음에 질문하고 답을 받는 것입니다. (멀티턴, multi-turn) • 사용자: 클로바, 짱구박사를 시작해줘 • 익스텐션: 안녕하세요. 짱구박사가 시작되었습니다. 제어하고 싶은 가전기기와 동작 방법 을 말씀하세요. • 사용자: 거실 전등 켜줘. • 익스텐션: 거실 전등이 켜졌습니다.
  • 44. 익스텐션 작동 시나리오 고려사항 • 이제 해야할 일은 시나리오가 클로바 플랫폼에서 작동하도록 하는 것인데요. • 문제는 사용자가 같은 말을 물어보더라도, 위에서 정의한 글자그대로 말하지는 않는다는 점입니다. • 예) 거실 전등 켜줘 • 예) 거실 점등 해줘 • 예) 거실 불켜줘 • 이렇게 같은 의도이지만 다양한 표현을 입력하고 인터렉션 모델에 이러한 여러 문장 케이스들을 잘 정리해놔야 더 똑똑한 익스텐션을 만들 수 있겠습니다.
  • 45. 인터렉션 모델 등록하기 – 슬롯 등록 • 짱구박사는 집안의 지역 IoT기기를 제어 할 것이므로 인텐트는 하나만 등록하면 되 고, 슬롯은 ’집안의 다양한 장소들이'이 되 겠습니다. • 슬롯 등록하기 전에 • 슬롯에는 커스텀 슬롯과 빌트인 슬롯 2가 지가 있습니다. • 빌트인 슬롯은 아래와 같이 사람들이 이미 인지하는 용어들을 모아둔 것으로, 사용하 겠다고 체크하면 편리하게 사용하실 수 있 습니다. • 집안의 다양한 장소들은 커스텀 슬롯 으로 등록합니다. • IOT_TYPE • 거실: 리빙룸 • 안방: 침실 • 부억: 키친 • 베란다
  • 46. 인터렉션 모델 등록하기 – 슬롯 등록 • 슬롯이 등록되면 아래와 같이 나타납니다.
  • 47. 인터렉션 모델 등록하기 – 인텐트 등록 • 우측의 '사용중인 Intent' 옆의 + 버튼을 눌러서 ‘turnOnIntent’입력하고 '만들기' 버튼을 누릅니다. • 사용자 표현 리스트에 사용자들이 입력할 것 같은 대화들을 입력하는데, slot과 의도에 해당하는 문장들은 다양하게 입력합니다. • 문장의 가짓수는 많을 수록 더욱 대화의도 파악은 잘 됩니다. • 거실 전등 켜줘 • 안방 불 켜줘 • 침실 점등 해줘
  • 49. 인터렉션 모델 등록하기 – 인텐트 슬롯 등록 • 사용자 표현 리스트에서 ’거실'이라는 단어를 드래그한 다음 앞에서 입력한 ‘homeSlotType’이란 이름으로 매핑해줍니다. • 매핑이 완료되면 Slot 에 해당하는 글씨들이 아래와 같이 하이라이트 됩니다.
  • 50. 인터렉션 모델 빌드하기 • ‘저장’ 버튼을 누른 다음 • 우측 상단의 '빌드' 버튼을 눌러 인터렉션 모델을 빌드합니다. 빌드가 완료되면 다시 '빌드'라는 버튼으로 바뀝니다.
  • 51. 인터렉션 모델 테스트 • 아직 REST API 서버 개발전이지만, 등록한 인터렉션 모델이 잘 동작하는지 확 인합니다. • '빌드' 버튼 아래에 '테스트'를 누릅니다.
  • 52. 인터렉션 모델 테스트 • 체크할 포인트는 인터렉션 모델에 등록한 문장과 비슷한 문장을 입력하더라도 slot과 intent값을 리턴하는지 확인하는 것입니다. • 예) • 거실 전등 켜줘 (인터렉션 모델에 있는 문장) • 부억 점등 해줘 (인터렉션 모델에 있는 문장과 비슷한 유형이지만, slot 이 다른 문장) • 침실 불 켜줘 (비슷한 문장)
  • 54. 개발 환경 구성 • 개발 도구 • IntelliJ ( with Java ) • 프로젝트 생성 • Spring Initializr로 프로젝트 생성 • 프로젝트 설정 • pom에 api test (rest-assured)에 필요한 dependency 설정
  • 55. 개발환경 세팅 – Spring Initailzr로 프로젝트 생성
  • 56. 개발환경 세팅 – group 명 설정
  • 57. 개발환경 세팅 – Web컴포넌트 선택
  • 58. 개발환경 세팅 – 프로젝트 이름 설정
  • 59. rest-assured 관련 pom.xml 설정 추가 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>3.0.5</version> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>json-path</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>xml-path</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>json-schema-validator</artifactId> <version>3.0.5</version> <scope>test</scope> </dependency>
  • 61. 실행 상태 확인 • http://localhost:8080/ * 주의: Clova 서버 포트는 80 또는 443만 가능 application.properties 에 아래 내용 추가 server.port=80
  • 62. 아주 간단한 Rest API 작성 - Controller • 코드 • 실행 결과 @RestController @RequestMapping("/clova") public class DemoApiController { @ResponseBody @RequestMapping(value = "/v1/hello", method= RequestMethod.GET, produces = "application/json" ) public String hello() { return "hello clova api!"; } } http://localhost:8080/clova/v1/hello
  • 63. 첫 RestAssured 테스트 케이스 작성 • src-test-java 밑에 HelloWorldRestAssured class 추가후 아래와 같이 메소드 입력 • 주요 API 설명 • given() • 입력값 설정 (파라미터, 헤더 등 ) • when() • get(path) : 지정된 path로 get 요청 • post(path) : 지정된 path로 post 요청 • … 등등 • then() • 호출 결과 검증 ( statusCode(), body(), equals() 등등…) @Test public void naverShouldBeOK() { given().when().get("/v1/hello").then().statusCode(200); }
  • 64. 서버가 처리해야할 작업 - 1 • Clova 요청 메시지의 request type에 따라 지정된 포맷의 응답 리턴 • Request type • LaunchRequest : 익스텐션의 시작 (“짱구박사 시작해줘” 했을 경우) • SessionEndedRequest : 익스텐션의 종료 (“종료해줘” ) • IntentRequest • Custom Intent à 개발자 콘솔에 입력한 Intent 와 Slot • Built-in Intent à https://developers.naver.com/console/clova/guide/CEK/References/CEK_API.md#cek-api-레퍼런스
  • 65. 서버가 처리해야할 작업 – 2 https://developers.naver.com/console/clova/guide/CE K/References/CEK_API.md#cek-api-레퍼런스 응답메시지 구조
  • 66. 서버가 처리해야할 작업 – 3 • 멀티턴 처리 • 응답 메시지의 shouldEndSession은 false • 계속 유지해야 할 값은 sessionAttribute에 담아서 전송 http://stg.developers.naver.com/console/clova/guide/CEK/Guide s/Build_Custom_Extension.md#DoMultiturnDialog
  • 67. 컨트롤러 api @RequestMapping(value = "/extension", method= RequestMethod.POST, produces = "application/json" ) @ResponseBody public ResponseEntity<MyExtensionMessage> weather (@RequestBody Map<String, Object> map) { Map m = (HashMap)map.get("request"); String type = (String) m.get("type"); MyExtensionMessage mm = null; if(type.equals("LaunchRequest")) { // extension 시작 mm = new MyExtensionMessage("turnOnIntent", "안녕 짱구 박사를 시작합니다. 제어하려는 전등을 말씀 하세요. ", false, "PlainText"); } else if (type.equals("IntentRequest")) { // extension의 인텐트 시작 Map intent = (HashMap) m.get("intent"); String intentName = (String) intent.get("name"); Map slots = (HashMap) intent.get("slots"); String slotName = ""; String slotValue = ""; if (intentName.equals("turnOnIntent")) { if (slots != null) { Map myslot = (HashMap) slots.get("homeSlotType"); slotName = (String) myslot.get("name"); slotValue = (String) myslot.get("value"); System.out.println("slotName===" + slotName); System.out.println("slotValue===" + slotValue); } mm= new MyExtensionMessage("turnOnIntent", slotValue + "의 전등을 켰습니다. ", true, "PlainText"); // Built-in Intent 처리 } else if (intentName.equals("Clova.YesIntent")) { mm = new MyExtensionMessage(intentName, "예 라고 하셨나요?", true, "PlainText"); } else if (intentName.equals("Clova.NoIntent")) { mm = new MyExtensionMessage(intentName, "노 라고 하셨나요?", true, "PlainText"); } else if (intentName.equals("Clova.GuideIntent")) { mm = new MyExtensionMessage("hearTestIntent", "부산 날씨는 어때라고 해보세요", false, "PlainText"); } else if (intentName.equals("Clova.CancelIntent")) { mm = new MyExtensionMessage("hearTestIntent", "짱구 박사 실행을 취소합니다. 안녕", true, "PlainText"); } } else if (type.equals("SessionEndedRequest")) { // extension 종료 mm = new MyExtensionMessage("turnOnIntent", "짱구 박사를 종료합니다. ", false, "PlainText"); } return new ResponseEntity<MyExtensionMessage>(mm, HttpStatus.OK); }
  • 69. Extension 응답 message 처리 클래스 public class MyExtensionMessage { public String version = "1.0"; public Map<String, Object> sessionAttributes = new HashMap(); public MyResponse response = null; public MyExtensionMessage(String INTENT_NAME, boolean session, ArrayList<Map> myResponseValue) { if(!session) { sessionAttributes.put("intent", INTENT_NAME); } MyResponse response = new MyResponse(); response.shouldEndSession= session; response.outputSpeech.put("type", "SpeechList"); response.outputSpeech.put("values", myResponseValue); this.response = response; } public MyExtensionMessage(String INTENT_NAME, String message, boolean session, String type) { // MyResponseValue 객체 Map<String, String> myResponseValue = new HashMap<String, String>(); myResponseValue.put("type", type); myResponseValue.put("lang", "ko"); myResponseValue.put("value", message); if(!session) { sessionAttributes.put("intent", INTENT_NAME); } MyResponse response = new MyResponse(); response.shouldEndSession= session; response.outputSpeech.put("type", "SimpleSpeech"); response.outputSpeech.put("values", myResponseValue); this.response = response; } public static class MyResponse { public Map<String, Object> outputSpeech = new HashMap<String, Object>(); public Map<String, Map> card = new HashMap<String, Map>(); public ArrayList<String> directives = new ArrayList<String>(); public boolean shouldEndSession = false; } }
  • 70. Api test private final String LaunchRequest = "LaunchRequest"; private final String IntentRequest = "IntentRequest"; private final String SessionEndedRequest = "SessionEndedRequest"; private final String INTENT_NAME = "turnOnIntent"; private final String SLOT_NAME = "homeSlotType"; @Test public void extensionShouldReturnLaunchRequest() { given() .header("Content-Type", "application/json") .body(getClovaJson(LaunchRequest, INTENT_NAME, SLOT_NAME)) .when().post("/clova/extension") .then().body("response.outputSpeech.values.value",containsString("안녕")); } @Test public void extensionShouldReturnIntentRequest() { given() .header("Content-Type", "application/json") .body(getClovaJson(IntentRequest, INTENT_NAME, SLOT_NAME)) .when().post("/clova/extension") .then().body("response.outputSpeech.values.value",containsString("전등")); } @Test public void extensionShouldReturnEndRequest() { given() .header("Content-Type", "application/json") .body(getClovaJson(SessionEndedRequest, INTENT_NAME, SLOT_NAME)) .when().post("/clova/extension") .then().body("response.outputSpeech.values.value",containsString("종료")); }
  • 71. Api test private String getClovaJson(String type, String intentName, String slotName) { String jsonReq = "{n" + " "version": "0.1.0",n" + " "session": {n" + " "sessionId": "ff5db3a3-0f67-4b24-830f-cfa785556a71",n" + " "user": {n" + " "userId": "azvjPlQkSCuV8LmItY2VrQ",n" + " "accessToken": "66e7e019-cda9-4826-acdd-b1671b551e97"n" + " },n" + " "new": truen" + " },n" + " "context": {n" + " "System": {n" + " "user": {n" + " "userId": "azvjPlQkSCuV8LmItY2VrQ",n" + " "accessToken": "66e7e019-cda9-4826-acdd-b1671b551e97"n" + " },n" + " "device": {n" + " "deviceId": "4a0307d4-0674-4cdb-890e-be29f049339d"n" + " }n" + " }n" + " },n" + " "request": {n" + " "type": ""+ type +"",n" + " "intent": {n" + " "name": ""+ intentName +"",n"+ " "slots": {n" + " ""+ slotName +"": {n" + " "name": ""+ slotName +"",n" + " "value": “거실"n"+ " }n" + " }n" + " }n" + " }n" + "}"; return jsonReq; }
  • 72. Clova 앱과 스피커에서 익스텐션 호출 테스트
  • 73. 테스트 단계 • 개발자 콘솔에 test할 네이버 계정 등록 • 음성 테스트 방법1 – Clova 앱 • Clova 앱에 해당 아이디로 로그인 후 • à “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인 • 음성 테스트 방법2 – Friends 스피커 • 테스터로 등록된 아이디로 Clova앱을 이용해서 스피커 설정 • à “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인
  • 74. Appendix. • Clova 플랫폼 개발자 문서 : https://developers.naver.com/console/clova/guide/ • Design 챕터 / Clova Extensions Kit 챕터 / Clova Developer Console 챕터 참고 • 튜토리얼 및 샘플 코드 참고 • 샘플 코드 Github • 마법 구슬 : https://github.com/naver/clova-extension-sample-magicball • 빗소리 : https://github.com/naver/clova-extension-sample-rainsound • 주사위 놀이 : https://github.com/naver/clova-extension-sample-dice • 코인 헬퍼 : https://github.com/naver/clova-extension-sample-coinhelper