Skip to content

device-independent/automatic-alerts-sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Automatic Link Notifications

NOTE: This is a proof-of-concept and was not written for production use cases. I am posting the code to provide some insight into how I initially tackled getting alerts setup with my Automatic Link. You have been warned :)

Goal

Utilize the Automatic API, specifically the webhooks, and integrating with other services such as Philips Hue and Twilio.

Tools

  • Automatic Link for your vehicle and an account to access the API.
  • Twilio account to send SMS messages. (optional)
  • Philips Hue starter kit and bulbs. (optional)
  • Sinatra as a simple web server to receive localhost requests.
  • ngrok to create a tunnel to localhost.
  • I am using OSX to perform all tasks.
  • I am using Ruby and RVM for my Ruby version manager.

Steps

Here are the steps I took to integrate multiple alert services with my Automatic Link.

Application and Dependencies

I started by creating a folder that will house the code dependencies and server. You can setup with:

git clone [email protected]:nateklaiber/automatic-alerts-sample.git
cd automatic-alerts-sample
bin/boostrap

Here's some info on the dependencies:

  • sinatra is the application webserver.
  • huey is a base gem I use to handle connects with the Hue Bridge.
  • twilio-ruby is the ruby wrapper for Twilio.
  • dotenv is a gem to help manage ENV variables within your app. This prevents hardcoding any tokens or credentials.
  • multi_json for fast JSON parsing.

ngrok

First you want to download and install ngrok. You can follow the steps on the download page to install for your OS. Once you are up and running, you can start ngrok with

ngrok 4567

I use 4567 as it's the default port for the Sinatra web server. You will get a response that looks like:

ngrok

Tunnel Status online
Version       1.6/1.5
Forwarding    http://{key}.ngrok.com -> 127.0.0.1:4567
Forwarding    https://{key}.ngrok.com -> 127.0.0.1:4567
Web Interface 127.0.0.1:4040

ngrok is now up and running and tunneling requests. Now we need to turn on the web server.

Sinatra

I chose Sinatra for it's quickness and simplicity. Rails would also be a sufficient server.

I instantiate a simple server to capture the webhooks with the following server.rb file:

require 'sinatra'
require 'multi_json'
require File.expand_path('../library.rb', __FILE__)

post '/hooks/automatic' do
  body_content = request.body.read
  json_content = MultiJson.load(body_content)
  
  puts json_content.inspect
  
  status(200)
  body(nil)
end

I'll explain some more of the underlying code in a minute. For now, I start my sinatra server with:

bundle exec ruby server.rb

If all is successful you will receive the output:

[2014-03-03 14:33:54] INFO  WEBrick 1.3.1
[2014-03-03 14:33:54] INFO  ruby 2.0.0 (2014-02-24) [x86_64-darwin12.5.0]
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from WEBrick
[2014-03-03 14:33:54] INFO  WEBrick::HTTPServer#start: pid=87759 port=4567

The sinatra server is now up and running. You can do a quick test to ensure ngrok is properly tunneling requests to sinatra with:

curl 'http://{key}.ngrok.com/hooks/automatic' -X POST -d '{}'

Your sinatra output will recognize the request and respond:

127.0.0.1 - - [03/Mar/2014 14:35:38] "POST /hooks/automatic HTTP/1.1" 200 - 1.9406
localhost - - [03/Mar/2014:14:35:36 EST] "POST /hooks/automatic HTTP/1.1" 200 0
- -> /hooks/automatic

And ngrok will show the request:

HTTP Requests                                                         
-------------                                                         
POST /hooks/automatic         200 OK  

All is good. You now have a tunnel to your local instance of sinatra. Now you need to register this with the folks at Automatic. You will register an Application with them and specify the Webhook URL to be your ngrok instance:

http://{key}.ngrok.com/hooks/automatic

You will replace key with the address you are assigned from ngrok. Once they get this setup and in place you can use their web interface to simulate webhook event and pick from an event to simulate. If all is working well, as soon as you hit Simulate you will see the request come through to your local application server.

Philips Hue

I am currently using the huey gem to connect and play with the lights. You can read the Huey documentation.

Important: Be sure to read the Getting Started notes in order to register Huey

Twilio

In order to use the Twilio alerts, you will need to setup a Twilio account. Once you are registered you will receive API Credentials with:

  • AccountSID
  • AuthToken

You will also be given a number where the calls will be made from: Manage Numbers

As a trial member you will need to verify a number in the Manage Numbers screen. If you do not register the numbers, you will receive errors in the application when trying to send an SMS.

Your credentials will be stored in the .env file:

TWILIO_ACCOUNT_SID='your-account-sid'
TWILIO_AUTH_TOKEN='your-auth-token'
TWILIO_FROM_NUMBER='your-twilio-number'

Handling the Response

Now is where we will begin to fill out our /hooks/automatic route. In order to handle the response, we will utilize a few Alert objects and some wrappers to our API's. Here's what the route will look like:

post '/hooks/automatic' do
  # Read the incoming body
  body_content = request.body.read
  json_content = MultiJson.load(body_content)

  # Choose lights to trigger for the alerts
  light_groups = [Huey::Group.new('Basement')]

  # Choose numbers to text for the alerts
  sms_numbers = []

  # Instantiate an instance of the Incoming Webhook Event
  event = Automatic::Events::Instance.new(json_content)

  # Setup custom alerts for the Hue Lights
  light_groups.each do |group|
    event.add_alert(Alerts::Lights.new(event, group.bulbs))
  end

  # Have the OSX System `say` command speak the event
  event.add_alert(Alerts::Screamer.new(event))

  # Send an SMS to specified numbers
  sms_numbers.each do |number|
    event.add_alert(Alerts::SMS.new(event, number))
  end

  # Write the alert to a JSON cache file
  event.write!

  # Trigger the alerts
  event.alert!

  # Return a successful response
  status(200)
  body(nil)
end

Again, for simplicity, the code for this is stored in library.rb. Normally we would separate out the concerns and gemify certain aspects. This is intentionally a rough proof-of-concept.

Simulating Locally

There is a bin/simulate script that allows you to pass it an event to your local ngrok instance to test end-to-end. Read more about simulating locally.

About

Automatic Webhooks and Alerts Sample

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published