Amazon Alexa Skill to talk to your Kegbot


#1

It was a slow week at work and I’ve been playing with my new Amazon Echo Dot, so I figured I’d hook it up to my Kegbot. I can now say “Alexa, ask Kegbot how much beer is left?” and she’ll tell me.

Here is the code: https://github.com/patfreeman/alexa-lambda-kegbot

This implementation is written as an AWS Lambda and requires your VPC to have a VPN or direct connection to your kegbot server, so I’m guessing most people will not find this useful. But it was a fun project for me to learn Lambda and Alexa Skills.

HOME SETUP:
If you don’t have a network set up to allow a Lambda to connect to your kegbot server, here is the code that can be used in a home setup:


#2

I have an echo also, I’ll be following you progress!
Thanks for posting.

Edit: I just had a quick look… Way over my head. lol


#3

The home setup will be easier, but not much. Instead of step 8 where you create the Lambda, you’ll have to make alexa-app-server externally accessible on your home internet connection.


#4

Really awesome, thanks for sharing!


#5

I just added a link to the home setup in the opening post, but here it is as well: https://github.com/patfreeman/alexa-app-kegbot

Sorry @Chuckmc, after writing up the instructions I realized it’s not that much easier.


#6

Just got an Echo Dot. Definitely excited about this!

A couple of clarifications:

  1. The DNS1 entry in 4.iii.d, is this supposed to be my FQDN? For instance: coloradoicculus.noip.me?

  2. The port you’re suggesting on poking in the router, is this supposed to be the same external and internal? For instance, my kegberry is 192.168.2.12 and the port is 8443. Should the external port also be 8443?

  3. When I run the node command, is there any output I can expect? Currently it seems to try to run and stop right away. Sorry, I’m new to Node. It doesn’t seem to be accepting connections, either if I am getting to it via 127.0.0.1 in Lynx, or 192.168.2.12 from inside my router.

Very exciting!


#7
  1. Yes. That DNS name should be your noip FQDN.

  2. For consistency and ease, it’s probably best to keep it the same.

  3. It should output something. For example here is my output.

    [email protected]:~/node_modules/alexa-app-server/api$ node server.js
    Serving static content from: public_html
    Loading server-side modules from: server
    Loaded /home/alexa/node_modules/alexa-app-server/api/server/login.js
    Loading apps from: apps
    Loaded app [alexa-app-kegbot] at endpoint: /alexa/Kegbot
    Listening on HTTP port 8081
    I’m running mine on port 8081. I’m not a node expert either. What version of node are you using?


#8

hopefully you are still around, I’ve gotten to the step of loading node.js and am getting the following

error loading app [/home/moad/node_modules/alexa-app-server/api/apps/alexa-app-kegbot/index.js]: SyntaxError: Invalid or unexpected token

edit: when I run node even with that error I am still able to see the root site

“alexa-app-server is running”

when trying /alexa/kegbot/

Cannot GET /alexa/kegbot/


#9

What version of node are you running?


#10

FWIW, yesterday I successfully deployed the Lambda version of the Alexa skill.

Everything went pretty smooth, but there were a few updates to the instructions found on the Github README:

  • Step 7 should be: "Clone Repo: git clone https://github.com/patfreeman/alexa-lambda-kegbot.git. Currently the URL is incorrectly listed as github.org.

  • I’m not sure if it’s something new with the “config” npm package. But it’s now looking for the config file under a separate config directory with the name of “default.js”. Here’s the tree of the project I zipped and uploaded to AWS
    .
    ├── config
    │ └── default.js
    ├── node_modules
    │ └── [Dependencies installed by NPM]
    ├── index.js
    ├── package.json
    └── package-lock.json

  • For the current methods, the API key is NOT required by default. Doesn’t hurt to have it, but not required to access the api/taps endpoint

  • It appears that it’s required to perform the ZIP operation on a linux box zip -r lambdaFunc.zip . from within the directory with the files. I tried to use the Windows “Send to Compressed (zipped) file” but that did not work. Perhaps a separate app like 7-zip or WinZip would zip it correctly.

  • When I configured my AWS Lambda application, I had a lot of trouble with the VPC configuration. It turns out you do NOT need to configure a VPC for the Lambda function to work. Just leave the Network configuration set to “No VPC”

  • It’s been said before, but in order for this to work you will need to have some type of public internet access to your Kegbot Server.

There were a few other items that I tweaked since Amazon has updated the interface for both Lambda and Alexa Skills development but they were pretty self explanatory. I can certainly help if anyone else tries to get this working.

AWESOME WORK @e2r4!!!


#11

Want to submit a pull request?


#12

Sure, should have something later today.


#13

Strong preference to use lamda rather than self host but I was getting errors from lamda hitting kegbot.

If you are happy to help I’ll get some screens of everything and post tonight.

I found I needed the api key in http requests I make to the API to display tap info on a custom display FYI.


#14

Definitely happy to help, send anything you have and I’m sure we can get this up and running.

As far as the API key, it looks like it is based on the Privacy Setting configured for you Kegbot Server. I currently have mine set to Public so the API Key is not required to hit the /api/taps endpoint. If you have any other privacy setting configured, the API key is required.

I will edit my current Pull Request on Github to include that information.


#15

Excellent. Was going to say that about the auth.

I have mine open on port 80 so wanted to lock it down


#16

ok here goes…

Alexa skill:

Skill ID

amzn1.ask.skill.20422629-4137-xxxx-xxxx-8f593b4b7ada

image

config.js file

I then created the zip file in step 13.

created lambda application and uploaded zip file

Error when testing the skill is

KegBot was unable to connect to the Keg Bot API

edit: Using nodejs 8.1 on my server, changed to 8.1 on the lambda application but no difference.

I don’t really understand the architecture here…

skill talks to lambda which sends the request direct to kegbot? if so, why does it matter what version of node is installed?!

edit again - after installing sdk and other packages I see the zip file is now much bigger so am assuming it bundles up files from the install locally. Will see what I am missing


#17

All of this looks good, and it’s pretty much “working” if you’re getting that “Unable to connect message”, but I believe you’re facing the issue with the config package since as I mentioned in my comment it’s looking for a file within a separate config directory with a file called default.js. My gut feeling is that it doesn’t see the config file so it’s actually not picking up the URL from the config file. Hopefully my pull request with updated instructions will get merged into the main github repo soon, but in the meantime try this.

  1. In your root project directory, create a new folder called config
  2. Move your current config.js file into that folder and rename to default.js
  3. Back in the root project directory, just run node index.js. You shouldn’t get any output, but you also should not get any errors. In my case npm install did not get the “config” package that’s required.
  4. Create the zip file again. In my case, the full zip file size was about 6.38MB.
  5. Re-upload the zip to AWS Lambda and run the test.

If you go to the github repo for the lambda function and look under Pull Requests, you’ll see my updated instructions as well as a script for testing from within the lambda function itself.

As far as architecture, you’re absolutely correct. The Alexa skill fires the Lambda function which makes a web request directly to your kegbot to get a response. The function formats that response into a phrase and sends back to the Alexa Skill which converts to speech and reads back to you. As such, I don’t think the Node version really matters. I’m actually running Node 10.1 on the box I use to configure and zip the files, but leaving set to 4.3 on the AWS side works fine.


#18

fixed that, still not working. Will look at that structure now


#19

nodejs index.js

no errors


#20

jere the test log output from the lambda test

START RequestId: 46ea9361-bda2-11e8-b318-37a84a7c708b Version: $LATEST
2018-09-21T13:28:51.970Z 46ea9361-bda2-11e8-b318-37a84a7c708b { Error: ETIMEDOUT
at Timeout._onTimeout (/var/task/node_modules/request/request.js:849:19)
at ontimeout (timers.js:482:11)
at tryOnTimeout (timers.js:317:5)
at Timer.listOnTimeout (timers.js:277:5) code: ‘ETIMEDOUT’, connect: true }
END RequestId: 46ea9361-bda2-11e8-b318-37a84a7c708b
REPORT RequestId: 46ea9361-bda2-11e8-b318-37a84a7c708b Duration: 1258.71 ms Billed Duration: 1300 ms Memory Size: 128 MB Max Memory Used: 48 MB

I increased timeout to 5 seconds in the default.js file and 6 on lambda function but same error. ill try with privacy off