Alexa 기술로 Go

전회( Alexa-hosted 스킬을 사용하여 Alexa 스킬 만들기 ), Go언어로 Alexa 스킬로 만들려고 하고 시작했지만, 도중에서 탈선해 Alexa-hosted 스킬로 흘러 버렸습니다.
다시 Go 언어로. 마지막으로 만든 녀석의 백엔드 부분은 버리는 가정입니다.
그래서 만드는 스킬은 함께.

Go 언어를 Lambda에 배포



그러나, 역시라고 할까 뭐라고 할까, 벌써 하고 있는 분 계시군요.
Alexa 기술을 Go와 Serverless로 작성했습니다.

이대로 하면 대체로 할 수 있지 않을까.
진행하고 있어 막힐 곳이 있으면 기록합니다. 없으면 이 기사에는 공개의 의의 없을지도 모른다.

우선 여기를 참고로 진행
$ serverless create -u https://github.com/serverless/serverless-golang/ -p alexa-kamefood-go
$ cd alexa-kamefood-go
$ vi serverless.yml
$ diff serverless.yml serverless.yml.orig 
25,26c25,26
<   stage: dev
<   region: ap-northeast-1
---
> #  stage: dev
> #  region: us-east-1
57,59d56
<     memorySize: 128
<     events:
<       - alexaSkill
$ go get github.com/aws/aws-lambda-go/lambda

그리고 대략 여기 의 리포지토리의 내용으로 deploy 하면 잘 되었습니다.
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Warning! You are using an old syntax for alexaSkill which doesn't restrict the invocation solely to your skill. Please refer to the documentation for additional information.
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service alexa-kamefood-go.zip file to S3 (10.04 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...................
Serverless: Stack update finished...
Service Information
service: alexa-kamefood-go
stage: dev
region: ap-northeast-1
stack: alexa-kamefood-go-dev
resources: 6
api keys:
  None
endpoints:
  None
functions:
  hello: alexa-kamefood-go-dev-hello
layers:
  None

그리고, alexa-kamefood-go-dev-hello 라고 하는 function 가 되어 있습니다. (function의 명칭 아무래도 좋았기 때문에 hello 그대로입니다..)



테스트해도 보통으로 사용할 수 있다.
결국, 순조롭게 갔습니다.

코드 작성



그런 다음 여기 을 영감하면서 코드를 마무리합니다.
덧붙여 json 읽어 보게 했으므로 serverless.yml 조금 바꾸었습니다

serverless.yml
package:
 exclude:
   - ./**
 include:
   - ./bin/**
   - ./jsons/**

json 근처의 코드는 이런 느낌입니다.

main.go
var (
        // ErrInvalidIntent is error-object
        ErrInvalidIntent = errors.New("Invalid intent")
        FoodJsonFile string = "./jsons/foods.json"
)

.....

        // JSONファイル読み込み
        foods := make(map[string]string)
        bytes, err := ioutil.ReadFile(FoodJsonFile)
        if err != nil {
            log.Fatal(err)
        }
        // JSONデコード
        if err := json.Unmarshal(bytes, &foods); err != nil {
            log.Fatal(err)
        }

        if food, ok := intent.Slots["foodSlot"]; ok {
            if speech, ok := foods[food.Value]; ok {
                speechOutput = speech
            }else{
                speechOutput = "すみません。" + food.Value + "についてはわかりませんでした。他の食べ物の名前を聞いてみてくださいね。ではまた。"
            }
        } else {
            speechOutput = "すみません。わかりませんでした。他の食べ物の名前を聞いてみてくださいね。ではまた。"
        }

encoding/json 를 사용하고 있습니다.
덧붙여 코드에 대해서는 참조원의 라이센스 표기가 없고, 조금 공개하는 것이 회색이므로 공개는 삼가해 둡니다.

신청



실은 Alexa-hosted인 채로 신청을 하고 있었습니다만, 철회하면서, Go의 lambda function의 것과 바꿔 보았습니다.

에서 전환 후 테스트



그래, 괜찮아.
Go 언어의 Lambda function으로 신청해 봅니다.



그래서 이것으로 끝나면 조금 지루하지 않기 때문에 조금 놀아.
git hub에 올리면 마음대로 deploy하고 싶습니다.
aws codestar를 사용해보십시오.

열고 역할 만들기





Go 언어를 선택하고 GitHub 계정과 연동





buildspec.yml 및 template.yml 편집



꽤 적당하기 때문에 불필요한 부분이있을지도 모릅니다.

buildspec.yml
version: 0.2

phases:

  install:
    commands:

      # AWS Codebuild Go images use /go for the $GOPATH so let's symlink our
      # application source code into that directory structure.
      #- ln -s "${CODEBUILD_SRC_DIR}" "/go/src/handler"

  pre_build:
    commands:

      # Make sure we're in the project directory within our GOPATH
      #- cd "/go/src/handler"

      # Fetch all dependencies
      - go get github.com/aws/aws-lambda-go/lambda
      - go get encoding/json
      - go get io/ioutil

  build:
    commands:
      # Build our go application
      - go build -o bin/main main.go
      #- serverless deploy -v
      # Copy static assets to S3, and package application with AWS CloudFormation/SAM
      - aws cloudformation package --template template.yml --s3-bucket $S3_BUCKET --output-template template-export.yml

  post_build:
    commands:
      # Do not remove this statement. This command is required for AWS CodeStar projects.
      # Update the AWS Partition, AWS Region, account ID and project ID in the project ARN on template-configuration.json file so AWS CloudFormation can tag project resources.
      - sed -i.bak 's/\$PARTITION\$/'${PARTITION}'/g;s/\$AWS_REGION\$/'${AWS_REGION}'/g;s/\$ACCOUNT_ID\$/'${ACCOUNT_ID}'/g;s/\$PROJECT_ID\$/'${PROJECT_ID}'/g' template-configuration.json

artifacts:
  type: zip
  files:
    - template-export.yml
    - template-configuration.json

template.yml
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar

Parameters:
  ProjectId:
    Type: String
    Description: AWS CodeStar projectID used to associate new resources to team members
  CodeDeployRole:
    Type: String
    Description: IAM role to allow AWS CodeDeploy to manage deployment of AWS Lambda functions
  Stage:
    Type: String
    Description: The name for a project pipeline stage, such as Staging or Prod, for which resources are provisioned and deployed.
    Default: ''

Globals:
  Function:
    AutoPublishAlias: live
    DeploymentPreference:
      Enabled: true
      Type: Canary10Percent5Minutes
      Role: !Ref CodeDeployRole

Resources:
  hello:
    Type: AWS::Serverless::Function
    Properties:
      Handler: bin/main
      Runtime: go1.x
      Role:
        Fn::GetAtt:
        - LambdaExecutionRole
        - Arn
      Events:
        AlexaSkillEvent:
          Type: AlexaSkill
  LambdaExecutionRole:
    Description: Creating service role in IAM for AWS Lambda
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub 'CodeStar-${ProjectId}-Execution${Stage}'
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [lambda.amazonaws.com]
          Action: sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        -  arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      PermissionsBoundary: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/CodeStar_${ProjectId}_PermissionsBoundary'

필요없는 파일을 깎거나 소스를 넣거나



public이라든지, main-test.go라든지 지웠습니다.
그리고는 소스를 덧쓰기.

github에 push



으로 마음대로 lambda 함수가 만들어집니다.
제대로 움직였습니다.



CodeStar 사용하여 Codepipeline의 세트(CodeCommit or GitHub, CodeBuild, CodeDeploy)가 완전히 만들어진 느낌입니다.
오, 편리.

라고 할까, CodeBuild내에서 Severless FrameWork의 커멘드 쓰면 말하면 Code Build만으로도 할 수 있을 것 같다.

좋은 웹페이지 즐겨찾기