/dash-button

A small Node.js server that reacts to Amazon Dash buttons on your WiFi network

Primary LanguageTypeScriptMIT LicenseMIT

Dash Button for Node Circle CI codecov npm version

This project is archived. As of 2020, Amazon has disabled Dash Buttons. Various guides on the internet (e.g. Rescue Your Amazon Dash Buttons) explain how to keep some Dash Buttons working but it is no longer as simple to customize Dash Buttons as before.

Additionally, some of this library's dependencies don't compile with Node 12 and newer. You can still compile the dependencies with Node 10.

For these reasons, this project is archived.


Dash Button is a small Node server that reacts to Amazon Dash buttons on your WiFi network. You can write event handlers that Dash Button will run when it detects someone has pressed your Dash button.

Dash Button is designed to run on a Raspberry Pi. Specifically, it runs on Raspbian (Jessie or newer) and supports modern Node.js.

Installation and Setup

Dash Button runs on Node 8 and up on macOS and Linux. It depends on libpcap:

# Ubuntu and Debian
sudo apt-get install libpcap-dev
# Fedora and CentOS
sudo yum install libpcap-devel

Install Dash Button in your project using npm:

npm install --save dash-button

You will need to configure Dash Button with the MAC address of each of your Dash buttons, plus code to run when you press them. The examples here use ES2017.

Setting Up Your Dash Button

Follow Amazon's instructions to add your WiFi credentials to your Dash button, but skip the last step of choosing which product to order when you press the button. Your button is correctly configured if its LED flashes white for a few seconds before turning red when you press it. Note that the Dash button throttles presses, so you may have to wait a minute if you've pressed it recently.

Finding the MAC Address of Your Dash Button

The dash-button package includes a script that prints the MAC addresses of devices sending DHCP requests or ARP probes, which the Dash button emits when pressed. Use this to learn the MAC address of your Dash button by pressing it.

Add a new script to the scripts section of your package.json file:

{
  "scripts": {
    "scan": "dash-button scan"
  }
}

Run it with sudo npm run scan:

$ sudo npm run scan

By default it will listen on the first external network interface, which is commonly en0 or wlan0, for example. You can listen on another interface with the --interface option:

sudo npm run scan -- --interface en1

Telling Dash Button about Your Dash Button

Once you know your Dash button's MAC address you need to tell Dash Button about it:

const DashButton = require('dash-button');

const DASH_BUTTON_MAC_ADDRESS = 'xx:xx:xx:xx:xx:xx';

let button = new DashButton(DASH_BUTTON_MAC_ADDRESS);

Running Code When You Press Your Dash Button

Add a listener to your button. The listener will run when you press the button.

let subscription = button.addListener(async () => {
  let nest = require('unofficial-nest-api');
  await nest.login(username, password);
  nest.setFanModeOn();
});

// Later, if you want to remove the listener do so with the subscription:
subscription.remove();

You can add both normal and async functions. If you add an async function, Dash Button waits for the promise to settle before listening to new button presses.

API

DashButton

A DashButton listens to presses from a single Dash button with a specified MAC address. See the setup instructions for how to learn your Dash button's MAC address by scanning for DHCP requests and ARP probes.

Constructor

constructor(macAddress: string, options?: Options = {})

Creates a new DashButton object that listens to presses from the Dash button with the given MAC address. The supported options are:

  • networkInterface: name of the network interface on which to listen, like "en0" or "wlan0". See ifconfig for the list of interfaces on your computer. Defaults to the first external interface.

addListener

addListener(listener): Subscription

Adds a listener function that is invoked when this DashButton detects a press from your Dash button. Use the returned subscription to remove the listener.

The listener may be an async function. If you add an async listener, this DashButton will ignore subsequent presses from your Dash button until the async function completes. When you have multiple async listeners, the DashButton will wait for all of them to complete, even if some throw errors, before listening to any new presses. This lets you conveniently implement your own policy for throttling presses.

Subscription

Subscriptions are returned from DashButton.addListener and give you a convenient way to remove listeners.

remove

remove()

Removes the listener that is subscribed to the DashButton. It will release its reference to the listener's closure to mitigate memory leaks. Calling remove() more than once on the same subscription is OK.

Help Wanted

Green Light

The coolest feature would be to control the light on the Dash button so it turns green. Currently it turns white when broadcasting a DHCP request or ARP packet and then red when it doesn't receive a response from Amazon. But when you use a Dash button in the normal way, the light turns green after Amazon has placed your order. It would be great and make custom Dash apps feel more responsive if Dash Button could send back some kind of packet to trick the Dash button's light into turning green.

You probably can figure out what's going on with a packet capturing library or a tool like Wireshark. Once we know what Amazon's response looks like, then we need to spoof it. This might be impossible because of TLS but it's worth a shot.

Acknowledgements

These posts and projects were helpful for making Dash Button:

License

This source code is released under the MIT license. It is not affiliated with Amazon.