Amazon IoT Button + Pushover = Extra Laziness

I’ve four kids (and we’re done). My oldest is 9, and my youngest is 2. The oldest always wakes up around 5am, and the toddler wakes up around 6:30. I don’t like waking up at 6:30, and the oldest can now get her out of the crib.

So, every morning around 6:30, I hear the two year old start crying and then get my phone and text my son, who goes to get her. This is mostly great, except I have to wake up enough to send a text message (even just to copy/paste a previous request from the day before).

I could suggest that he get her up any time she starts crying after 6:30, but there are circumstances where we don’t want that, so I still want to be manually involved to some extent.

Enter the Amazon IoT Button. I hooked that up to an AWS Lambda function, which pings Pushover, which sends a push notification to my son’s iPad. So, now instead of sending a text, I just push a button and go back to sleep.

The code itself is pretty simple. I didn’t really care about input, so it’s just an unused Java inputstream (note that all of the Lambda stuff requires plain Java interactions, so .asJava is necessary if you’re returning a non-primitive). Full repo on GitHub: terrbear/iot-pinger:

package org.terrbear

import dispatch._, Defaults._

import scala.collection.JavaConverters._

import com.amazonaws.services.lambda.runtime.Context

object Natertot {
  def main(args: Array[String]): Unit = {
    val notifier = new Notifier
    val answer = notifier.notify(notifier.YES_PLZ)
    println(answer())
  }
}

class Notifier {
  val PUSHOVER_KEY = "your-pushover-key"
  val PUSHOVER_APP_KEY = "your-pushover-app-key"
  val YES_PLZ = "Can you please get J out of bed?"

  def lambda(input: java.io.InputStream, context: Context) : String = {
    val logger = context.getLogger
    logger.log("got a click!")
    logger.log(notify(YES_PLZ)())
    "all done"
  }

  def notify(msg: String): Future[String] = {
    val request = url("https://api.pushover.net/1/messages.json").POST << Map("token" -> PUSHOVER_APP_KEY, "user" -> PUSHOVER_KEY, "message" -> msg)
    Http(request OK as.String)
  }
}

I’m not really embracing Dispatch’s futures here, but that seemed reasonable for the way it’s running. Also, Lambda wants a class it can instantiate to call the handler method (from my tiny bit of experimentation).

Steps to reproduce:

  1. Buy an IoT button
  2. Install Pushover and make an account and register an app
  3. Make your own Lambda function - when you’re creating the Lambda function you’ll be given an opportunity to register your IoT Button.
  4. Profit