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
少し変えました
package:
exclude:
- ./**
include:
- ./bin/**
- ./jsons/**
jsonのあたりのコードはこんな感じです。
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編集
けっこう適当なので余計な部分とかあるかもですが。
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
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だけでもできそう。
Author And Source
この問題について(AlexaスキルでGo), 我々は、より多くの情報をここで見つけました https://qiita.com/ikegam1/items/19cb22a65ed02d58d48c著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .