Writing an Alexa skill using Ruby and AWS Lambda

2020-12-03



What we’re doing

This post gets us started with AWS SAM and creates a demo hello world lambda function using Ruby.

Prerequisites

Follow the instructions listed in AWS SAM explaining how to

  • Create an AWS account:
  • Configure IAM permissions.
  • Install Docker. Note: Docker is only a prerequisite for testing your application locally.
  • Install Homebrew.
  • Install the AWS SAM CLI.

At the end of this step, you should be able to successfully run sam --version at the command line and get back something like ‘SAM CLI, version 1.13.2’.

Creating a Hello world app

Follow the instructions in the tutorial to deploy a ‘hello world’ app to AWS (don’t forget to select Ruby), or follow here:

Start by

sam init

Enter the highlighted data as you’re prompted, selecting your own name for the app, of course:

image info

At the end of this process, something like this would have been displayed:

image info

Now run (substituting your app’s name):

cd lambda-alexa-myinfo
bundle

At this stage, the app is ready to be run locally, tested, or to be deployed.

Running locally

sam local start-api will start a local instance at ‘localhost:3000’, and you can reach it by curl localhost:3000/hello-world, you will get a 403 authentication error.

The better way to test this is to issue sam local invoke that will create an image and run its container locally for testing:

image info

Running tests

sam init also created a test in tests/unit. To run them using Rake, create a Rakefile at the root of the project and paste the following into it:

require 'rake/testtask'

task default: "test"
Rake::TestTask.new do |task|
  task.pattern = 'tests/**/test_*.rb'
end

Save the file and issue rake at the command line.

If the test fails, I think it’s because HTTParty is called with a failing expectation. I did not see the value in this and faked out the mock call to HTTParty. Comments welcome!

def test_lambda_handler
  HTTParty.expects(:get).with('http://checkip.amazonaws.com/').returns(mock_response)
  response = HTTParty.get('http://checkip.amazonaws.com/')
  response.body
  response.code
  assert_equal(lambda_handler(event: event, context: ''), expected_result)
end

Deploying the app

Issue sam build, and answer the questions as per your environment. Note that I am skipping the auth question:

image info

Using the URL given to us at the end of the output, we can curl for the response:

curl https://<your path here>.execute-api.us-east-1.amazonaws.com/Prod/hello/

and visit that address using a browser.

What happened with my AWS account?

Once deployed, these will be the visible changes to your account:

  • A new S3 bucket was created to hold the source code and template.
  • A lambda function was created and registered.
  • An API Gateway was created to route requests to the function.
  • CloudFormation stacks

What’s next?

Wire up functions to handle Alexa requests



Other Tags

API GW
AWS
ActiveRecord
Agile
Alexa
Analysis
Ansible
BDD
BLE
C
CAB
CloudFormation
CloudFront
CloudWatch
Cross-compile
Cucumber
DevOps
Devops
DotNet
Embedded
Fitbit
GNU
GitHub Actions
Governance
How-to
Inception
IoT
Javascript
Jest
Lambda
Mac OS X
MacRuby
Metrics
MySQL
NetBeans
Objective-C
PMO
Product Management
Programme management
Project Management
Quality Assurance
Rails
Raspberry Pi
Remote compilation
Remote debugging
Remote execution
Risk Assessment
Route 53
Ruby
S3
SPA
Self Organising Teams
SpecFlow
TDD
Unit testing
VSM
Value
arm
contract testing
inception
nrf51
pact
planning
rSpec
ruby
ssh