Category Archives: Uncategorized

DynamoDB and Botkit

emojination_64I recently built (on top of the Botkit framework) and launched a Slack chat based game, emojination. I started out running emojination on Heroku. It was cheap and fast to get up and running there. Heroku does some really nice things for developers that shields the complexity of Amazon’s AWS. However, once I had emojination running well enough on Heroku, I wanted to learn AWS better. I knew about some of the services at a high level and used some of them on projects operationally, but I had never built anything on top of them myself.

I could run everything on “native” Amazon AWS services except Redis, which I was using for Botkit’s storage. While Amazon has a Redis based service, it is meant for caching. I could run Redis on EC2, either running the setup myself or using a 3rd party that makes it simpler to setup and maintain. While those options were reasonable, I wanted to see if I could make use of Amazon’s DynamoDB, since it’s a perfect match for the job (a key/value store), doesn’t require ops overhead on my part, and comes with some AWS free tier incentives. Yep, lock me up in the trunk and throw away the key.

The only problem was that there wasn’t a Botkit storage module for DynamoDB. There was one for Redis, MongoDB, Firebase, etc. but no DynamoDB. Seeing as I have near zero Node.js skils, I thought, “how hard can it be to create the DynamoDB Botkit storage module?” Not too hard, as it turns out, except for the part where I need to still figure out how to get the tests passing where promises are involved. The bulk of my time was spent figuring out how DynamoDB worked and what the options were in regards to npm DynamoDB modules. I ended up using the Dynasty module, which has a nice promise based approach. I found a few surprises along the way working with DynamoDB, but everything is running smoothly now, with emojination using it for both read and write operations.

The end result is there is now a botkit-storage-dynamodb module available for all who are interested in using DynamoDB with their Botkit based bot. A small contribution that has helped me learn quite a bit in a short period of time. ❤️

One little problem setting up Cloudflare SSL via cPanel for a site

I’m not going to give a full tutorial on how to setup Cloudflare SSL for a web site using cPanel for its hosting management. There are better resources for that. However, I did run into an issue that took me a while to track down and I wanted to capture that here in hopes that it saves someone else some time.

I had everything setup on the Cloudflare side and added the keys to cPanel for my domain but received the following error:

The system did not find the Certificate Authority Bundle that matches this certificate

There was a spot in the cPanel SSL setup page for adding the CA Bundle but my Google searches weren’t returning what I needed. Somewhere along the way I finally ran into my answer, which can be found at this Cloudflare support page. Once I added the Cloudflare root certificate from that support page, my site was enabled to serve up pages via HTTPS.

Note: I setup another domain for SSL via this same setup and didn’t have to enter the Cloudflare root certificate again.

Calling a Slack Web API method from a slash command app

I’m currently trying to build a little Slack app. The (Botkit based) app is a “slash command” that also needs access to the team and user info Slack web API methods.

I ran into a problem where I needed an access token that Botkit stores in its users object store. The issue is that when I need to use the access token to call the Slack web API methods, I need to find that token. I wanted to lookup that access token via the team_id that is passed in through the slash command message, but I couldn’t if the token is in the users object store, with the install user’s ID as the key.

Here is an example of what I had in the Botkit users and teams object stores after a user installed my app:

botkit:store:teams
{"id":"T1DDTABCD","createdBy":"U1DDKABCD","url":"https://someslackteam.slack.com/","name":"slack-team-name"}

botkit:store:users
{"id":"U1DDKABCD","access_token":"xoxp-49999999999-49999999999-59999999999-7e05d2266c","scopes":["identify","commands"],"team_id":"T1DDTABCD","user":"johndoe"}

When my app gets a message, it doesn’t have access to the install user’s ID, but it does have the team ID. I needed to pass in that “access_token” for the web API calls like this:

My workaround was to get the access_token from the install user during the install process and store it with the team. This is what that code looks like:

That happens once during install and adds the access token to the teams record:

botkit:store:teams
{"id":"T1DDTABCD","createdBy":"U1DDKABCD","url":"https://someslackteam.slack.com/","name":"slack-team-name", "access_token":"xoxp-49999999999-49999999999-59999999999-7e05d2266c"}

botkit:store:users
{"id":"U1DDKABCD","access_token":"xoxp-49999999999-49999999999-59999999999-7e05d2266c","scopes":["identify","commands"],"team_id":"T1DDTABCD","user":"johndoe"}

I could then call the Slack web API like this:

Notice I’m calling the teams storage and passing in the message.team_id to look up the team for the user who submitted the command.

With (more than) a little help from my friends

This entry is part 4 of 7 in the series Bicycling: Recovering from being hit by a vehicle


I like to think that I’m in control of much more than I am. Getting hit by that SUV while riding my bike and having to recover from that has been a harsh reminder of how little control I have. It’s also been a reminder of how thankful I am to have people in my life who care about and for me. Below are just some of the people who helped me during a great time of need.

My wife has probably suffered through this more than me. She had to see me shortly after I got hit, covered in blood, laying on an hospital ER bed, looking like a zombie. She was the one who drove me to endless doctor and dentist appointments. While most people didn’t see me much for a month after being hit, my wife saw me everyday and did her best to get me anything she could to help me. She had to answer the endless questions about how I was doing, what the status of “our case” was, etc. After a while, it all wears you down. Through it all, my wife, Kelly, was there for me and continues to be there for me, even as I know I wreck her nerves by continuing to ride my bicycle. I love her very much.

The king of hurt

Special thanks to my daughter who gave me the title of “The king of hurt” during the early days of my recovery.

There were numerous people from Zappos who went above and beyond to help me and my family during our time of need. There were Rachel and Susan who took our kids out for the day to have some fun. There were numerous people who provided meals. Others provided cards and other gifts to help cheer me up. A number of people stepped up and filled in to handle my absence at work. There is one person who stands out most of all, Mr. Ken. Yes, Mr. Ken. His name comes after he told some of us a story where he was on vacation and all the hotel staff called him, “Mr. Ken.” The name stuck. Mr. Ken came to the hospital and got the honor of watching me puke blood into a bucket. He visited later on when (honestly), I didn’t feel like seeing anyone, but was really happy to see him. He checked in on me, got my computer for me, kept me in the loop on stuff going on at work. He made sure I knew that if I needed anything, anything at all, he was there for me. Many thanks to Mr. Ken for all his support and help along the way.

Last, but not least, I need to thank those from our church, Spring Meadows Presbyterian, who provided meals, prayer and some practical advice along the way. While I didn’t eat much during that time, my family did and every meal that was provided was one less thing my wife had to deal with.

I had a lot of help along the way. I am truly thankful.


I’m capturing my journey towards recovery after being hit by an SUV while riding my bicycle on February 8th, 2014. I’ve learned quite a bit along the way and want to share those lessons. I’m not a doctor, lawyer, or any other sort of expert in this area. Any insights I provide along the way should be taken as my insights to my particular situation. In other words, seek professional counsel if you find yourself in similar circumstances. See more here.

One year ago today (…or when an SUV meets a cyclist)

I was riding my bike 5 minutes from my house one year ago today when an SUV ran a stop sign and hit me. The pictures below were a couple days later. It’s the first time I’ve looked at them myself. I’ll write more about the aftermath of it all some other time. Until then…

image

image

image

image

image

I’m sorry Apple, this is stupid

The iPod Touch (4th generation) is a nice device. What isn’t so nice is trying to load music onto it from anything other than iTunes. I work for Canonical and run Ubuntu on all our computers here at home. Even before joining Canonical I had switched over to Ubuntu. With that bias out of the way, can I ask why it requires a nuclear scientist to crack the code that is updating music on an iOS device outside of iTunes? How is it that my silly little Sansa Clip+ MP3 Player can get music from just about any software known to man, including the good old file system of the operating system you’re running, while it requires iTunes to properly add music to an iPod Touch?

OK, I get it. I’m not that naive. Apple has total control of the ecosystem. You buy one of their products, you’re locked in the trunk. In fact, you’ve bought the trunk! Most people don’t care and (for the most part) nor should they – until they do. Until one day you realize that what was once done in the name of great design and user experience crosses the line and becomes more about protecting high margins than much else. By that time it’s too late. We’re invested and the trunk has a lock not even Houdini could wiggle his way out of.

Anyway, my son’s iPod Touch looks like it’s getting new music from Banshee 2.3.6 on Ubuntu Precise Beta 1 but it appears the iTunes database is not updating properly, even though I can see the database is getting updated and the files are on the device in the same cryptic manner iTunes would do it (iTunes Control/Music/F00, F01, etc.) I’m guessing the iTunes database format changed and Banshee isn’t updating it quite right. I’m not sure. What I am sure of is that I used to LOVE Apple back in the day. Now? Not so much.

P.S. Yes, I know my son can stream music from Ubuntu One on his iPod, but he wants the tracks on the device and playable through Apple’s music app. Yet another hardening of the lock on the trunk.