SparkPost / raffles

Email-driven raffle service

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sign up for a SparkPost account and visit our Developer Hub for even more content.

SparkPost Raffles App

This is a Node.js app that consumes inbound email from a relay webhook database and interprets it as a set of raffle entries.

Each recipient address localpart represents a raffle and each received email represents an entrant to that raffle.

For example, when the app receives the following email:

From: bob@entrant.com
To: winstuff@raffle.sparkpost.com
Subject: Pick Me!

...it interprets it as an entry to the winstuff raffle by bob@entrant.com.

Prerequisites

  • Node (tested on 0.12)
  • PostgreSQL
  • Heroku toolbelt (optional)

Installation/Configuration/Running Locally

$ git clone https://github.com/SparkPost/raffles

Configuration

This app uses the following environment variables for configuration.

Variable Example Description
SPARKPOST_API_KEY 42188099814736e582812b07a4e0bd2d Your SparkPost API key
WEBHOOK_CONSUMER_DB postgres://<your_user>@localhost/avocadomail The path to your Postgres install
RCPT_DOMAIN hey.avocado.industries The to domain used to query raffle results
BA_USERNAME sparkpostisamazing The username to use for basic auth
PASSWORD_HASH 60b1198f6b6f25fd67f7856e92923231 md5 hash of your basic auth password

Running Locally

Create a local sparkies database. Note: this creates a Postgres DB named avocadomail:

psql < tools/avocadomail.sql

Install dependencies (this will install both NPM and Bower deps):

npm install

Create a .env file with the following values and source it:

export WEBHOOK_CONSUMER_DB_URL="postgres://<your_user>@localhost/avocadomail"
export SPARKPOST_API_KEY=<YOUR_API_KEY>
export RCPT_DOMAIN=hey.avocado.industries
export BA_USERNAME=<username for basic auth>
export PASSWORD_HASH=<md5 hash of your basic auth password>

You can use the md5it.js command line tool to generate your password hash:

node tools/md5it YOUR_PASSWORD

Start the app locally:

npm run web

You can also run the dev command to set a watcher on files to restart the server on every save:

npm run dev

Using The Dashboard

Each raffle has a dashboard useful for displaying on a TV at events. You can givie the dashboard for each raffle using this URL: /#/raffles/:raffleId/dashboard.

Reporting Time Window

The dashboard will show details about the last 24 hours by default. You can set the reporting time window using the date pickers at the top of the dashboard.

Compact Mode

The dashboard includes a "compact mode" which hides the date pickers (but still obeys your selected time window). You can toggle compact mode by clicking on the QR code image.

API Usage

Note: all endpoints support from and to query date/time parameters to narrow their focus to a particular time window. If the JS Date type can parse it, you can use it in from or to.

e.g.:

$curl -u myusername:mypassword -s 'http://localhost:3000/raffles?from=2015-01-01&to=2015-02-01' | jq .

/raffles - list raffles:

$ curl -u myusername:mypassword -s http://localhost:3000/raffles | jq .
{
  "results": [
    {
      "localpart": "dgray",
      "cnt": "2"
    },
    {
      "localpart": "ewan",
      "cnt": "1"
    }
    ]
}

/raffles/:raffleId - summarise entries for a raffle:

$ curl -u myusername:mypassword -s http://localhost:3000/raffles/dgray | jq .
{
"results": {
"num_entries": "2",
  "first_received": "2016-01-26T16:46:30.982Z",
    "last_received": "2016-01-26T16:46:30.984Z"
  }
}

/raffles/:raffleId/winner - pick a winning entrant for a given raffle:

$ curl -u myusername:mypassword -s http://localhost:3000/raffles/dgray/winner | jq .
{
  "results": {
    "winner_address": "dgray@sparkpost.com",
    "winner_sent_at": "2016-01-26T16:46:30.984Z"
  }
}

/raffles/:raffleId/entries - details about entries for a raffle:

$ curl -s http://localhost:5000/raffles/thedude/entries | jq .
{
    "results": [
        {
            "content": {
                "date": "2016-01-26T18:46:36.000Z",
                "from": [
                    {
                        "address": "some.dude@sparkpost.com",
                        "name": "Some Dude"
                    }
                ],
                "headers": {
                    "accept-language": "en-US",
                    "content-language": "en-US",
                    "content-type": "multipart/alternative; boundary=\"_000_D2CD6F8920EA2somedudesparkpostcom_\"",
                    "date": "Tue, 26 Jan 2016 18:46:36 +0000",
                    "dkim-signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=sparkpost.com; s=dkim1024; t=1453833998; bh=skhPF1DbeM5zGroj96RyrZ5fgdqbVDMk0cnZMUWQQvU=; h=From:To:Subject:Date:Message-ID; b=W9/6+9E3F0y9oXKrWLb/dbao+AyY77DXs1AxPgn61leURRxxoEgIM4L8O4qHqYApm DnY+fcjIozp90fe6rEd5RYA7saQoICYkCZpO+OJeYkdS5xNukUTFFS7ZwxGqaKYg0m JmUwI7Utnr5FRTUQUsod56YqhVvYaCFFgWGuXHL8=",
                    "from": "Some Dude <some.dude@sparkpost.com>",
                    "message-id": "<D2CD6F89.20EA2%some.dude@sparkpost.com>",
                    "mime-version": "1.0",
                    "received": [
                        "from [204.232.133.73] ([204.232.133.73:53427] helo=a.mx.messagesystems.com) by momentum3.platform1.us-west-2.aws.cl.messagesystems.com (envelope-from <some.dude@sparkpost.com>) (ecelerity 4.2.10.52432 r(Core:4.2.10.0)) with ESMTP id 3B/58-07606-01FB7A65; Tue, 26 Jan 2016 18:46:40 +0000",
                        "from [108.166.43.129] ([108.166.43.129:35088] helo=smtp11.relay.ord1c.emailsrvr.com) by b.mx.messagesystems.com (envelope-from <some.dude@sparkpost.com>) (ecelerity 3.6.0.39694 r(Platform:3.6.0.0)) with ESMTP id C5/B2-28631-E0FB7A65; Tue, 26 Jan 2016 13:46:38 -0500",
                        "from smtp11.relay.ord1c.emailsrvr.com (localhost.localdomain [127.0.0.1]) by smtp11.relay.ord1c.emailsrvr.com (SMTP Server) with ESMTP id 9EBB32804D8 for <thedude@hey.avocado.industries>; Tue, 26 Jan 2016 13:46:38 -0500 (EST)",
                        "from smtp11.relay.ord1c.emailsrvr.com (localhost.localdomain [127.0.0.1]) by smtp11.relay.ord1c.emailsrvr.com (SMTP Server) with ESMTP id 755A528041F for <thedude@hey.avocado.industries>; Tue, 26 Jan 2016 13:46:38 -0500 (EST)",
                        "from smtp192.mex05.mlsrvr.com (unknown [184.106.31.85]) by smtp11.relay.ord1c.emailsrvr.com (SMTP Server) with ESMTPS id 426212804DE for <thedude@hey.avocado.industries>; Tue, 26 Jan 2016 13:46:38 -0500 (EST)",
                        "from smtp192.mex05.mlsrvr.com ([UNAVAILABLE]. [184.106.31.85]) (using TLSv1 with cipher AES256-SHA) by 0.0.0.0:25 (trex/5.5.4); Tue, 26 Jan 2016 13:46:38 -0500",
                        "from ORD2MBX06B.mex05.mlsrvr.com ([fe80::4cba:20ff:fe52:4153]) by ORD2HUB07.mex05.mlsrvr.com ([fe80::d6ae:52ff:fe7f:66a7%15]) with mapi id 14.03.0235.001; Tue, 26 Jan 2016 12:46:37 -0600"
                    ],
                    "return-path": "<some.dude@sparkpost.com>",
                    "subject": "Hiya DevRel!",
                    "thread-index": "AQHRWGnil7lSt1uheEaxS17Z320Kog==",
                    "thread-topic": "Hiya DevRel!",
                    "to": "\"thedude@hey.avocado.industries\" <thedude@hey.avocado.industries>",
                    "x-ms-has-attach": "",
                    "x-ms-tnef-correlator": "",
                    "x-originating-ip": "[86.141.41.165]",
                    "x-sender-id": "some.dude@sparkpost.com",
                    "x-smtpdoctor-processed": "csmtpprox beta"
                },
                "html": "<html>\n<head>\n<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n</head>\n<body style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-family: Calibri, sans-serif;\">\n<div>This. Is. A Test.</div>\n<div><br>\n</div>\n</body>\n</html>\n",
                "messageId": "D2CD6F89.20EA2%some.dude@sparkpost.com",
                "priority": "normal",
                "receivedDate": "2016-01-26T18:46:40.000Z",
                "subject": "Hiya DevRel!",
                "text": "This. Is. A Test.\n\n",
                "to": [
                    {
                        "address": "thedude@hey.avocado.industries",
                        "name": ""
                    }
                ]
            },
            "from": "some.dude@sparkpost.com",
            "received": "2016-01-26T18:46:41.272Z",
            "subject": "Hiya DevRel!"
        }
    ]
}

Using Heroku

Create a Heroku app, attach the Sparkies heroku-postgresql addon, configure the app and push:

$ heroku create
$ heroku addons:create heroku-postgresql -a <your app name>
$ git push heroku master

Set the other environment variables with the heroku config:set command.

You can now access the app from https://<your-app>.herokuapp.com

About

Email-driven raffle service


Languages

Language:JavaScript 49.1%Language:SQLPL 28.1%Language:HTML 12.3%Language:CSS 10.5%