Skip to content

Commit 8951b4c

Browse files
added host-alexa-skill-on-aws-with-serverless
1 parent d65edf6 commit 8951b4c

File tree

2 files changed

+306
-1
lines changed

2 files changed

+306
-1
lines changed
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
---
2+
canonical_url: https://dev.to/aws-builders/setup-an-alexa-skill-with-serverless-1gck
3+
categories: alexa, aws, node, serverless
4+
cover_image: https://source.unsplash.com/featured/?galaxy
5+
date: 2022-05-31
6+
tags: categories: alexa, aws, node, serverless
7+
title: Host Alexa skill on AWS with Serverless
8+
---
9+
10+
*This post first appeared on [dev.to](https://dev.to/aws-builders/setup-an-alexa-skill-with-serverless-1gck)*
11+
12+
Hey all :wave: we are gonna see how to setup an Alexa skill for a trivia related to space events, using the [Serverless](https://serverless.com) framework. It's assumed you are ok with some Alexa fundamentals and certain concepts of AWS such as IAM, Lambda etc. Let's get started.
13+
14+
You may go through this nice [tutorial](https://developer.amazon.com/en-US/docs/alexa/workshops/build-an-engaging-skill/get-started/index.html) if you want to get started with Alexa by building an Alexa hosted skill. What we have done here in this blog is an AWS hosted skill.
15+
16+
## Alexa
17+
Login to the Alexa skill kit [console](https://developer.amazon.com/alexa/console/ask) with your developer account.
18+
19+
You can then create a skill and give it some invocation name.
20+
![Skill invocation name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nl9hd8xcz26tiw2w8x8g.png)
21+
22+
### Intents
23+
I've addedd 2 built-in intents and 2 custom intents, than what gets added by default.
24+
![Added intents](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tdpe0j1y4ty8i4nfdkau.png)
25+
26+
The GetAnswerIntent has the following utterances.
27+
```
28+
it's {date}
29+
I guess it's on {date}
30+
I think the date is {date}
31+
{date}
32+
I'm guessing it's {date}
33+
```
34+
You may add more or modify as you wish. The only slot here is `date` and it is of built-in type AMAZON.DATE.
35+
36+
Likewise the AskQuestionIntent has the following utterances.
37+
```
38+
could you ask me the question please
39+
can you go back to the question
40+
can you ask me the question
41+
question please
42+
go back to the question
43+
next question
44+
Ask question
45+
```
46+
Ensure to save and build the model once all the intents are added.
47+
48+
## IAM
49+
Log in to [AWS](https://console.aws.amazon.com) as a root user, and create a user group
50+
![Create group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ekfw77ben31bnw3o66vw.png)
51+
52+
The user group should be attached by the AWS managed permission policy [AWSCloud9User](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSCloud9User) that allows creating Cloud9 environments. This is not required though, if you are not using Cloud9.
53+
54+
I've then created another custom [policy](https://us-east-1.console.aws.amazon.com/iamv2/home#/policies) with the following [JSON](https://www.serverless.com/framework/docs/guides/providers#using-a-custom-iam-role-and-policy), with the name `ServerlessPolicy` that gives enough permissions for the serverless SDK to deploy using cloud formation stack, and access to other relevant services as listed.
55+
```
56+
{
57+
"Version": "2012-10-17",
58+
"Statement": [
59+
{
60+
"Effect": "Allow",
61+
"Action": [
62+
"apigateway:DELETE",
63+
"apigateway:GET",
64+
"apigateway:PATCH",
65+
"apigateway:POST",
66+
"apigateway:PUT",
67+
"cloudformation:CreateChangeSet",
68+
"cloudformation:CreateStack",
69+
"cloudformation:DeleteChangeSet",
70+
"cloudformation:DeleteStack",
71+
"cloudformation:DescribeChangeSet",
72+
"cloudformation:DescribeStackEvents",
73+
"cloudformation:DescribeStackResource",
74+
"cloudformation:DescribeStacks",
75+
"cloudformation:ExecuteChangeSet",
76+
"cloudformation:ListStackResources",
77+
"cloudformation:UpdateStack",
78+
"cloudformation:ValidateTemplate",
79+
"events:DescribeRule",
80+
"events:PutRule",
81+
"events:PutTargets",
82+
"events:RemoveTargets",
83+
"iam:CreateRole",
84+
"iam:DeleteRole",
85+
"iam:DeleteRolePolicy",
86+
"iam:GetRole",
87+
"iam:PassRole",
88+
"iam:PutRolePolicy",
89+
"iam:UpdateAssumeRolePolicy",
90+
"lambda:AddPermission",
91+
"lambda:CreateFunction",
92+
"lambda:DeleteFunction",
93+
"lambda:GetAccountSettings",
94+
"lambda:GetAlias",
95+
"lambda:GetEventSourceMapping",
96+
"lambda:GetFunction",
97+
"lambda:GetFunctionConfiguration",
98+
"lambda:GetLayerVersion",
99+
"lambda:GetLayerVersionPolicy",
100+
"lambda:GetPolicy",
101+
"lambda:InvokeFunction",
102+
"lambda:ListAliases",
103+
"lambda:ListEventSourceMappings",
104+
"lambda:ListFunctions",
105+
"lambda:ListLayerVersions",
106+
"lambda:ListLayers",
107+
"lambda:ListTags",
108+
"lambda:ListVersionsByFunction",
109+
"lambda:PublishVersion",
110+
"lambda:RemovePermission",
111+
"lambda:UpdateFunctionCode",
112+
"lambda:UpdateFunctionConfiguration",
113+
"logs:CreateLogGroup",
114+
"logs:DeleteLogGroup",
115+
"logs:DeleteSubscriptionFilter",
116+
"logs:DescribeLogGroups",
117+
"logs:FilterLogEvents",
118+
"logs:GetLogEvents",
119+
"logs:PutSubscriptionFilter",
120+
"s3:CreateBucket",
121+
"s3:DeleteBucket",
122+
"s3:DeleteBucketPolicy",
123+
"s3:DeleteBucketWebsite",
124+
"s3:DeleteObject",
125+
"s3:DeleteObjectVersion",
126+
"s3:GetBucketLocation",
127+
"s3:GetObject*",
128+
"s3:ListBucket",
129+
"s3:PutBucketPolicy",
130+
"s3:PutEncryptionConfiguration",
131+
"s3:PutObject",
132+
"sts:GetCallerIdentity"
133+
],
134+
"Resource": "*"
135+
}
136+
]
137+
}
138+
```
139+
140+
So the group is attached to both policies.
141+
![Group permission policies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1og68nmzwtb4achexfd.png)
142+
143+
Once the group is created, add a new user to the group.
144+
![Add user to the group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vuwunoyeivw48k2dmmyd.png)
145+
146+
And don't forget to copy the credentials
147+
148+
## Instance
149+
You may now login to AWS as the new user. Next we need a machine from which we can clone the serverless code and deploy it, for this purpose I would be launching a [cloud 9](https://dev.to/aws-builders/run-svelte-app-on-aws-cloud9-4j5b) instance, so that I can also use it as an online editor. You can use any Linux machine though.
150+
151+
I'd be creating a Cloud9 environment in the Mumbai region, ap-south-1.
152+
![Launch cloud9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eo0ry9tumj2ywurzdpm3.png)
153+
I've choosen t3.small as the instance type, we may go with t2.micro if we want a free tier eligible instance.
154+
155+
Once it's created you shoud see the console.
156+
![Cloud9 environment console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n1ilc88c89ho82sfjd6a.png)
157+
158+
## AWS CLI
159+
AWS CLI comes pre-installed in Cloud9 and it would also have the credentials file
160+
```
161+
serverless-user-1:~/environment $ ls ~/.aws/
162+
credentials
163+
```
164+
We can setup the config though.
165+
```
166+
serverless-user-1:~/environment $ cat ~/.aws/config
167+
[default]
168+
region=ap-south-1
169+
```
170+
171+
## Clone
172+
Let's clone the alexa skill repo [space-events-trivia](https://github.com/networkandcode/space-events-trivia) from github.
173+
```
174+
serverless-user-1:~/environment $ git clone https://github.com/networkandcode/space-events-trivia.git
175+
```
176+
The code we cloned is a set of nodejs functions and is compatible with the serverless sdk.
177+
```
178+
serverless-user-1:~/environment $ cd space-events-trivia/
179+
serverless-user-1:~/environment/space-events-trivia (main) $ ls
180+
AplRender.js GetAnswerIntentHandler.js interceptors.js README.md StartTriviaHandler.js
181+
CancelAndStopIntentHandler.js HelpIntentHandler.js LaunchRequestHandler.js RepeatIntentHandler.js triviaFunctions.js
182+
documents index.js package.json serverless.yml
183+
ErrorHandler.js IntentReflectorHandler.js package-lock.json SessionEndedRequestHandler.js
184+
```
185+
186+
The file [documents/questions.json](https://github.com/networkandcode/space-events-trivia/blob/main/documents/questions.json) contains the list of questions for the trivia, you may modify it as required.
187+
188+
## Packages
189+
The package.json file should tell us the packages we would be using in our code.
190+
![package.json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/36jrhbpnxpjml3jxfscd.png)
191+
192+
Let's install those.
193+
```
194+
serverless-user-1:~/environment/space-events-trivia (main) $ npm i
195+
npm WARN deprecated [email protected]: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
196+
npm WARN deprecated [email protected]: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
197+
198+
added 18 packages, and audited 19 packages in 2s
199+
200+
1 package is looking for funding
201+
run `npm fund` for details
202+
203+
found 0 vulnerabilities
204+
```
205+
206+
## Serverless
207+
We can install the serverless SDK and later deploy the code using it to AWS lambda. We are actually talking about two things here, one the serverless framework/SDK, and two the serverless technology offering from AWS which is Lambda. Instead of writing the functions directly on Lambda we are going to use the serverless SDK with it's constructs to acheieve the purpose in a controlled way.
208+
```
209+
serverless-user-1:~/environment $ npm i serverless -g
210+
```
211+
It should now be installed.
212+
```
213+
serverless-user-1:~/environment $ serverless -v
214+
Framework Core: 3.18.2
215+
Plugin: 6.2.2
216+
SDK: 4.3.2
217+
```
218+
There is a serverless.yml file in our repo, that has our serverless [configuration](https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml), you may modify it according to your setup.
219+
```
220+
serverless-user-1:~/environment/space-events-trivia (main) $ cat serverless.yml
221+
app: space-events-trivia
222+
service: space-events-trivia
223+
224+
frameworkVersion: '3'
225+
226+
provider:
227+
environment:
228+
DYNAMODB_REGION: ${aws:region}
229+
DYNAMODB_TABLE: ${self:service}-users-${sls:stage}
230+
iam:
231+
role:
232+
statements:
233+
- Effect: 'Allow'
234+
Action:
235+
- 'dynamodb:CreateTable'
236+
- 'dynamodb:PutItem'
237+
- 'dynamodb:Get*'
238+
- 'dynamodb:Scan*'
239+
- 'dynamodb:UpdateItem'
240+
- 'dynamodb:DeleteItem'
241+
Resource: arn:aws:dynamodb:${aws:region}:${aws:accountId}:table/${self:service}-users-${sls:stage}
242+
name: aws
243+
region: ap-south-1
244+
runtime: nodejs16.x
245+
stage: dev
246+
247+
functions:
248+
handler:
249+
handler: index.handler
250+
events:
251+
- alexaSkill: amzn1.ask.skill.${param:alexaSkillId}
252+
```
253+
The org is missing in the configuration, we can specify that while deploying. We have also given permissions for the lambda function on DynamoDB incuding the create table permission, so that the lambda function can create the table if it doesn't exist.
254+
255+
## Deploy
256+
Let's deploy the function, for which first login to serverless.
257+
```
258+
$ serverless login
259+
? Which would you like to log into? Serverless Framework Dashboard
260+
Logging into the Serverless Dashboard via the browser
261+
If your browser does not open automatically, please open this URL:
262+
https://app.serverless.com?client=cli&transactionId=<some-id>
263+
```
264+
Once logged in via the browser, you should see this screen.
265+
![Serverless logged in](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ga38coaffss3am7cm3m.png)
266+
267+
That's it, time to deploy.
268+
```
269+
$ serverless deploy --org <your-org> --param="alexaSkillId=<id>"
270+
```
271+
You have to mention your org and alexaSkillId before running the command above. The org name is something you created in serverless while signing up the account, and you can get the skill ID from the alexa developer console, so that it gets mapped with `alexaSkill: ${param:alexaSkillId}` in [serverless.yml](https://github.com/networkandcode/space-events-trivia/blob/main/serverless.yml)
272+
![Copy skill id](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/op4lygzb3faoxw7tqj85.png)
273+
274+
The function should get successfully deployed by now. The serverless dashboard should show a successful status with green color.
275+
![Service deployed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wnmy9bgr9lld3bfbh9yx.png)
276+
277+
## Endpoints
278+
You can get the lambda endpoint straight from the Serverless CLI.
279+
```
280+
$ serverless info --param="alexaSkillId=<your-skill-id>" --verbose
281+
service: space-events-trivia
282+
stage: dev
283+
region: ap-south-1
284+
stack: space-events-trivia-dev
285+
functions:
286+
handler: space-events-trivia-dev-handler
287+
288+
Stack Outputs:
289+
HandlerLambdaFunctionQualifiedArn: <lambda-arn>
290+
EnterpriseLogAccessIamRole: <role-name>
291+
ServerlessDeploymentBucketName: <bucket-name>
292+
293+
Want to ditch CloudWatch? Try our new console: run "serverless --console"
294+
```
295+
You can copy the lambda ARN from the output above except the suffix which is a number, and set it as an endpoint in the Skill settings in Alexa developer console. It should have the format `arn:aws:lambda:<region>:<account-id>:function:<function-name>`. I've just added it for the default region.
296+
![Set endpoint](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y68ygulez2hykdejg0il.png)
297+
298+
The skill could now be tested from the test window.
299+
![Skill test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24s9oh4zxftkufnpnskn.png)
300+
301+
You can also test :test_tube: the skill from an Alexa device that's using the same account as your developer account.
302+
303+
Alright then, that's it for now, thanks for reading !!!
304+
305+
Image credit: [unsplash](https://source.unsplash.com/featured/?galaxy)

_posts/2022-06-30-trying-my-hands-on-neo4j-with-some-iot-data.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ tags: cypher, graphdb, iot, neo4j
66
title: Trying my hands on Neo4j with some IoT data
77
---
88

9-
* This post first appeared on [dev.to](https://dev.to/networkandcode/trying-my-hands-on-neo4j-with-some-iot-data-28g7) *
9+
*This post first appeared on [dev.to](https://dev.to/networkandcode/trying-my-hands-on-neo4j-with-some-iot-data-28g7)*
1010

1111
## Introduction
1212

0 commit comments

Comments
 (0)