Lately, I have been fascinated with the Internet of Things. More specifically, I’m fascinated with the idea of interfaces between the digital and physical worlds. A goal for this year is to build more things, and I purposefully defined ‘build’ broadly to mean digital, physical, or a mixture of both.
The Dash Button
When I first heard of Amazon’s Dash Buttons almost two years ago, I thought they were pretty darn cool. Use case: leave a Tide dash button near your washing machine, and press it when you’re almost out of detergent to automatically add more to your Amazon cart.
The IoT Button
Later I heard they released an IoT Button. Now this caught my attention. Imagine a physical button that you can program to do anything you want! I shelved the idea in the back of my mind, until January 22, 2017 when I finally placed my order for one on Amazon.
By the time I received it on February 4, I was ready to rock!
The InstaFan Project
My friend AK takes great photos on Instagram and is well on her way to building a sizable following. I decided that my new IoT button would be put to excellent use by becoming one of her biggest fans. Clicking the button would result in a Like, a Comment, or both to her latest Instagram post from a profile that I set up for the job.
Yes, this is a little creepy. Luckily, she has a wonderful sense of humor and has been a great sport about all of this. (Thanks AK!)
Setting Up the Button
Amazon makes getting started with the IoT button really easy. I followed their setup process to securely pair the physical button with my Amazon AWS account and my home’s WiFi.
There are few options for configuring what service to engage when clicking the button. I chose Amazon Lambda, which allows code to execute “in the cloud” based on a button click, without the need for a server or other infrastructure. Lambda makes it easy to get started with Blueprints, pre-written code that can be used as a template.
It was good that I chose Node.js, because the only button blueprint available was written in Node.js. It’s called “iot-button-email”, and seemed like a great place to start.
Setting the Trigger
The rest of the setup process guided me through linking my button to the Lambda function that I created from the blueprint. The result was a trigger being setup from my button to the function.
It was really impressive how Amazon’s setup process basically did all the work for me.
My Button Does Something!
The blueprint contained a Node.js script that created an Amazon SNS (simple notification service) topic, subscribed an email address of my choosing to it, and published a message to it — all at the push of a button. The message ended up being sent to me as an email:
As you can imagine, I was beyond excited that I had just sent myself an email with the push of a physical button. Thankfully, there’s no video of that. These emails continued to be useful for development and testing, since they told me when the button was clicked, and whether it was Single, Double, or Long click (see the email subject line).
To Connect to the Gram
I decided to use this Instagram Package for Node.js, which would give me some examples to work with and all of the infrastructure to interact with the Instagram API. I created an Instagram developer account, and an app in their sandbox to obtain credentials.
My next problem — Node.js was pretty foreign to me, and I didn’t have any idea how to actually load the Instagram package. I could edit and test the simple send-email script from within Lambda, but without the package I was pretty stuck. Fortunately, I found this article that explained what I needed to do, written by two Amazon developers. But, surprise! The first paragraph sent me down another rabbit hole.
Building Version 1
Now that I was able to launch my Node.js instance with my Instagram Package, I was in business. I used sample code from the package author to login to my own Instagram account and download a feed of my most recent content. I tried to download my target account content, but hit a roadblock — I didn’t have permissions. After a bit of reading, I learned that sandbox apps weren’t able to interact with users who did not explicitly join the app as ‘sandbox users’. I decided to focus on building the code to Like and Comment first, and figure out how to aim it at my target later.
When I had finished with all of the functions I needed, it was back to my problem of aiming them at my target (again, she’s been a great sport!). Problem was, to access another user’s profile via my app, I needed to get the app out of the sandbox. Step one of requesting permissions:
Only the three highlighted use cases are actually acceptable to Instagram. Unfortunately, “pranking your friends with an IoT button” didn’t really fit into any of those. So, I realized that I’d have very little chance getting my app out of the sandbox.
Private API to the Rescue
Though I was set back, I was not willing to give up yet. I had to go back to the drawing board. I’m not totally sure why such resources exist, but boy was I glad to find the Node.js Instagam Private API Package. I’m pretty sure that it’s not Instagram-approved, but I’m not really doing anything to hurt the platform, so hopefully they don’t get angry.
This package allowed me to login to Instagram like the public API, but with a username/password instead of the more secure OAuth. Oh, well. The package uses two technologies that were new to me: promises and bluebird. I learned those just well enough to understand the example functions and start playing with them.
Once I had access, I needed to rewrite all of my functions. I took this opportunity to make them cleaner and more modular. As an example, I now had a separate function to choose a random comment from my library.
Side Note — A couple of the comments are © Pavel, but most were wholesale ripped off from Henry David Thoreau and Dr. Seuss. All were modernized to end with the folded hands emoji: 🙏, because I know AK loves it.
Finally I had to put it all together, setting functions based on the type of click. I decided a single click would give a like, a double click would leave a comment, and a long click would do both.
Per the instructions in an earlier-referenced article, I zipped up the codebase from my development environment, and uploaded it to my Lambda function.
Finally, I was ready to roll… One long click later, and I had added both a like and a randomly chosen comment to her most recent Instagram photo!
See what I mean about how she takes great photos? Thanks again AK for being such a great sport this past week!