Create Slack Notifications using the Amazon Dash Button

Today we'll be following this guide to use the Amazon Dash button that when pressed, sends a notification through Slacks API.

Our specific use case was a coffee pot full notifier to our company. Instead of manually posting a message in the Slack channel, we figured it'd be easier to just push a button by the coffee pot to let everyone know.

The Amazon Dash buttons are only $5USD so it seemed like the perfect product for this. Later we'll (potentially) cover the graphic with some cool stuff from one of our talented designers.

The button:

Let's open our text editor (We're using Sublime Text 3) and copy/paste the following code.

from scapy.all import *  
import requests  
SLACK_API_URL = 'https://slack.com/api/chat.postMessage'

def send_message():  
  data = {
    "token": "<YOUR USER TOKEN>",
    "channel" : "<YOUR CHANNEL ID>",
    "icon_url" : "http://i.imgur.com/4tPGRDP.gif",
    "text": ":coffee: Fresh Pots :coffee:"
  }
  requests.post(SLACK_API_URL, data)

def arp_display(pkt):  
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      if pkt[ARP].hwsrc == '<DASH BUTTON MAC ADDRESS>':
        send_message()

print sniff(prn=arp_display, filter="arp", store=0)  

I've saved this file as dash.py on my desktop for testing. When you run this program, you'll want to cd (change directory) to the containing folder and run python dash.py in the terminal (I love iTerm2)

So If you clicked on the linked guide (which is awesome btw), you'll first need to set up your Amazon Dash button following his instructions, make sure you do not select a product on the final step though!

Then you'll want to create another file to sniff our your Dash Buttons MAC address. We'll follow Ted Benson's guide and use his listen.py script.

from scapy.all import *

def arp_display(pkt):  
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      print "ARP Probe from: " + pkt[ARP].hwsrc

print sniff(prn=arp_display, filter="arp", store=0, count=10)  

When you go to run this in your terminal, again, change directories cd to that folder and run python listen.py then press your dash button. You should see something like the following:

Grab that MAC Address and enter it into your dash.py file on line 17 : if pkt[ARP].hwsrc == '<DASH BUTTON MAC ADDRESS>': Save the file.

Let's test that it's working by adding a print "errr, I'm listening" statement to your if statement in dash.py and run the program, then click your button.

def arp_display(pkt):  
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      if pkt[ARP].hwsrc == '74:c2:46:dc:d3:ea':
        print "errr, I'm listening"
        # send_message()

print sniff(prn=arp_display, filter="arp", store=0)  

You should see:

Yay! We're receiving the button press and triggering an event! Now it's time to hook up our slack account!

Let's navigate our browser to the Slack API docs! We'll want to scroll down and generate a token for our account! Save that token somewhere!.

We'll be using the chat.postMessage endpoint in the Slack Docs. You can see all the required and available parameters.

I'm using a chrome program called Postman to test the endpoints.

We'll need to grab a couple required parameters to start with.

"token": "<YOUR_TOKEN>",
"channel" : "<CHANNEL_ID>",
"text": "<YOUR TEXT>"

Slacks API wouldn't allow me to use the plaintext channel name as a parameter so I used there channels.list endpoint in Postman to grab my Channel ID. Just send over your Token as a param in a GET request, then save that.

For some reason (probably my own issue), The Slack API through Postman wouldn't accept a data object so I had to pass all arguments as URL parameters.

Here's the failed request, with an error of not_authed which I thought I was since I'm sending the token. But if we send everything as URL Parameters, it works!

Sad face:

Yay working!

(The data object through the dash.py script works fine, this is just for debugging/testing)

This is what our final script looks like

from scapy.all import *  
import requests  
SLACK_API_URL = 'https://slack.com/api/chat.postMessage'

def send_message():  
  data = {
    "token": "<token>",
    "channel" : "C0C6S9T7E",
    "icon_url" : "http://i.imgur.com/4tPGRDP.gif",
    "text": ":coffee: Fresh Pots :coffee:"
  }
  requests.post(SLACK_API_URL, data)

def arp_display(pkt):  
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      if pkt[ARP].hwsrc == 'Mac address':
        send_message()

print sniff(prn=arp_display, filter="arp", store=0)  

And VOILA:

Notes: If you have issues with getting the script dependencies installed (I did) I used the following commands (OSX):

http://www.secdev.org/projects/scapy/doc/installation.html

$ wget http://libdnet.googlecode.com/files/libdnet-1.12.tgz
$ tar xfz libdnet-1.12.tgz
$ cd libdnet-1.12
$ ./configure
$ make
$ sudo make install
$ cd python
$ python setup.py install

$ wget http://dfn.dl.sourceforge.net/sourceforge/pylibpcap/pylibpcap-0.6.2.tar.gz
$ tar xfz pylibpcap-0.6.2.tar.gz
$ cd pylibpcap-0.6.2
$ python setup.py install

Get dat coffee:

Thanks to NelsonCash for Freestyle Fridays and the idea!