Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Into The Box | Alexa and ColdBox Api's

111 views

Published on

Gavin Pickin

Published in: Software
  • Be the first to comment

  • Be the first to like this

Into The Box | Alexa and ColdBox Api's

  1. 1. Alexa & ColdBox APIs Gavin Pickin Into the Box 2018
  2. 2. What do you need to start building for Alexa? ● Amazon Developer Account ● AWS Services Account ● Look at Github Alexa Repos
  3. 3. Create a AWS Developer Account https://developer.amazon.com/alexa Login with your Amazon login and then register
  4. 4. Create a AWS Developer Account App Distribution Agreement
  5. 5. Create a AWS Developer Account Payments
  6. 6. Setup your AWS Services Account ● https://aws.amazon.com/ ● Does require a credit card ● Does have a free tier which is great Nothing we will be doing here, will incur a cost.
  7. 7. Alexa Github Repos ● https://github.com/alexa ● Lots of great examples and templates. ● The Repos have a lot of the getting started information in them
  8. 8. Starting Our First Alexa Skill ● Login at https://aws.amazon.com/ with your AWS Services account ● We are going to start with Lambda, so go to Services and click on Lambda under the Compute heading. ● Click ‘Create a function’ on the Lambda page.
  9. 9. Lambda - Node Yes Brad, we’re going to look at writing a Lambda in NodeJS.
  10. 10. Select a Blueprint
  11. 11. Pick the Alexa-skill-kit-sdk-factskill
  12. 12. How to get your Skill ID Later when we have created our Alexa Skill, if you pick a Lambda endpoint, you will see this. Copy this and come back here to update your Skill ID
  13. 13. Configure the Alexa Skill in Developer Portal
  14. 14. Create the new Skill
  15. 15. Choose a model to add to your Skill
  16. 16. Add Invocation Name
  17. 17. But I’m a programmer ● You don’t like using a mouse? ● Can’t handle typing and clicking and waiting? Don’t fret, there is a JSON editor, so we can cheat a little. Lets get some JSON from the Alexa Github repos https://github.com/alexa/skill-sample-nodejs-fact
  18. 18. JSON Editor Simple JSON Very Clear Formatting Quicker than the User Interface BUT You have to know the format
  19. 19. Now our Intents are loaded
  20. 20. Check out all of our Utterances
  21. 21. Lets Skip the interfaces - Advanced
  22. 22. Selecting our Endpoint
  23. 23. Select the Lambda we already created Copy the Amazon Resource Name ARN from AWS services
  24. 24. Enter the ARN in your Default Region
  25. 25. Build your Model Click the Build Model option from the checklist When you click on a step now you will see something like this
  26. 26. Build Successful Once the build is successful, you’ll see a notification like this one pop up.
  27. 27. Testing your Skill
  28. 28. Adding Slots Adding slots into your utterances really give your Alexa App power. You can pass information into your endpoint with these slots, and customize the experience. Alexa ask Forgebox how many hits does {kiwiSays} have? These are similar arguments to your function. Note: there were some difficulties with slots.
  29. 29. Slot Requirements and Confirmation For a given Slot, you can set it as required. This allows you and Alexa to ask for this slot directly to ensure you have all the data you need. You can also confirm a slot. You can tell Alexa what to ask, what to expect in response and how to confirm. Alexa: What package would you like me to lookup? You: KiwiSays or Lookup KiwiSays Alexa: Ok, so you want me to lookup KiwiSays? You: Yes
  30. 30. Issues with Slots Alexa does not automatically process the Dialog for you. You get a list of the slots, but they are not always defined. An error in your Lambda can break your skill. You should be able to return a Dialog.delegate and then Alexa will process until complete… but I had issues with this.
  31. 31. Building a REST API to talk to ● We will be looking at ColdBox REST today ● Its easy to add onto existing ColdBox Apps ● Or start a new app with our AdvancedScript or REST skeleton ● REST Template does most of the REST boilerplate for you ● You can just do your thing
  32. 32. Scaffold our App CommandBox has a lot of create commands, today we’ll use the ColdBox Create App command. We could specify a skeleton to use when creating the ColdBox app so we can hit the ground running. We could use the REST Skeleton which you can find out more about here: https://www.forgebox.io/view/cbtemplate-rest You could make your own template and use that from ColdBox Create App ( even if it wasn’t coldbox ) The default is advancedScript - which is fine for this example.
  33. 33. Run our CommandBox command Coldbox create app name=myAPI skeleton=rest This will download the REST template, and do a box install. Start commandbox and you’ll see your first API response. http://127.0.0.1:55944/ { "data": "Welcome to my ColdBox RESTFul Service", "error": false, "messages": [] }
  34. 34. Lets create a new Handler for Forgebox component extends="handlers.BaseHandler"{ function downloads( event, rc, prc ){ event.paramValue( "slug", "kiwisays" ); var result = ""; cfhttp( method="GET", charset="utf-8", url="https://www.forgebox.io/api/v1/entry/#rc.slug#", result="result" ); var jsonResponse = deserializeJSON( result.filecontent ); if( jsonResponse.error ){ prc.response.setError( true ); prc.response.addMessage( "Error finding Slug" ); } else { prc.response.setData( jsonResponse.data.hits ); } }
  35. 35. Lets create a RESTful Route Add this to your routes file: /config/routes.cfm addRoute( pattern = "/forgebox/entry/:slug/:action", handler = "forgebox" );
  36. 36. Reinit App and Test the endpoint Reinit the app http://127.0.0.1:55944/?fwreinit=1 Test the endpoint http://127.0.0.1:55944/forgebox/entry/kiwisays/downloads { "data": 1432, "error": false, "messages": [] }
  37. 37. Why are we using a API to call an API Short Answer: NODE Using a Lambda, you are using Node. Node doesn’t support http and https requests natively, so you install a module for that. HTTPS is a great tool, BUT if you want to hit an HTTPS site, you have to manually install the SSL cert. So you can load files on the fly to make the call… or you can call a ColdFusion API and let cfhttp do it for you :)
  38. 38. Node isn’t always better That comment made Brad happy
  39. 39. Create a Lambda for API Call Here is a Gist of a lambda function https://gist.github.com/gpickin/4a57d996df15079abb7b7136e25bf414
  40. 40. Parts of the Lambda - Handlers Handlers work just like an MVC framework. This index.js file gets the call, and decides how to return to it. const handlers = { 'LaunchRequest': function () { this.emit('forgeboxDownloads'); },
  41. 41. Parts of the Lambda - ForgeboxIntent & Slots Slots are available in a struct. Warning - if that slot was not provided, an undefined will force the lambda to return an null response. BOOM 'forgeboxDownloads': function () { let slug = "kiwisays"; slug = this.event.request.intent.slots.slug.value;
  42. 42. Parts of the Lambda - Setup the API Call // npm install http in CLI and then require it const http = require('http'); // Setup the options for the HTTP request const options = { hostname: 'edf6f5f8.ngrok.io', port: 80, path: '/forgebox/entry/' + slug + '/downloads', method: 'GET' };
  43. 43. Parts of the Lambda - Make API Call // Store this for inside of closure const $this = this; // Make the request const req = http.request(options, (res) => { res.setEncoding('utf8'); res.on('data', function (chunk) { //console.log('BODY: ' + chunk); const bodyString = chunk; const bodyObject = JSON.parse( chunk ); // process the json }); });
  44. 44. Parts of the Lambda - Process the API Response if( bodyObject.error ){ const speechOutput = 'Error loading data'; $this.response.cardRenderer(SKILL_NAME, speechOutput); $this.response.speak(speechOutput); $this.emit(':responseReady'); } else { const speechOutput = GET_FACT_MESSAGE + 'The package with the slug ' + slug + ' has ' + bodyObject.data + ' hits'; $this.response.cardRenderer(SKILL_NAME, 'The package with the slug ' + slug + ' has ' + bodyObject.data + ' hits'); $this.response.speak(speechOutput); $this.emit(':responseReady'); }
  45. 45. Parts of the Lamba - Catch API Errror req.on('error', (e) => { console.error(e); const speechOutput = 'Error loading data'; $this.response.cardRenderer(SKILL_NAME, speechOutput); $this.response.speak(speechOutput); $this.emit(':responseReady'); });
  46. 46. Parts of a Lambda - Close the Connection // Node gives you the tools, but you have to do everything yourself… including close the request req.end();
  47. 47. Let’s Test it with Alexa ask gavin the amazing how many hits does commandbox-migrations have ● Ask - prefix to Invocation name ● Gavin the amazing - the Invocation name ● How many hits does {slug} have - Utterance to call forgeboxIntent ● Commandbox-migrations - this is the slot called slug This will call our Lambda function
  48. 48. Let’s Test it with Alexa
  49. 49. Why are you using Node?? Brad No like Node :)
  50. 50. Alexa SDK There are SDKs for NodeJS, Java etc, but not CFML…. But that’s ok. They have a JSON version you can setup with an HTTPS endpoint. Thanks to Steve Drucker’s repo, we had a solid starting point https://github.com/sdruckerfig/CF-Alexa Note: I had to make a lot of changes to get it to work.
  51. 51. Alexa.cfc This is the base object, with the core functions you need to interact with Alexa Included Functions: ● say() ● setTitle() ● setText() ● setImage() ● And many more. To use this, you extend Alexa.cfc in your Service ( AlexaBot in this example )
  52. 52. AlexaBot.cfc This is your template for your service. Define your Intents Create functions to handle your incoming Intents Functions respond to Alexa with JSON returns Alexa.cfc handles the DSL to do the hard work for you.
  53. 53. AlexaBot.cfc - Update your Intents First edit your intents this.intents = { "testAPI" = "testAPI", "makeMeAMeme" = "makeMeAMeme", "AMAZON.HelpIntent" = "onHelp", "AMAZON.CancelIntent" = "onStop", "AMAZON.StopIntent" = "onStop", "AMAZON.NoIntent" = "onStop", "AMAZON.YesIntent" = "onContinue" }
  54. 54. AlexaBot.cfc - Add function to respond Use the Alexa DSL to respond to Alexa Your response can set the Alexa CARD with title & text and/or Speech public void function testAPI( ){ say( "Coldbox is ICE cold" ); setTitle( "How cool is Coldbox?" ); setText( "Coldbox is ICE cold" ); }
  55. 55. AlexaBot.cfc - Use slots as arguments public void function makeMeAMeme( memeTemplate="", lineOne="", lineTwo="" ){ if( memeTemplate == "" ){ say( "What meme template would you like?" ); } }
  56. 56. Setup the API Route for Alexa Add to your routes file { pattern = "/alexa", handler = "Main", action = { GET = "alexa", POST = "alexa" } },
  57. 57. Setup the API Handler for Alexa function alexa( event, rc, prc ){ var content = getHttpRequestData().content; var alexaBot = new models.Alexa.alexabot(); // or use wirebox with getInstance() prc.response.setData( alexaBot.get( content ) ); prc.response.setRaw( true ); // New to REST response model }
  58. 58. Test the API Endpoint Return to the Alexa Developer Tools You: ‘ask gavin the cool how cold is coldbox’ Alexa: ColdBox is ICE cold You: ‘ask gavin the cool make me a meme’ Alexa: Meme Generated Visit to view meme: http://127.0.0.1:55944/models/Alexa/index.html
  59. 59. Check out the Meme
  60. 60. What’s next? I hope this was a good introduction to using Alexa, and ColdBox APIs ● We have a lot more information on REST in our REST Roadshow we recorded in 2016 https://www.ortussolutions.com/events/restful-roadshow-2016 ● Check out our blog on Ortussolutions.com ● We offer training online and in person ● We have Brad the monkey manning slack 34 hours a day. ColdBox REST is simple, lots more support in ColdBox 5, and all the ForgeBox modules at your disposal
  61. 61. Thanks I hope you enjoyed the session. Visit www.gpickin.com to see my follow up blog post with links to code and slides. Don’t forget to come see my ContentBox + Docker - Friday at 3:25pm Got questions? Find me at Happy Box right after this session and the live panel podcast recording.

×