Oh my god. It's full of code!

Heroku

Create an Alexa skill in Node.Js and host it on Heroku

Ok, here we go.

So for the last couple weeks I’ve been totally enamored with working with Alexa. It’s really fun to have a programming project that can actually ‘interact’ with the real world. Until now I’ve just been using my hacked together web server with If This Then That commands to trigger events. After posting some of my work on Reddit, I got some encouragement to try and develop and actual Alexa skill, instead of having to piggyback off IFTTT. With some sample code, an awesome guy willing to help a bit along the way and more than a little caffeine I decided to give it a shot.

The Approach: Since I already have a decent handle on Node.Js and I was informed there are libraries for working with Alexa, I decided Node would be my language of choice for accomplishing this. I’ll be using alexa-app-server and alexa-app Node.Js libraries. I’ll be using 2 github repos, and hosting the end result on Heroku.

How it’s done: I’ll be honest, this is a reasonably complex project with about a million steps, so I’ll do my best to outline them all but forgive me if I gloss over a few things. We will be hosting our server in github, creating a repo for the server, making a sub module for the skill, and deploying it all to Heroku. Lets get started. First off, go and get yourself a github account and a Heroku account. If you haven’t used git yet, get that installed. Also install the heroku toolbelt (which may come with git, I can’t quite remember). Of course you’ll also need node.js and Node Package Manager (NPM) which odds are you already have.

If you don’t want to create all the code and such from scratch and want to just start with a functioning app, feel free to clone my test app https://github.com/Kenji776/AlexaServer1.git

Create a new directory for your project on your local machine for your project. Then head on over to github and create yourself a new project/repo. Call it AlexaServer or something similar. Go ahead and make it a public repo. Do not initialize it with a readme at this time. This is the repo where the core server code will live. It’s important to think of the server code as a separate component from each individual skill, they are distinct things. You should see this screen.

repo1

Open a command prompt and change to the directory you created for your project. Enter the commands show in the first section for creating a new repository. Once those commands are entered if you refresh the screen you shoud see your readme file there with the contents shown like this.

github1

Okay, now we are ready to get the Alexa-Server app, https://www.npmjs.com/package/alexa-app-server is what you are looking for. In your project directory type in

“npm install alexa-app-server”

This will take a few moments but should complete without any problems. In your project folder you’ll want to create a folder called apps. This is where each individual skill will live. We will cover that later. Now you’ll need to create your actual server file. Create a file called server.js. Put this in there.

'use strict';

var AlexaAppServer = require( 'alexa-app-server' );

var server = new AlexaAppServer( {
	httpsEnabled: false,
	port: process.env.PORT || 80
} );

server.start();

Pretty simple code overall. The weird bit of code in the port section is for Heroku (they give your app a port to use when hosted). If not on Heroku then it will default to using port 80. Now you need to create your Procfile. This is going to tell Heroku what to do when it tries to run your program. It should be a file named Procfile in the same directory with no file extension. The contents of which are simply

“web: node server.js”

without quotes. We will also want to create a package.json file. So again in your project directory run the command

npm init

This will run a script and it will ask you a few questions. Answer them and your package.json file should get generated. Go ahead and push this all into Github using the following command sequence.

git add .
git commit -m “added server.js and Procfile, along with alexa-app-server-dependency”
git push origin master

If you view your Github repo online you should see all your files there. It should look something like this.

first repo push

 

You can see all of our files got pushed in. Now with the server setup, it’s time to create our skill. Create another GitHub repo. Call this whatever you like, hopefully something descriptive of the skill you are making. In your command prompt get into the apps directory within your main project. In there create another folder with a name same or similar to your new GitHub repo. Follow the same steps as before to initialize the repo and do the initial commit/push. Now we are going to indicate to GitHub that the apps/test-skill folder is actually a sub module so any dependencies and such will be maintained within itself and not within the project root. To do this navigate to the root project folder and enter.

git submodule add https://github.com/Kenji776/AlexaTestSkill.git apps/test-skill

Replacing the github project url with the one for your skill, and the apps/test-skill with apps/whatever-your-skill-is-named. Now Git knows that this folder is a submodule, but NPM doesn’t know that. If you try and install anything using NPM for this skill it’s going to toss it into the root directory of the project. So we generate a package.json file for this skill and then NPM knows that this skill is a stand alone thing. So run

npm init

Again and go through all the questions again. This should generate a package.json file for your skill. Now we are ready to install the actual alexa-app package. So run…

npm install alexa-app –save

and you should see that the skill now has it’s own node_modules folder, in which is contained the alexa-app dependency. After this you’ll have to regenerate your package.json file again because you’ve now added a new dependency. Now it’s time to make our skill DO something. In your skill folder create a file called index.js. Just to get started as a ‘hello world’ kind of app, plug this into that file.

module.change_code = 1;
'use strict';

var alexa = require( 'alexa-app' );
var app = new alexa.app( 'test-skill' );


app.launch( function( request, response ) {
	response.say( 'Welcome to your test skill' ).reprompt( 'Way to go. You got it to run. Bad ass.' ).shouldEndSession( false );
} );


app.error = function( exception, request, response ) {
	console.log(exception)
	console.log(request);
	console.log(response);	
	response.say( 'Sorry an error occured ' + error.message);
};

app.intent('sayNumber',
  {
    "slots":{"number":"NUMBER"}
	,"utterances":[ 
		"say the number {1-100|number}",
		"give me the number {1-100|number}",
		"tell me the number {1-100|number}",
		"I want to hear you say the number {1-100|number}"]
  },
  function(request,response) {
    var number = request.slot('number');
    response.say("You asked for the number "+number);
  }
);

module.exports = app;

Now, if you aren’t familiar with how Alexa works, I’ll try and break it down for you real quick to explain what’s happening with this code. Every action a skill can perform is called an intent. It is called this because ideally there are many ways a person might trigger that function. The might say “say the number {number}” or they might say “give me the number {number}” or many other variations, but they all have the same intent. So hence the name. Your intent should account for most of the common ways a user a might try to invoke your functions. You do this by creating utterances. Each utterance represents something a user might say to make that function run. Slots are variables. You define the potential variables using slots, then use them in your utterances. There are different types of data a slot can contain, or you can create your own. Check out https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interaction-model-reference for more information on slots types. I’m still figuring them out myself a bit. So the intent is triggered by saying one of the utterances. The slot is populated with the number the person says, and after reading the variable from the request, it is read back to the user.

So now, believe it or not, your skill is usable. You can test it by heading by starting your server. Again in your command line shell within the root project directory type

node server.js

A console window should show up that looks like this.

skill running

Now in your browser you should be able to bring up an emulator/debugger page be heading to

http://yourserver/alexa/your-skill-name       (EX: http://localhost/alexa/test-skill)

You should get a page that looks like this.

emulator

Holy cow, we did it! We have a functioning skill. The only problem now is that there is no way for Alexa to ‘get to it’. As in, Alexa doesn’t know about this skill, so there is no way for echo to route requests to it (also, I find it mildly creepy that when referring to Alexa, I keep accidentally wanting to type ‘her’. Ugh). So now we have to put this skill somewhere were it’s accessible. That is where Heroku is going to come in. Sure we could host this on our local machine, setup port forwarding, handle the SSL certs ourselves, but who wants to have their skill always running on their local box? I’ll do a bit on how to do that later since it requires creating a self signed SSL certificate using openSSL and such but for now I’m going to focus on getting this sucker into a cloud host.

Oh by the way, once everything is working smoothly, you should commit and push it all into github. Remember, you’ll have to do a separate commit and push for your server, and for the skill submodule since they are officially different things as far as github is concerned, even though the skill is a sub directory of your server. Also, I’m still learning exactly how submodules work, but if for some reason it doesn’t seem like your submodule is updating properly you can navigate to the project root folder and try this series of commands.

git submodule foreach git pull origin master
git add .
git commit -m “updated submodule”
git push origin master

with some luck that should do it. You’ll know it’s all working right when you open up your server repo in github, click the apps folder and you see a greyish folder icon for the name of your skill. Clicking it should show you the skill with all the files in there. Like this.

submoduleNow, on to Heroku. This part is pretty easy comparatively. Head on over to Heroku and create a new app. As usual, name it whatever you like, preferably something descriptive. Next you’ll be in the deploy area. You’ll be able to specify where the code comes from. Since we are smart, and we used github you can actually just link this heroku project straight to your github project.

hreoku connect
Just like that! However, this automatic integration does not seem to include sub modules, so we will have to add our skill submodule from the command line. So again navigate to your project folder from the shell, and run this command to link your directory with the heroku project.

heroku git:remote -a alexatestapp

Of course replacing alexatestapp with whatever the name of your heroku app is. You should get back a response saying that the heroku remote has been added. Now we need to push it all into Heroku (which in retrospect may have made the above linking done from the website un-needed, but whatever. It doesn’t seem to hurt anything). So now run

git push heroku master

You should be treated with a whole bunch of console output about compressing, creating runtimes, resolving dependencies, blah blah blah. Now with some luck your app should work via your hosted Heroku app. Just like when hosted locally we can access the emulator/debugger by going to

https://alexatestapp.herokuapp.com/alexa/test-skill

Replacing the domain with your heroku app, and the skill with whatever your skill is named. If all has gone well it should operate just like it did on your local machine. We are now finally ready to let Amazon and Echo know about our new skill. So head on over to https://developer.amazon.com/edw/home.html#/skills/list (you’ll need to sign up for a developer account if you do not have one) and click the add new skill button.

app create 1

On the next page it’s going to ask you for your intent schema. This is just a JSON representation of your intents and their slots. Thankfully that handy debug page generates that for you. So it’s just copy paste the intent schema from the debug page into that box. It will ask you about custom slot types, and odds are if you are making a more complicated app you are going to want to make your own, but really all that is is creating a name for your data type, common values for it (no it doesn’t have to be every value) and saving it. Spend some time reading the docs on custom slot types if you need to. It’s also going to want sample utterances, which again that debug page generates for you, so again, just copy paste. You might get a few odd errors here about formatting, or wrong slot types. Just do your best to work through them.

model

 

Next up is setting up the HTTPS. Thankfully Heroku handles that for us, so we don’t have to worry about it! Just select

“My development endpoint is a subdomain of a domain that has a wildcard certificate from a certificate authority”

Next up us account linking. I haven’t figured that one out yet, still working on it, so for now we just have to say no. Next up is the test screen. If everything is gone well up to this point, it should work just peachy for ya.

testsay

Next you’ll be asked to input some meta data about your app. Description, keywords, logo, icon, etc. Just fill it out and hit next. Finally you’ll be asked about privacy info. For now you have just say no to everything, and come back to update that when you’ve got your million dollar app ready to go. Hit save and you should be just about ready to test through your Echo. If you open your Alexa app on your phone and look for your skill by name, you should find it and it should be automatically enabled. You should now be able to go to your echo, use the wake word, speak the invocation name and ask for a number. If all has gone well you’ll hear the wonderful sound of Alexa reading back your number to you. For example

“Alexa Ask Test Get My Number”

Alexa should respond with what you defined as the app start message in your skill. You can now say

“Say the number 10”

Which should then be repeated back to you. Congrats. You just created a cloud hosted, Node.Js Alexa Skill that is now ready for you to make do something awesome. Get out there and blow my mind. Good luck!


Node.js, Socket.io, and Force.com canvas and you

So I got back from Dreamforce a week ago, and my head hasn’t stopped spinning. So many cool technologies and possibilities, I’ve been coding all week playing with all this new stuff (canvas, node.js, socket.io, nforce, heroku, streaming api, etc). Cloudspokes conveniently also had a challenge asking us to write a force.com canvas application that used a node.js back end. I wanted to take this chance to see if I could put what I had learned into practice. Turns out, it’s not too hard once you actually get your dev environment set up, and get things actually uploading and all the ‘paper work’ done. I wanted to leverage the Salesforce.com streaming API, Node.Js, and Socket.io to build a real time data streaming app. I also wanted to use Force.com canvas to get rid of having to worry about authentication (honestly the best part about canvas, by a wide margin). You can see the end result here:

http://www.screencast.com/t/Qfen94pl (Note the animations don’t show too well in the video due to framerate issues with the video capture software).

You can also grab my source project from here

Demo Source

Getting Set Up

First off, huge word of warning. All this process is just what I’ve found to work from trial and error and reading a ton of shit. I have no idea if this is the recommended process or even a good way to do things. It did/does however work. This was my first ever node.js application, as well as my first time using canvas and only my second time using Heroku. So ya know, definitely not pro level here but it’s at least functional. Also the actual idea for this application was inspired by Kevin O’Hara (@kevinohara80) and Shoby Abdi (@shobyabdi) from their streaming API session in dreamforce. They are also the authors of the kick ass nforce library, without which this app would not be possible, so thanks guys!

So how can you get started doing the same? Well first of course get yourself setup with Heroku. Heroku is where we are going to store our project, it’s a free hosting platform where you can host node.js, python and java applications. So if you don’t have a Heroku account, go get one, it’s free.

You’ll also want to download the Heroku toolbelt. This is going to get us our tools for dealing with Heroku apps (heroku client), as well as testing our stuff locally (foreman), and working with git. You can grab it here. https://toolbelt.heroku.com/. On that page it walks you through creating your project. For a more in depth guide, check out https://devcenter.heroku.com/articles/nodejs. Get a node.js project created and move onto the next step.

So now I assume you have a basic node.js project on Heroku. Now to actually make it do stuff, we’ll need to install some libraries using NPM. Open a command prompt and navigate to your local project folder. Install express (npm install express), socket.io (npm install socket.io) and nforce (npm install nforce). This should add all the required libraries to your project and modify the package.json file that tells Heroku the shit it needs to include.

You’ll also need a winter 13 enabled salesforce org to start building canvas apps. So go sign up for one here (https://www.salesforce.com/form/signup/prerelease-winter13.jsp) and get signed up. Depending when you are reading this you may not need a prerelease org, winter 13 may just be standard issue. Whatever the case, you need at least winter 13 to create canvas apps. As soon as you get your org, you’ll also probably want to create a namespace. Only orgs with namespaces and publish canvas apps, which you may want to do later. Also having a namespace is just a good idea, so navigate to the setup->develop->packages section, and register one for yourself.

In your org, you’ll need to configure your push topic. This is the query that will provide the live streaming data to your application.Open a console or execute anonymous window, and run this:

PushTopic pushTopic = new PushTopic();
pushTopic.ApiVersion = 23.0;
pushTopic.Name = 'NewContacts';
pushtopic.Query = 'Select firstname, lastname, email, id from contact;
insert pushTopic;
System.debug('Created new PushTopic: '+ pushTopic.Id); 

This will create a live streaming push topic in your org of all the new incoming contacts. You could change the query to whatever you want of course but for the purpose of this example, lets keep it simple.

Next, you’ll want to configure your canvas application. In your org, go to setup->create->apps. There should be a section called connected apps. Create a new one. Give it all the information for your Heroku hosted application. Permissions and callbacks here are a bit un-needed (since canvas will be taking care of the auth for us via a signed request) but should be set properly anyway. The callback url can be just the url of your application on Heroku. Remember only https is accepted here, but that’s okay because Heroku supports https without you having to do anything. Pretty sweet. Set your canvas app url to the url of your Heroku application and set access method to post signed request. That means when your app is called by canvas, it’s going to be as a post request, and in the post body is going to be a encoded signed request that contains an oAuth key we can use to make calls on behalf of the user. Save your canvas application.

The actual code (there isn’t much of it)
So we have everything configured now, but no real code. Our app exists, but it doesn’t do shit. Lets make it do something cool. Open up node server file (it’s probably called like web.js, or maybe app.js if you followed the guide above. It’s going to be whatever file is specified in your Procfile in your project). Paste this code. You’ll need to modify the clientId and clientSecret values from your canvas application. They are the consumer key and consumer secret respectively. I honestly don’t know if you’d need to provide your client secret here since the app is already getting passed a valid oAuth token, but whatever, it can’t hurt.

var express = require('express');
var nforce = require('nforce');
var app = express.createServer() , io = require('socket.io').listen(app);

var port = process.env.PORT || 3000;
//configure static content route blah
app.configure(function(){
  app.use(express.methodOverride());
  app.use(express.bodyParser());
  app.use(express.static(__dirname + '/public'));
  app.use(express.errorHandler({
    dumpExceptions: true, 
    showStack: true
  }));
  app.use(app.router);
});

app.listen(port, function() {
  console.log('Listening on ' + port);
});

io.configure(function () { 
  io.set("transports", ["xhr-polling"]); 
  io.set("polling duration", 10); 
});

var oauth;

var org = nforce.createConnection({
      clientId: 'YOUR CAVANAS APPLICATION CONSUMER KEY',
      clientSecret: 'YOUR CANVAS APPLICATION CLIENT SECRET',
      redirectUri: 'http://localhost:' + port + '/oauth/_callback',
      apiVersion: 'v24.0',  // optional, defaults to v24.0
      environment: 'production'  // optional, sandbox or production, production default
});

//on post to the base url of our application
app.post('/', function(request, response){
    //get at the signed_request field in the post body
    var reqBody = request.body.signed_request;   

    //split the request body at any encountered period (the data has two sections, separated by a .)
    var requestSegments = reqBody.split('.'); 

    //the second part of the request segment is base64 encoded json. So decode it, and parse it to JSON
    //to get a javascript object with all the oAuth and user info we need. It actually contains a lot of 
    //data so feel free to do a console.log here and check out what's in it. Remember console.log statments 
    //in node run server side, so you'll need to check the server logs to see it, most likely using the eclipse plugin.   
    var requestContext = JSON.parse(new Buffer(requestSegments[1], 'base64').toString('ascii'));
    
    //create an object with the passed in oAuth data for nForce to use later to subscribe to the push topic
    oauth = new Object();
    oauth.access_token = requestContext.oauthToken;
    oauth.instance_url = requestContext.instanceUrl;
    
    //send the index file down to the client
    response.sendfile('index.html');

});


//when a new socket.io connection gets established
io.sockets.on('connection', function (socket) {
      
    try
    {
      //create connection to the NewContacts push topic.
      var str = org.stream('NewContacts', oauth);
    
      //on connection, log it.
      str.on('connect', function(){
        console.log('connected to pushtopic');
      });
    
      str.on('error', function(error) {
         socket.emit(error);
      });
    
      //as soon as our query has new data, emit it to any connected client using socket.emit.
      str.on('data', function(data) {
         socket.emit('news', data);
      });
    }
    catch(ex)
    {
        console.log(ex);
    }
    
});

Now you’ll also need the index.html file that the server will send to the client when it connects (as specified by the response.sendfile(‘index.html’); line). Create a file called index.html, and put this in there.

<!DOCTYPE html>
<html>
    <head>
        <!-- - does a commit work remotely as well? -->
        <title>New Contacts</title>
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
        
        <link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
        
        <link rel="stylesheet" href="/reveal/css/main.css">
        <link rel="stylesheet" href="/reveal/css/theme/default.css" id="theme">    
        
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    
        <script src="/socket.io/socket.io.js"></script>
    
        <script>
          $.noConflict();    
          var socket = io.connect();

          socket.on('news', function (data) {
            jQuery('.slides').append('<section><h2><a href="https://na2.salesforce.com/'+data.sobject.Id+'">'+data.sobject.FirstName+' '+data.sobject.LastName+'</a></h2><br>'+data.sobject.Email+'<br/></section>');
            
            Reveal.navigateNext();
          });



        </script>    
    </head>
    <body>

        <div class="state-background"></div>
        
        <div class="reveal">
            <div class="slides"> 
                <section>New Contacts Live Feed</section>
            </div>

            <!-- The navigational controls UI -->
            <aside class="controls">
                <a class="left" href="#">◄</a>
                <a class="right" href="#">►</a>
                <a class="up" href="#">▲</a>
                <a class="down" href="#">▼</a>
            </aside>

            <!-- Presentation progress bar -->
            <div class="progress"><span></span></div>                
        </div>


            
            <script src="/reveal/lib/js/head.min.js"></script>
            <script src="/reveal/js/reveal.min.js"></script>    
            <script>
                
                // Full list of configuration options available here:
                // https://github.com/hakimel/reveal.js#configuration
                Reveal.initialize({
                    controls: true,
                    progress: true,
                    history: true,
                    mouseWheel: true,
                    rollingLinks: true,
                    overview: true,
                    keyboard: true,
                    theme: Reveal.getQueryHash().theme || 'default', // available themes are in /css/theme
                    transition: Reveal.getQueryHash().transition || 'cube', // default/cube/page/concave/linear(2d)
    
                });

        
            
                    
            </script>            
    </body>
</html>

We are also going to need the CSS reveal framework to create the awesome slideshow. Grab it https://github.com/hakimel/reveal.js. In your Heroku project create a folder called public. In there create a folder called reveal. In that folder dump the css, js, lib and plugin folders from reveal. So it should be like root_folder->public->reveal->js->reveal.js for example. There is probably a more ‘git’ way to include the reveal library, but I don’t know what it is. So for now, moving folders around should work.

Now use git to push this all up to Heroku. I’d really highly recommend using the Heroku plugin for eclipse to make life easier. There is an install guide for it here https://devcenter.heroku.com/articles/getting-started-with-heroku-eclipse. However you do it, either from eclipse or command line, you gotta push your project up to Heroku. If you are using command line, I think it’s something like “git add .” then “git commit” then “git push heroku master” or something like that. Just use the damn eclipse plugin honestly (right click on your project and click team->commit, then right click on the root of your project and click team->push upstream).

If your app pushes successfully and doesn’t crash, it should run when called from Canvas now. Canvas will call your Heroku application using a post request. The post request contains the signed request data including an oAuth token. We use that oAuth token and store it in our node.js app for making subsequent api calls. Node.js returns the index.html file to the client. The client uses socket.io to connect back to the server. The server has a handler that says upon a new socket.io connection, create a connection to the push topic newContacts in salesforce, using the oAuth token we got before. When a new event comes from that connection, use Socket.IO to push it down to the client. The client handler says when a new socket.io event happens, create a new slide, and change to that slide. That’s it! It’s a ton of moving parts and about a million integration, but very little actual code.

Enjoy and have fun!