Election Night

Being the political junkie that I am, I can't wait for Election Night! Problem is, the media never presents the data as I want to consume it. So, I'm going to try to write an app to show me the data the way I want it.

Components of the solution

iOS App

Because it's my wheelhouse, I'll write an iOS app to display the content. I've already found a couple of libraries to display maps and bar charts. After some thought, I've decided it would be better to write a general purpose app that displays any data it gets from the cloud, rather than have logic in the app that I won't be able to update without re-submission to the app store.

Cloud Backend

Time to experiment with AWS! I think I'll have some Lambda code that processes the current data and provides it to the iOS App for display. It could just as easily provide it to a web or Android front end. So I'll probably need a noSQL DB to store the data, some Lambda code to convert the data into JSON for transmission to the app, and some more Lambda code to handle the cloud API.

Data Console

I'll need some way to enter and manage the election results data. DynamoDB has some sort of dashboard, which may be good enough. 

Scraper

If I have time, I'd love to write a scraper (maybe also a Lambda Function?) that scrapes the current data from a website. Risky to depend on, though, as I can imaging it might not be easy to write, because the media doesn't want to make it easy to give you the data.

Off to the races!

AWS GoT Hack: Target Intent(s)

Read More

AWS GoT Hack: Lambda Code

To recap, I'm working on a 48-hour hack to help learn about AWS.  My goal is to:

Create a "Game of Thrones" Alexa Skill that allows the user to ask if a character is alive or dead, and responds with an accurate answer.

In the previous post, I created a Git repo in AWS CodeCommit. I'll use this repo to hold the code for the Lambda function, and other assets, e.g. the Alexa Skill's sample utterances and intent schema.

Lambda Code

Lucky for me, there is lots of sample Lambda code for Alexa Skills. "Hello World" seems to be a good place to start.

CodeCommit Detour...

So I copied the hello world code, committed it (commit early, commit often), and tried to push it. The push failed. Back to the CodeCommit docs, and I find that there is a 15 minute timeout on the credentials by default. So, I ended up having to configure SSH anyway. Sometimes just do the right thing, even if it takes a few extra minutes, eh?  

BTW, if you aren't already doing it, check out git-flow. You'll be glad you did. 

Back to the Lambda code...

The lambda code is broken into two files:

  • AlexaSkill.js, which provides generic helper functions
  • index.js, which contains the custom code for your Alexa Skill

Steps to adapt index.js for my needs:

  • Get the Application Id from the Amazon Skill console and paste it into "APP_ID"
  • Rename "HelloWorld" to "GoTWikia"
  • Update the onLaunch "speechOutput" and "repromptText" variables as appropriate.
  • Make a similar change in intentHandlers to response.ask() under AMAZON.HelpIntent.
  • In intentHandlers, add my planned response under "AttributionIntent":
    • "My data comes from the Game of Thrones Wikia at gameofthrones.wikia.com"

That should be about it for the code.  Let's give it a try.

Uploading Lambda code

To upload the code, I first zip the two files together, and then head back to the Lambda dashboard, where I upload and save it. Simple.

Test the Alexa Skill

Once the code is there, we can return to the Alexa console and test it. Type in one of our sample utterances: "where do you get your data" and see what happens.  I got this:

The remote endpoint could not be called, or the response it returned was invalid.

So, which was it? On to debugging! For that, we get to use AWS CloudWatch.

CloudWatch

CloudWatch does a number of things. What I want to do now is look at logs. And what I see is:

Syntax error in module 'index': SyntaxError
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)

Well, duh. Maybe I should have used an IDE or run a syntax checker before uploading the code.

Looks like I forgot to put quotes around my application ID. Fix it, compress the files, upload and test again.

Voila! The Lambda response is:

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "My data comes from the Game of Thrones Wikia at gameofthrones.wikia.com"
    },
    "shouldEndSession": true
  },
  "sessionAttributes": {}
}

Which looks right, and when I push the "Listen" button, Alexa plays it just as expected. Yay!

In the next post, I'll add our other question ("Is {{name}} [[alive|dead]]?") to the skill and Lambda code. 

AWS GoT Hack: CodeCommit

To recap, I'm working on a 48-hour hack to help learn about AWS.  My goal is to:

Create a "Game of Thrones" Alexa Skill that allows the user to ask if a character is alive or dead, and responds with an accurate answer.

In the previous post, I set up the AWS Lambda function that backs up the Alexa skill. But I didn't populate the code, because I want to set up a code repository first, and for that I'm going to use AWS CodeCommit.

CodeCommit

CodeCommit provides secure Git repositories in the cloud. So does Github, of course. What I'm curious about is how CodeCommit interacts with other AWS services.  I expect it takes advantage of IAM. I hope it can trigger Lambda functions and perhaps automated code deployment services.

I created a new repository and called it "GameOfThronesWikiaSkill". And I cloned it to my local drive (using HTTPS, BTW, just cause it is easier than setting up SSH keys)  Well, I thought it would be easier. But I hadn't finished the "prerequisites":

  1. Create an IAM user and download its credentials
  2. Attach "AWSCodeCommitFullAccess" policy to new user.
  3. Install the AWS Command-Line Interface (CLI). I had to download and run the bundled installer.
  4. Configure AWS CLI.
  5. Configure Git

Now I can clone the repo. I kinda hate this kind of setup...

OK, now I have a repo. Creating the repo was easy, and so was cloning it. Setup sucked, although AWS had really good instructions for going about doing it.

Triggers

I'm not going to do anything with them right now, but CodeCommit has triggers for Lambda functions and Amazon SNS "topics".  I can create triggers for select branches, and a few events: push, or adding or deleting a branch or tag.  I'm sure I can figure out how to use those triggers to automate deployment. although I'm guessing I could create triggers from Github to do the same.

OK. So now I have a repo. I'll add code to it in the next post.

 

AWS GoT Hack: Lambda Function

To recap, I'm working on a 48-hour hack to help learn about AWS.  My goal is to:

Create a "Game of Thrones" Alexa Skill that allows the user to ask if a character is alive or dead, and responds with an accurate answer.

In the previous post, I created most of the very simplest implementation of our Alexa Skill.  Now we need to go write the code that backs up that skill. We'll be using AWS Lambda.

One creates a Lambda function from the Lambda Management Console. I'll skip the blueprint and configure the trigger to be the "Alexa Skills Kit".

Configuration

The configuration page is a bit more complex:

  1. I'll name the function "GoT-Skill"
  2. I'll use the Node.js runtime. 
  3. When I actually start coding, I'm going to upload a .ZIP file, rather than enter the code into a form field. However, just to get the function set up, I'm going to leave the template code here.
  4. I'll create a basic execution role.
    1. "Create a new IAM Role"
    2. Name it "LambdaBasicExecution"
    3. Hit "Allow"
    4. Launch IAM Management Console
    5. Select "LambdaBasicExecution"
    6. Hit "Attach Policy"
    7. Select "AWSLambdaBasicExecutionRole"
    8. Hit "Attach Policy" 
    9. Select "Choose an existing Role" and "LambdaBasicExecution". I had to wait a minute or so for the new role to appear.
  5. I'll leave the Advanced settings the way they are.
  6. Review the function and accept it.

OK, so now I have a very basic Lambda function that really does nothing.  But, at the top of this page I do have something I need: the ARN. I'll copy that, go back and paste it into my Alexa Skill.

Testing Alexa Skill

Now I can test my Alexa Skill. I'll enter an utterance ("where do you get your data") and see what happens.

The request JSON shows that the utterance is mapping correctly to the "Attribution" intent, but the response is:

The remote endpoint could not be called, or the response it returned was invalid.

Well, that actually makes sense as I haven't actually added any code to the template. I should go do that.

Lambda Code

Before I start writing code, I want to create a repo in which to store that code. I could do that using Github, but I'm trying to use a lot of AWS services, so I'm going to try AWS CodeCommit in the next blog post.