닉 라보이 는 최신 웹 및 모바일 개발 기술을 옹호하는 사람입니다. 자바, 자바스크립트, 골랑, 앵귤러, 네이티브스크립트, 아파치 코르도바 등 다양한 프레임워크에 대한 경험이 있습니다. Nic 웹 및 모바일 개발과 관련된 자신의 개발 경험을 알기 쉽게 풀어쓴 글입니다.
최근에 다음과 같은 튜토리얼을 작성했습니다. AWS 람다 생성 함수와 통신하는 카우치베이스 Go 프로그래밍 언어를 사용한 NoSQL 데이터베이스. 이전 튜토리얼은 표준 서버리스 개발을 기반으로 했지만, 한 단계 더 발전시키고 싶다면 어떻게 해야 할까요? 예를 들어, 대부분의 경우 Amazon Alexa 기반 장치는 AWS Lambda를 활용하여 작동합니다. 그렇다면 우리 함수를 Alexa와 호환되게 만들려면 무엇이 필요할까요?
이 튜토리얼에서는 아마존 알렉사 요청을 처리하고 알렉사가 사용자에게 오디오 메시지를 전달할 수 있도록 적절하게 응답하는 방법을 살펴봅니다. 응답하는 데이터는 데이터베이스에서 가져오며 Go 프로그래밍 언어로 관리됩니다.
아마존 알렉사 지원으로 람다 함수 만들기
아직 제 이전 튜토리얼를 먼저 살펴본 후 계속 읽어보시기 바랍니다. 이전 튜토리얼은 짧지만 Go와 Couchbase로 Lambda 함수를 개발하는 데 필요한 몇 가지 관점을 제공합니다.
이제 **$GOPATH** 내에 **main.go** 파일이 포함된 프로젝트를 생성합니다. 명령줄에서 다음을 실행하여 종속 요소를 다운로드합니다:
1 2 3 4 5 6 7 |
go get github.com/아리엔말렉/알렉사-go go get github.com/aws/aws-람다-go/람다 go get github.com/사토리/go.uuid go get gopkg.in/카우치베이스/gocb.v1 |
종속성 중 Go용 AWS Lambda SDK와 Go용 Couchbase SDK를 다운로드하고 있습니다. 또한 문서 키를 나타내는 고유 값을 생성하기 위해 이전 튜토리얼에서 사용했던 UUID 패키지도 다운로드하고 있습니다. 하지만 이번에는 각 요청과 응답에 대한 모델이 포함된 다른 패키지를 다운로드하고 있습니다. Alexa는 요청과 응답이 모두 특정 JSON 형식일 것으로 예상하며, 이는 Alexa 패키지의 거의 유일한 목적입니다.
main.go** 파일에 다음 상용구 코드를 추가합니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
패키지 메인 가져오기 ( "github.com/arienmalec/alexa-go" "github.com/aws/aws-lambda-go/lambda" uuid "github.com/satori/go.uuid" gocb "gopkg.in/couchbase/gocb.v1" ) var 버킷 *gocb.버킷 유형 Todo 구조체 { ID 문자열 `json:"id,생략"` 텍스트 문자열 `json:"텍스트, 생략"` 유형 문자열 `json:"유형,생략"` } func IntentDispatcher(요청 알렉사.요청) (알렉사.응답, 오류) { var 응답 알렉사.응답 스위치 요청.본문.의도.이름 { case "GetTodosIntent": 응답 = 핸들겟토도스인텐트(요청) case "CreateTodoIntent": 응답 = 처리할 작업 인텐트 만들기(요청) case "AboutIntent": 응답 = 핸들 어바웃 인텐트(요청) } 반환 응답, nil } func 핸들 어바웃 인텐트(요청 알렉사.요청) 알렉사.응답 { } func 처리할 작업 인텐트 만들기(요청 알렉사.요청) 알렉사.응답 { } func 핸들겟토도스인텐트(요청 알렉사.요청) 알렉사.응답 { } func 메인() { 클러스터, _ := gocb.연결("couchbase://HOST_HERE") 클러스터.인증(gocb.비밀번호 인증기{사용자 이름: "todos", 비밀번호: "123456"}) 버킷, _ = 클러스터.OpenBucket("todos", "") 람다.시작(IntentDispatcher) } |
그렇다면 위의 코드에서 무슨 일이 일어나고 있을까요?
다운로드한 종속성을 임포트한 후에는 Todo
데이터 구조가 필요합니다. 앞의 예와 마찬가지로 할 일 목록 정보를 저장하고 해당 정보를 쿼리할 것입니다.
에서 메인
함수를 사용하여 Couchbase 인스턴스에 대한 연결을 설정하고 버킷을 열고 있습니다. Lambda가 이 인스턴스와 상호 작용할 수 있어야 하므로 Couchbase 인스턴스를 어딘가에 호스팅하는 것이 중요합니다. 즉, 로컬 호스트에서 실행 중인 Couchbase로는 테스트할 수 없습니다.
Alexa에서는 인텐트라고 하는 동작에 따라 일이 진행됩니다. 이러한 작업은 일반적으로 Alexa에 대한 요청입니다. 특정 스킬에 대해 일반적으로 다양한 방식으로 Alexa와 상호작용할 수 있으며, 따라서 인텐트도 다양합니다. 스킬에는 AboutIntent
정보를 위해 CreateTodoIntent
데이터 저장을 위한 GetTodosIntent
를 사용하여 데이터를 쿼리하고 사용자에게 반환할 수 있습니다. 이러한 의도는 IntentDispatcher
함수입니다.
저희의 아이디어는 IntentDispatcher
는 Alexa로부터 요청이 들어오는 것입니다. 요청 내에서 Amazon은 정확한 의도를 파악하고 해당 정보를 사용할 수 있습니다. 이 인텐트 정보는 나중에 정의됩니다. 인텐트 정보를 사용하여 올바른 함수를 호출할 수 있습니다.
그럼 이제 AboutIntent
함수입니다:
1 2 3 4 5 |
func 핸들 어바웃 인텐트(요청 알렉사.요청) 알렉사.응답 { 반환 알렉사.NewSimpleResponse("정보", "폴리글롯 개발자인 닉 라보이가 만들었습니다.") } |
함수가 호출되면 Alexa 패키지를 사용하여 응답 형식을 올바른 JSON으로 지정하고 반환할 수 있습니다. 응답에는 제목과 사용자에게 음성으로 응답할 텍스트가 포함됩니다.
이제 CreateTodoIntent
함수입니다:
1 2 3 4 5 6 7 8 9 |
func 처리할 작업 인텐트 만들기(요청 알렉사.요청) 알렉사.응답 { 할 일 := Todo{텍스트: 요청.본문.의도.슬롯["할 일"].가치} 버킷.삽입(uuid.필수(uuid.NewV4()).문자열(), 할 일, 0) 반환 알렉사.NewSimpleResponse("생성된 작업", "추가 `"+할 일.텍스트+"`를 목록에 추가합니다.") } |
디스패처가 위의 함수를 선택하면 슬롯이라고 하는 동적 데이터를 가져와서 Couchbase에 삽입합니다. 슬롯 데이터는 아마존에서 파싱되어 요청 의도와 마찬가지로 요청에 포함됩니다. 작업이 완료되면 슬롯 데이터가 반환되고 Alexa가 이를 음성으로 전달합니다.
최종 함수는 더 길지만 그다지 복잡하지는 않습니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
func 핸들겟토도스인텐트(요청 알렉사.요청) 알렉사.응답 { 토도스 := "" 쿼리 := gocb.NewN1qlQuery("SELECT text FROM `todos` AS todos") 행, _ := 버킷.ExecuteN1qlQuery(쿼리, nil) var 행 Todo 에 대한 행.다음(&행) { 토도스 += 행.텍스트 + ". " } 반환 알렉사.NewSimpleResponse("할 일 목록", 토도스) } |
에서 핸들겟토도스인텐트
를 사용하여 오픈 버킷을 쿼리하고 있습니다. 그 결과로 사용자에게 반환하고 Alexa가 음성으로 말할 데이터 문자열을 구성하고 있습니다.
코드가 완성되었으니 이제 배포에 집중할 수 있습니다.
알렉사 스킬로 람다 기능 배포 및 테스트하기
스킬 스토어에 배포하기 전에 람다용 함수 코드를 준비해야 합니다. 이전 예제와 마찬가지로 Lambda가 사용하는 Linux용 애플리케이션을 교차 컴파일해야 합니다.
명령줄에서 다음을 실행합니다:
1 2 3 |
GOOS=리눅스 go 빌드 zip 핸들러.zip ./바이너리-이름 |
를 변경해야 합니다. 바이너리 이름
를 이전 빌드 명령에서 생성한 실제 바이너리 파일 이름으로 바꿉니다. 빌드 명령을 실행할 수 없는 경우 zip
명령으로 파일을 아카이브하는 것이 가장 좋습니다.
핸들러.zip** 파일을 손에 들고 Lambda 관리 대시보드(https://console.aws.amazon.com/lambda)로 이동하여 기본값을 사용하여 새 함수를 만듭니다. Go 프로젝트를 사용하고 있는지 확인하세요.
트리거의 경우 **Alexa 스킬 키트**를 선택하고 ZIP 파일을 업로드합니다. 핸들러**의 경우 ZIP 파일 이름이 아닌 바이너리 파일 이름을 입력해야 합니다.
마지막으로 주목해야 할 것은 ARN ID입니다. 이 ARN 값은 Alexa를 구성할 때 필요합니다.
이제 Alexa 개발자 콘솔(https://developer.amazon.com/alexa/console)로 이동하여 새 스킬을 만들 수 있습니다. 생성 과정의 일부로 네 가지 작업을 수행해야 합니다:
- 호출 이름
- 인텐트, 샘플 및 슬롯
- 모델 빌드
- 엔드포인트
호출 이름은 스킬 이름과 일치할 필요는 없지만 모든 억양으로 발음할 수 있는 실제 단어여야 합니다. 단어를 지어내거나 복잡한 단어를 사용하는 경우 알렉사가 사람들의 말을 이해하는 데 어려움을 겪을 수 있습니다.
엔드포인트는 이전 단계에서 Lambda 콘솔에서 복사한 ARN입니다. 반드시 붙여넣어야 합니다.
대부분의 작업은 인텐트, 샘플 발화 및 동적 슬롯 데이터를 생성하는 것입니다. Golang 코드에 있는 것과 일치하는 세 가지 인텐트를 만들어야 합니다. 각 인텐트에는 인텐트를 활성화하는 문구 목록이 있어야 합니다.
예를 들어 GetTodosIntent
에는 다음과 같은 샘플 발화가 있을 수 있습니다:
1 2 3 4 5 6 7 |
무엇 는 my 토도스 get me my 목록 무엇 는 on my 할 일 목록 get me my 토도스 |
예제 문구가 많을수록 스킬의 성능이 더 좋아집니다. 기본적으로 샘플은 Alexa가 코드에서 어떤 인텐트를 트리거할지 결정하는 데 도움이 됩니다. 예제 문구는 CreateTodoIntent
는 동적 데이터가 예상되기 때문에 상황이 조금 복잡해질 수 있습니다.
다음 샘플 발화를 살펴보세요:
1 2 3 4 5 |
추가 {할 일} 에 my 목록 저장 {할 일} create {할 일} 에 대한 my 목록 |
다음 사항이 있습니다. {todo}
가 위 샘플에서 제 코드의 슬롯과 일치합니다. 그리고 {todo}
플레이스홀더는 실제로 동적 정보를 위한 변수입니다. 이 정보는 데이터베이스에 저장됩니다. 하지만 어떤 유형의 데이터를 저장할지 정의해야 합니다. {todo}
입니다.
사용자 지정 슬롯 유형을 만들고 몇 가지 값을 지정합니다. 예를 들어 다음과 같이 추가했습니다:
1 2 3 |
씻다 자동차 clean 집 |
전체 목록이 필요하지는 않지만 Alexa의 학습 데이터이며 Alexa가 어떤 유형의 정보를 슬롯 정보로 간주해야 하는지 식별하는 데 도움이 됩니다. 목록에 텍스트가 존재하지 않는다고 해서 Alexa가 이를 인식하지 못하는 것은 아닙니다.
이 시점에서 스킬을 구축할 수 있을 것입니다. 배포하기 전에 테스트 포털에 몇 가지 샘플 문구를 입력하여 실제로 작동하는지 확인해 보세요.
결론
방금 Golang을 사용하여 Amazon Alexa 스킬을 만드는 방법과 카우치베이스 서버. 이것은 제가 이전에 작성한 튜토리얼의 연장선상에 있는 내용입니다, Golang 및 Couchbase NoSQL로 AWS 람다 함수 개발하기.
스킬에 대해서도 주목해야 할 점이 있습니다. 아마존에는 승인을 받기 위해 반드시 있어야 하는 몇 가지 필수 인텐트가 있습니다. 예를 들어 작업 중지 및 취소에 대한 인텐트가 있어야 합니다. 저희는 이를 추가하지 않았지만 동일한 전략을 따를 것입니다.
Golang으로 스킬을 개발하는 다른 예시를 보고 싶으시다면 제 튜토리얼을 확인해보세요, 골랑과 AWS 람다로 알렉사 스킬 빌드하기.