From baf8b42330b8c631773628cad2c6ae4f7c13fb45 Mon Sep 17 00:00:00 2001 From: Kevin Stock Date: Fri, 26 Feb 2016 23:31:23 -0800 Subject: [PATCH] Adds mailing list signup via MailChimp integration --- README.md | 14 +++--- assets/index.html | 26 ++++++++++- bindata_assetfs.go | 4 +- invite.go | 109 +++++++++++++++++++++++++++++++++++++++++++++ main.go | 14 +++++- slack.go | 57 ------------------------ 6 files changed, 155 insertions(+), 69 deletions(-) create mode 100644 invite.go delete mode 100644 slack.go diff --git a/README.md b/README.md index e3e485a..20b23a4 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,14 @@ make osx ## Running (in Production) Running the site will require the setting of a number of options. These options can be set via command line flags or environment variables. -| Environment Variable | Flag | Description | Default Value | -|--------------------------------|-----------------|------------------------------------------------------------------------------------------|---------------| -| `$HACK_BELLINGHAM_PORT` | `--port` | The TCP port to listen on. | `3000` | -| `$HACK_BELLINGHAM_HOST` | `--host` | The IP address/hostname to listen on. | All hosts | -| `$HACK_BELLINGHAM_SLACK_TEAM` | `--slack-team` | Slack team name, as found in the slack URL. | `""` | -| `$HACK_BELLINGHAM_SLACK_TOKEN` | `--slack-token` | Access token for your slack team. It can be generated at https://api.slack.com/web#auth. | `""` | +| Environment Variable | Flag | Description | Default Value | +|------------------------------------|---------------------|------------------------------------------------------------------------------------------|---------------| +| `$HACK_BELLINGHAM_PORT` | `--port` | The TCP port to listen on. | `3000` | +| `$HACK_BELLINGHAM_HOST` | `--host` | The IP address/hostname to listen on. | All hosts | +| `$HACK_BELLINGHAM_SLACK_TEAM` | `--slack-team` | Slack team name, as found in the slack URL. | `""` | +| `$HACK_BELLINGHAM_SLACK_TOKEN` | `--slack-token` | Access token for your slack team. It can be generated at https://api.slack.com/web#auth. | `""` | +| `$HACK_BELLINGHAM_MAILCHIMP_TOKEN` | `--mailchimp-token` | The API token for your MailChimp account. | `""` | +| `$HACK_BELLINGHAM_MAILCHIMP_LIST` | `--mailchimp-list` | The ID of the MailChimp list. | | ### systemd Configuration The canonical way to run the site is through the [`systemd`][systemd] service manager to setup the environment, manage when the application is started, and monitor the process to keep it running. This can be done with a system file like the one below: diff --git a/assets/index.html b/assets/index.html index 5bec464..8aff3a1 100644 --- a/assets/index.html +++ b/assets/index.html @@ -34,9 +34,23 @@ font-family: 'Roboto Slab', Arial, serif; } input { - width: 93.25%; + width: 97.75%; padding: 2.25% 1.125%; } + input[type=checkbox] { + width: auto; + position: absolute; + top: .25em; + left: 0; + margin: 0 0 0 0; + } + label { + font-size: .5em; + display: block; + margin: 1em 0; + padding: 0 0 0 25px; + position: relative; + } button { border-radius: 1.5em; border-style: none; @@ -98,6 +112,12 @@

Hack Bellingham is a social group dedicated to growing the local developer c

Join us on Slack:

+ + +
@@ -115,7 +135,9 @@

Join us on Slack:

xhr.open('POST', encodeURI('request-invite')); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify({ - email: document.getElementById("email-address").value + email: document.getElementById("email-address").value, + requestSlack: true, + requestMailingList: document.getElementById("mailing-list-opt-in").checked })); diff --git a/bindata_assetfs.go b/bindata_assetfs.go index 1e63955..61b7642 100644 --- a/bindata_assetfs.go +++ b/bindata_assetfs.go @@ -70,7 +70,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _assetsIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x57\x6b\x53\xe3\xba\x19\xfe\x9c\xfd\x15\xaa\x3b\x67\x92\x4c\x13\xe7\x02\x2c\x10\x62\xda\x9e\xed\xe9\xb0\x67\xf6\x36\x0b\x9d\xf6\x7c\x54\xec\x37\xb6\x0e\xb2\xe5\x4a\x72\x42\xda\xe1\xbf\xf7\x91\xe4\x84\x24\xb0\x94\x9d\x25\xc4\xef\xfd\x79\xaf\x66\xfe\x87\xbf\x7d\xfd\x70\xf7\xdb\xb7\x5f\x58\x61\x4b\x79\xfd\x6e\xbe\xfd\x45\x3c\xbb\x7e\xd7\x99\x5b\x61\x25\x5d\xdf\xf0\xf4\x9e\xfd\x4c\x52\x8a\x2a\x2f\x78\x39\x1f\x05\x32\xf8\xa0\xdc\xb3\x42\xd3\x32\xe9\x16\xd6\xd6\x66\x36\x1a\x2d\x55\x65\x4d\x9c\x2b\x95\x4b\xe2\xb5\x30\x71\xaa\xca\x51\x6a\xcc\x9f\x97\xbc\x14\x72\x93\x7c\x57\x0b\x65\xd5\x9f\x6e\x25\x5f\xcc\x4e\xc7\xe3\xc1\xc9\x78\xdc\x65\x9a\x64\xd2\x35\x76\x23\xc9\x14\x44\xb6\xcb\xec\xa6\xa6\xa4\x6b\xe9\xc1\x3a\xdd\xae\xf3\x55\x92\xe5\xac\xe2\x25\x25\xd1\x4a\xd0\xba\x56\xda\x46\x2c\x85\x37\xaa\x6c\x12\xad\x45\x66\x8b\x24\xa3\x95\x48\x69\xe8\x1f\x06\x4c\x54\xc2\x0a\x2e\x87\x26\xe5\x92\x92\x49\xe4\xac\x78\x27\xc1\x7c\xb4\x35\xef\x18\x1d\x87\x7c\xc0\x16\x2a\xdb\xb0\xff\xe2\xb1\x53\xf2\x87\x60\x67\xc6\x2e\x4e\xc7\xf5\xc3\x55\x20\xea\x5c\x54\x33\x36\x66\xbc\xb1\xca\x93\x6a\x9e\x65\xc8\xcb\x8c\x4d\x20\xc4\xa6\xdb\x0f\xcf\x73\xb9\x18\x06\xdc\x33\xd6\x0d\xc8\x99\x43\xde\x1d\xb0\xbf\x6a\x84\x36\x60\x86\xb4\x58\x5e\xb1\x9d\xf4\x9a\x44\x5e\xd8\x19\x43\x5a\x9e\x4c\x18\xf1\x1f\x02\xe9\x7d\x6b\x76\x81\x7a\xe4\x5a\x35\x55\x36\x4c\x95\x54\x7a\xc6\xd6\x85\xb0\xe4\x79\x2d\x41\xe7\x8b\xde\x74\x3c\xf0\xff\xfb\x8e\xf1\x88\x9f\x3f\x4a\x95\xab\x80\xae\x45\x86\x02\xec\x90\xed\xe0\x5e\x9e\xfe\x74\x00\x36\x3e\xa3\x92\x8d\xb7\x46\x8a\xc9\x80\x15\xd3\x4e\x30\x73\x10\xf2\xe9\xf3\x90\x27\x54\x3e\x23\xe9\x40\xf3\xb6\xa6\x2f\x98\x69\x91\x3b\xbe\xa8\xea\xc6\xa2\x28\x8d\xb5\xaa\xda\x13\x0d\x96\xe2\x8b\xe7\xd6\xe3\x0b\xbd\x4f\x7c\x6b\xee\x77\xce\x0e\xb2\x73\x79\x12\x4f\xcf\x7e\x3a\xac\xf2\xd4\x91\xd8\x24\x9e\xb4\x1c\xa7\xb9\x1f\xdf\x42\xe9\x8c\xf4\x50\xf3\x4c\x34\x06\x68\x5d\xf2\xae\xf6\x18\xbe\xff\x66\xac\x52\xd5\x41\xbd\x9e\x0a\xf8\xbc\xb8\xae\x96\xef\xc7\x03\x36\x39\x47\xea\x2f\x2f\xfb\x7b\xc5\x19\x5a\x55\x87\x02\x1d\x46\xe9\x4b\xe6\x93\xef\xc8\x56\xf3\xca\x60\x14\x14\x8a\xe9\xa1\xb1\xf8\xfc\xcc\xa0\x8c\x3e\xe3\xed\xc3\xb1\x5f\x4f\x3e\x44\x38\x2b\xd4\x8a\x74\xc0\x99\x36\xda\xb8\xe0\x6a\x25\x30\x81\xfa\x48\x30\x13\x86\x2f\x24\x65\x6d\x4e\x5e\x82\xc4\x7b\x67\x27\x83\xf3\xd3\xc1\xe5\xc9\x20\x3e\x0b\x98\xb6\x36\xd7\x5c\xd8\x60\x10\x1f\xb1\x69\xd2\x94\x0c\x22\x8c\x97\x5c\xc8\x46\xd3\xab\x46\xf7\x12\x05\x8d\x69\x7f\x2f\xf7\xa8\x06\x86\xd3\x28\x29\xb2\x97\x73\xfa\x5a\xbe\x77\xa9\x1d\x6f\x9b\x3a\x44\xf7\xff\x63\xea\x4d\x4f\x61\x67\x3a\x9d\xfa\x8f\xfd\x80\xf6\x85\x26\x97\x67\xe0\x23\xe6\xf3\xf1\xb3\x60\x8e\x79\xde\xf3\x5f\x4a\xca\x04\x67\xbd\xa7\xc1\x7d\xef\x86\xb9\x1f\x22\x39\xde\x66\xfb\x33\x32\xbd\x68\x67\xfe\xf1\xc7\xb6\x4e\xdf\x6a\x6b\x7c\x64\x6b\x3e\xf2\x1d\x8e\x1b\x32\x0a\x47\x64\xee\x14\xdd\xe6\x75\x8f\xa4\xdd\xaa\x9d\x8b\x32\x67\x22\x4b\x22\xb7\x8f\x22\x66\x74\x1a\xbe\xc6\x66\x95\xfb\x25\x3d\xda\xca\xba\xb5\xcf\x45\xe5\x94\x9c\x5e\x31\x39\xbe\x45\x4c\x18\xc6\x51\xd3\x14\x03\xcd\x5c\xea\x6b\x96\x01\x4b\xca\x2d\x9a\x0f\x03\x0f\xd2\x1a\x92\xcc\x16\xc4\xa4\xc2\x1d\x00\x7b\x45\x52\xd5\xe8\x63\x1c\xa6\xb2\xc1\x89\xd8\xc4\x70\x38\x71\xce\x3a\xf3\xfa\xfa\x9f\xc4\x38\xea\xe9\x98\xc2\xb6\x56\x6a\xad\x56\xc2\x95\x1f\xbe\x96\x5a\x50\x95\xc9\x0d\xd6\x07\x5f\x42\xb6\xca\xd8\x9a\x24\xc4\x1d\x9b\xaa\x95\xd0\xaa\x2a\x71\x92\xd8\x12\x33\x44\x0f\x70\x04\xf9\x14\x76\x9c\x24\x37\xb5\xd0\x3e\x1e\x4a\x8b\x0a\x15\xce\x85\xb1\x68\x6d\x4d\x39\xd7\x19\xae\x9f\x61\x6a\xc9\x78\x4e\x03\xe6\x47\x48\x48\x84\x37\x60\x39\x3c\x92\x1e\xe0\xfa\xb9\x21\xe6\x81\xa8\x79\x4a\x4e\x53\x8a\x1c\x44\xb7\xcd\x1e\x9a\x96\x05\xcf\x46\x60\xf3\x71\xcd\xe0\xdf\x38\x15\x96\x16\x1c\x1a\x18\x55\x78\x14\x29\x20\xd7\x01\x71\x26\x56\xbe\x16\xc6\x72\xdb\x98\x61\x89\x18\xe0\x3f\xba\x9e\x8f\xc0\x39\x12\x91\x48\xfe\x10\xb8\x4a\x7f\x31\x51\x8f\xe9\xf5\xaf\x98\x7f\xd6\x20\xec\xca\x2d\xd7\xf4\x7e\x86\x5c\x4e\x03\x37\x2c\xd4\xa7\x53\x1b\xb1\x1a\x12\x54\x28\x09\x30\x49\x44\xa8\xac\x64\x18\x2b\x0d\x97\x91\x77\xe0\x49\xc3\x1d\xc9\xdd\xd8\xa5\x4a\x1b\x13\xec\xb5\x6b\x56\x55\xa9\x14\xe9\x7d\x12\x69\xfa\x77\x43\xc6\x7e\x44\xce\x2d\xf5\xfa\x57\xc1\x86\xf0\x8f\xc3\x20\x1c\x5d\xdf\x22\x75\xac\x74\x75\x62\x81\x33\x1f\x05\x96\x6f\xc4\x2d\xc6\xf9\x28\xb4\x99\x7b\x41\x48\xb5\xa8\xf7\xc3\x1e\xfd\xce\x57\x3c\x50\x3d\xec\x65\x53\xa5\xae\x0c\xec\xc8\x7f\x18\x8e\x15\x72\xde\x06\x9a\xb0\x0c\xc1\xbb\x5e\x88\x73\xb2\xbf\x48\x72\x5f\x7f\xde\x7c\xcc\x7a\x47\x41\xf6\x07\x4e\x93\xe1\x9f\xd2\x28\x26\xaa\xf5\x89\x2f\x48\xc2\x40\x10\x88\x45\x55\x91\xbe\xb9\xfb\xfc\x29\xec\xf3\x96\xba\x5b\xb2\x09\xb3\xba\x69\xaf\xc7\x91\x02\x78\xd1\xf7\x10\xa7\x6f\xdf\x6d\x16\xe2\x38\x8e\x82\x31\x17\xf0\x43\xa1\x21\x58\xd1\x9a\xfd\xeb\xf3\xa7\x1b\xbc\xc8\xb5\x2a\xbd\xb0\x8a\xc0\x8e\x31\x31\x55\xaf\xfb\xed\xeb\xed\x1d\xee\x27\x1a\x5a\x65\xf4\x8f\xef\x1f\x7b\xdd\x36\x09\xc3\x60\xb6\xdb\x7f\xd2\x30\x64\x5b\x33\x37\x7e\x9a\x7b\xdd\x0f\xe1\x65\x6d\x78\x87\xdc\xc2\x4a\x97\xd7\xb5\x74\xa3\x8a\x64\x8e\x7e\x47\x97\x76\xf7\x95\xab\xac\xf7\xeb\xed\xd7\x2f\xb1\xb1\x6e\x60\xc4\x72\xd3\x0b\xcb\xc7\xf7\xc8\xec\xc7\xa9\x3d\xec\xa1\x7e\xbc\xe2\xb2\x21\xbf\xa1\x5c\x6c\xef\x76\x78\x2a\xa9\xb8\x4b\xdd\xb6\x9c\xdb\x02\xfa\x84\x84\x61\xf8\x1c\x66\xe1\xb5\x42\x1e\x4d\x4d\xa8\x64\xa7\xe3\x27\xe5\xef\x18\x94\x57\x75\x9f\xc6\xa9\x1f\x6a\xd1\x11\x4b\xd6\xf3\xf0\xbd\x59\x96\x24\x09\x36\xec\x78\x1b\x59\xe7\x20\xac\x38\x95\xdc\x98\x2f\x78\x21\x76\x45\x6e\xaf\x64\xf4\x92\xe0\x41\x37\x60\xc5\xfd\xa6\x1a\x1d\xfa\xc0\xe7\x9e\x15\xdc\xb0\x05\x51\x85\x15\x82\x30\xd9\x37\xbc\xb8\x1b\x6c\xc0\x82\xb0\x6a\x37\x4e\xd6\xe7\xd4\xaf\x8c\xb6\x69\xf6\x10\xc6\x35\xd6\x65\x65\xbf\xa0\x21\x62\xbc\x7b\xe1\x0d\xe1\x43\x21\x64\xd6\xdb\x09\x6c\xb1\x3d\x86\xf2\x49\x43\x6f\x80\xd3\x9e\xd5\x37\xc1\xb9\x2b\x08\x0b\x7b\x0d\x10\x68\x6f\xd2\x1a\xdb\x0f\x0b\xdb\x65\xc3\xb5\xfc\xe6\x10\xec\x0e\x9e\xd5\x1b\x2c\x5a\x4c\x3d\x93\x38\x16\xfa\x10\xdd\xf3\x09\x5b\x72\x04\x7e\x75\xc0\xdd\x8f\xe3\x60\x70\xaf\x9e\xf0\x3e\x1e\x76\xf4\xf6\x55\x1c\x57\xd2\x2f\x14\xec\x13\x1c\xca\x70\x21\xb1\x38\xdd\x1f\x5f\xff\x0b\x00\x00\xff\xff\xec\x5f\x86\x74\x93\x0d\x00\x00") +var _assetsIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x57\x6d\x73\xdb\xb8\x11\xfe\xac\xfc\x8a\xad\x3a\x19\x49\x53\x89\x92\x18\x3b\x89\x65\xd1\xed\x5d\x9a\x4e\x72\x93\xb7\x49\xdc\x69\x6f\x3a\xfd\x00\x91\x90\x88\x18\x24\x58\x00\x94\xac\x76\xf2\xdf\xfb\x00\x20\x25\x51\xf6\xe5\x72\x97\x38\x16\x16\xfb\xf6\xec\xb3\xbb\xd0\xf2\x0f\x7f\xfd\xf8\xea\xf6\xd7\x4f\xaf\x29\xb7\x85\xbc\x79\xb2\x6c\xff\xe1\x2c\xbb\x79\xd2\x5b\x5a\x61\x25\xbf\x79\xc3\xd2\x3b\xfa\x99\x4b\x29\xca\x4d\xce\x8a\xe5\x34\x1c\x43\x8e\x93\x3b\xca\x35\x5f\x27\x83\xdc\xda\xca\x2c\xa6\xd3\xb5\x2a\xad\x89\x36\x4a\x6d\x24\x67\x95\x30\x51\xaa\x8a\x69\x6a\xcc\x9f\xd7\xac\x10\x72\x9f\x7c\x56\x2b\x65\xd5\x9f\xbe\x48\xb6\x5a\x5c\xcc\x66\xe3\x67\xb3\xd9\x80\x34\x97\xc9\xc0\xd8\xbd\xe4\x26\xe7\xdc\x0e\xc8\xee\x2b\x9e\x0c\x2c\xbf\xb7\x4e\x77\xe0\x7c\x15\xdc\x32\x2a\x59\xc1\x93\xfe\x56\xf0\x5d\xa5\xb4\xed\x53\x0a\x6f\xbc\xb4\x49\x7f\x27\x32\x9b\x27\x19\xdf\x8a\x94\x4f\xfc\x87\x31\x89\x52\x58\xc1\xe4\xc4\xa4\x4c\xf2\x64\xde\x77\x56\xbc\x93\x60\xbe\xdf\x9a\x77\x82\x9e\xcb\x7c\x4c\x2b\x95\xed\xe9\x7f\xf8\xd8\x2b\xd8\x7d\xb0\xb3\xa0\x97\x17\xb3\xea\xfe\x3a\x1c\xea\x8d\x28\x17\x34\x23\x56\x5b\xe5\x8f\x2a\x96\x65\xc0\x65\x41\x73\x5c\xa2\xb8\xfd\xe1\x65\x0e\x8b\x49\xc8\x7b\x41\x83\x90\x39\xb9\xcc\x07\x63\xfa\x49\x23\xb4\x31\x19\xae\xc5\xfa\x9a\x0e\xb7\x77\x5c\x6c\x72\xbb\x20\xc0\x72\x34\x61\xc4\x7f\x39\x8e\x9e\x37\x66\x57\xa8\xc7\x46\xab\xba\xcc\x26\xa9\x92\x4a\x2f\x68\x97\x0b\xcb\xbd\xac\x39\xd0\x9b\xd5\x30\x9e\x8d\xfd\x9f\x91\x13\x7c\xc3\xdf\x3f\x4a\xb5\x51\x21\xbb\x26\x33\x14\xe0\x90\xd9\x21\xdd\xab\x8b\xa7\x9d\x64\xa3\x4b\x5e\xd0\xac\x35\x92\xcf\xc7\x94\xc7\xbd\x60\xa6\x13\xf2\xc5\xc3\x90\xe7\xbc\x78\x70\xa4\xc3\x99\xb7\x15\x3f\x62\xa6\xc9\xdc\xc9\x45\x59\xd5\x16\x45\xa9\xad\x55\xe5\xc9\xd5\x60\x29\x7a\xf9\xd0\x7a\xf4\x52\x9f\x1e\xfe\x28\xf6\x07\x67\x1d\x74\xae\x5e\x44\x2f\x2e\x9f\x76\xab\x1c\x47\xf1\xe5\x53\x9a\x47\xf3\x38\x48\x0e\x9a\xff\xf2\x9c\x4a\x73\x9e\xde\xad\xd4\xfd\xbf\x3b\x86\x8e\x64\x51\x06\x94\x54\x00\x95\xad\x8c\x92\x75\x53\x34\xab\x2a\x84\x1e\x5f\x36\xa1\x4b\xbe\x06\x0e\xb3\x33\xc6\xf9\xff\x5b\x97\xc8\x83\xcb\x87\x88\xb4\x16\x32\x61\x2a\xc9\x90\xf8\x4a\xaa\xf4\xae\x63\x68\xde\x16\xf3\x98\x53\xb0\x1d\x5f\x36\x54\x38\x06\x89\xb6\x64\x56\x6c\x79\xeb\xf5\xb4\x10\x2b\xa5\x33\xae\x27\x9a\x65\xa2\x36\x30\x7b\xf0\xdd\x08\x7c\xa3\x2d\xa8\x54\x65\x87\x98\x47\xa6\x3e\x64\xb1\x23\xed\xf3\xd9\x98\xe6\x2f\xc0\xb1\xab\xab\xd1\x49\xdc\x93\x00\x51\xeb\xe3\x10\xba\xe7\xa6\x67\x99\xc7\x51\xb3\xb2\x8d\xdd\x43\x4f\x28\xa0\x01\x5f\x3d\xb5\x9a\x0f\xe7\x7e\xfd\x71\x37\xc3\x45\xae\xb6\x5c\x87\x3c\xd3\x5a\x1b\x17\x5c\xa5\x04\x46\x8d\x3e\xbb\x08\xa0\xd9\x4a\xf2\xac\xc1\xe4\xb1\x94\xd8\xf0\xf2\xd9\xf8\xc5\xc5\xf8\xea\xd9\x38\xba\x0c\x39\xb5\x36\x77\x4c\xd8\x60\x10\x3f\x22\x53\xa7\x29\x37\x88\x30\x5a\x33\x21\x6b\xcd\xbf\x6b\xf4\x04\x28\x68\xc4\xa3\x13\xec\x51\x0d\x4c\x21\xf0\x4b\x64\x8f\x63\xfa\x3d\xbc\x4f\x58\x31\x6f\x3b\xd5\x45\xf7\xfb\x31\x0d\xe3\x0b\xd8\x89\xe3\xd8\xff\x38\x0d\xe8\xf4\xd2\xfc\xea\x12\x72\xc4\xfc\x62\xf6\x20\x98\x73\x99\xf7\xfc\x97\x82\x67\x82\xd1\xf0\x38\xa1\x9e\xbb\xa9\x35\x0a\x91\x9c\x8f\xed\xd3\x76\x88\x5f\x36\x8c\xfe\xf6\xdb\xb6\x2e\x7e\xd4\xd6\xec\xcc\xd6\x72\xea\x19\x8e\x65\x39\x0d\xdb\x72\xe9\x14\xdd\x8a\x71\x1f\xb9\x76\x3b\x65\x29\x8a\x0d\x89\x2c\xe9\xbb\xc1\xdb\x27\xa3\xd3\xf0\x6b\x64\xb6\x1b\xbf\x8d\xa6\xed\x5d\xb7\xdf\x98\x28\x9d\x92\xd3\xcb\xe7\xe7\x4b\x97\x84\x21\x86\x9a\xa6\x98\x5c\xe4\xa0\xaf\x28\x43\x2e\x29\xb3\x20\x1f\x26\x1b\x8e\x76\xb8\x49\x36\xe7\x84\x9e\xc7\x25\xec\x42\x2e\x55\x05\x1e\x63\x03\x17\x35\x76\xe1\x3e\x82\xc3\xb9\x73\xd6\x5b\x56\x37\xff\xe0\xc4\x50\x4f\x27\x14\xb6\xb1\x52\x69\xb5\x15\xae\xfc\xf0\xb5\xd6\x82\x97\x99\xdc\x63\x4e\xb2\x35\xee\x96\x19\xed\xb8\xc4\x75\x27\xe6\xe5\x56\x68\x55\x16\xd8\xbd\xb4\x46\x0f\xf1\x7b\x38\xc2\xfd\x14\x76\xdc\x4d\x66\x2a\xa1\x7d\x3c\x3c\xcd\x4b\x54\x78\x23\x8c\x05\xb5\x35\xdf\x30\x9d\x61\xcd\x1b\x52\x6b\x62\x1b\x3e\x26\xdf\x42\x42\x22\xbc\x31\x6d\xe0\x91\xeb\x31\xd6\xbc\x6b\x62\x16\x0e\x35\x4b\xb9\xd3\x94\x62\x83\x43\x37\xb6\xef\xeb\x46\x04\xcf\x46\x60\xc4\x33\x4d\xf0\x6f\x9c\x0a\xa5\x39\x83\x06\x5a\x15\x1e\x45\x8a\x94\xab\x90\x71\x26\xb6\xbe\x16\xc6\x32\x5b\x9b\x49\x81\x18\xe0\xbf\x7f\xb3\x9c\x42\x72\x76\x45\x02\xfc\x09\xf2\x2a\xfc\xd3\x00\xf5\x88\x6f\x7e\x41\xff\x53\x8d\xb0\x4b\xb7\x45\xd2\xbb\x05\xb0\x8c\x83\x34\x6c\x8e\xe3\x9b\xa2\x4f\x18\xbe\x29\xcf\x95\x44\x32\x49\x9f\xa3\xb2\x92\xd0\x56\x1a\x2e\xfb\xde\x81\x3f\x9a\x1c\x8e\xdc\x7e\x58\xab\xb4\x36\xde\x9e\xb7\x19\x06\x3c\x42\x48\xfa\xee\x2e\xa0\x9c\x48\x24\x34\x51\x95\x9d\x88\x32\x84\xd5\xf5\xdc\xae\x9e\xe0\xe1\x31\xa5\xe6\xf5\xf4\xa8\xc8\x6b\xf3\x2c\xd8\xfd\x49\x1a\xe5\x02\xa6\x82\x3b\x56\x38\x4e\x9d\xd3\xb1\x31\x42\xce\x48\x44\xc3\xd7\x3e\xc7\x2d\x56\x1a\x54\x76\x42\x4a\x5a\x39\x1e\xee\x22\x02\xcd\x72\x90\x94\x4c\x8d\x0a\xad\x65\xad\x80\x61\x40\xe4\x6b\x6d\x2c\x88\x42\x45\x9d\xe6\xce\x47\x49\x7b\x55\x53\xa6\xa2\x91\x47\x60\xea\x21\xf0\x85\xe9\x2d\x9b\xcd\xa3\xca\x54\x8a\xf4\x2e\xe9\x6b\xfe\x9f\x9a\x1b\xfb\x16\x34\xb4\x7c\x38\xba\x0e\x49\x0b\xff\x71\x12\x2e\xf7\x6f\xbe\x80\x4d\x2e\x05\x56\x52\x90\x2c\xa7\x41\xe4\x7b\xb3\x2d\xfb\x72\x1a\x3a\xcf\x3d\x0e\x53\x2d\xaa\xd3\x4a\x4e\xbf\xb2\x2d\x0b\xa7\x1e\xf2\x75\x5d\xa6\x8e\x99\x74\xe6\x3f\xcc\x8b\x2d\x68\xd8\x04\x9a\x20\x8f\xb4\x76\xed\x11\x6d\xb8\x7d\x2d\xb9\xfb\xf5\xe7\xfd\xdb\x6c\x78\x16\xe4\x68\xec\x34\x09\xff\x29\x0d\x7e\x83\xc0\xef\x7c\xe5\x93\xc6\x52\x24\xca\x92\xeb\x37\xb7\xef\xdf\x85\x15\xd7\x9c\x1e\xf6\x4e\x42\x56\xd7\xcd\x42\x3d\x53\x80\xac\xff\x39\xc4\xe9\x3b\xba\x45\x21\x8a\xa2\x7e\x30\xe6\x02\xbe\xcf\x35\x2e\x96\x7c\x47\xff\x7c\xff\xee\x0d\x1e\xf1\x8d\xca\x30\x4c\x67\x88\x23\x0c\x91\x72\x38\xf8\xf4\xf1\xcb\x2d\xde\x4e\xe8\x71\x95\xf1\xbf\x7f\x7e\x3b\x1c\x34\x20\x4c\x82\xd9\xc1\xe8\xa8\x61\xb8\x6d\xcc\xbc\xf1\x03\x6e\x38\x78\x15\x1e\xea\x93\x5b\x60\x0b\x2b\x03\x56\x55\xd2\x4d\x2f\x80\x39\xfd\x8a\xc6\x1d\x9c\x2a\x97\xd9\xf0\x97\x2f\x1f\x3f\x44\xc6\xba\x19\x22\xd6\xfb\x61\x98\xc7\x9e\x37\x8b\xdf\x86\xb6\xdb\x56\xa3\x68\xcb\x64\xcd\x3d\xc0\xbd\x26\xd6\xd0\xba\x1e\xb3\xce\xf9\xfb\x40\xe7\x77\x60\x73\x90\xfa\x51\xef\x32\x7a\x72\x40\xa1\x94\x8a\x39\xc0\x5b\x12\xb4\x65\xf7\x30\x86\xa9\xf2\x3e\x0c\x95\xef\x95\xff\x6c\xfc\x84\xfa\xf7\x7a\x7e\xe4\xfc\x0d\x13\xe7\xbb\xba\xc7\xb9\x34\x0a\x15\xec\x89\x35\x0d\x3d\x68\xde\x2c\x25\x49\x82\x55\x35\x6b\x23\xeb\x75\xc2\x8a\x52\xc9\x8c\xf9\x80\x21\xe0\xa8\xd1\x3c\x37\xfa\x8f\x5d\xec\x70\x08\xbb\xe2\x57\x55\xeb\xc0\x1e\x5f\x31\x74\xb4\x41\x83\xa3\x63\x8d\x0b\x93\x3e\xe1\xab\x9e\xe1\x61\x86\xb8\x26\xd6\xa1\xc3\xfd\xec\x6d\xa8\x76\x92\x61\x54\x61\xef\x94\xf6\x03\x68\x14\xe1\xb5\x8e\xa7\xd6\xab\x5c\xc8\x6c\x78\xb8\xd0\xe6\xf6\x2d\x14\x5d\x1a\xfe\x03\xe9\x34\xef\x93\x1f\x4a\xe7\x36\xe7\xd8\x7c\x3b\x24\x81\xa6\xe0\x5a\x63\x8d\x60\xf3\x39\x34\x5c\xa3\xec\xbb\xc9\x1e\xd2\xb3\x7a\x8f\x8d\x85\x59\x41\x78\x15\x73\xdd\xcd\xee\x61\x5f\xae\x19\x02\xbf\xee\x48\x4f\xe3\xe8\xb4\xfb\xf5\x31\xdf\x6f\xdd\x3e\x68\xbf\xbc\xe1\xb9\xe1\xc7\x10\xa6\x10\x5e\x1c\xe1\xa9\x81\x0d\xe4\xbe\xae\xff\x3f\x00\x00\xff\xff\xc8\x18\x94\x09\xc5\x0f\x00\x00") func assetsIndexHtmlBytes() ([]byte, error) { return bindataRead( @@ -85,7 +85,7 @@ func assetsIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "assets/index.html", size: 3475, mode: os.FileMode(420), modTime: time.Unix(1456160915, 0)} + info := bindataFileInfo{name: "assets/index.html", size: 4037, mode: os.FileMode(420), modTime: time.Unix(1456558002, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/invite.go b/invite.go new file mode 100644 index 0000000..94599c6 --- /dev/null +++ b/invite.go @@ -0,0 +1,109 @@ +// Invite +// +// Provides a HTTP handler for signing up for a Slack invite and/or +// a MailChimp mailing list signup via a JSON request. + +package main + +import ( + "encoding/json" + "net/http" + "sync" + + "github.com/codegangsta/cli" + "github.com/mnbbrown/mailchimp" + "github.com/nlopes/slack" +) + +type invitationRequest struct { + Email string `json:"email"` + RequestSlack bool `json:"requestSlack"` + RequestMailingList bool `json:"requestMailingList"` +} + +type invitationResponse struct { + Message string `json:"message"` + ErrorCode int `json:"errorCode,omitempty"` +} + +func inviteRequestHandler(c *cli.Context) handleFunc { + return func(w http.ResponseWriter, req *http.Request) { + + decoder := json.NewDecoder(req.Body) + var invitation invitationRequest + err := decoder.Decode(&invitation) + if err != nil { + jsonResponse(w, invitationResponse{ + Message: "There was an error processing your invitation. Please try again later.", + ErrorCode: 1, + }, http.StatusInternalServerError) + return + } + + var ( + slackErr, chimpErr error + wg sync.WaitGroup + ) + + if invitation.RequestSlack { + wg.Add(1) + go func() { + defer wg.Done() + slackErr = inviteToSlack(c.String("slack-token"), c.String("slack-team"), "", "", invitation.Email) + }() + } + + if invitation.RequestMailingList { + wg.Add(1) + go func() { + defer wg.Done() + chimpErr = subscribeToList(c.String("mailchimp-token"), invitation.Email, c.String("mailchimp-list")) + }() + } + + wg.Wait() + + if slackErr != nil || chimpErr != nil { + var ( + message string + code int + ) + + if slackErr != nil && chimpErr != nil { + message = "There was an error processing your invitation. Please try again later." + code = 2 + } else if slackErr != nil { + message = "There was an error processing your invitation to the Slack group. Please try again later." + code = 3 + } else { + message = "There was an adding you to the mailing list. Please try again later." + code = 4 + } + + jsonResponse(w, invitationResponse{ + Message: message, + ErrorCode: code, + }, http.StatusInternalServerError) + return + } + + jsonResponse(w, invitationResponse{ + Message: "Your invitation has been sent. Please check your email.", + }, http.StatusOK) + } +} + +func inviteToSlack(slackToken, teamName, firstName, lastName, email string) error { + client := slack.New(slackToken) + return client.InviteToTeam(teamName, firstName, lastName, email) +} + +func subscribeToList(mailchimpApiKey, email, listId string) error { + client, err := mailchimp.NewClient(mailchimpApiKey, nil) + if err != nil { + return err + } + + _, err = client.Subscribe(email, listId) + return err +} diff --git a/main.go b/main.go index 8f2a277..9311fac 100644 --- a/main.go +++ b/main.go @@ -12,7 +12,7 @@ type handleFunc func(w http.ResponseWriter, req *http.Request) func main() { app := cli.NewApp() - app.Version = "1.0.3" + app.Version = "1.1.0" app.Usage = "hack bellingham website" app.Flags = []cli.Flag{ @@ -38,6 +38,16 @@ func main() { EnvVar: "HACK_BELLINGHAM_SLACK_TOKEN", Usage: "access token for your slack team", }, + cli.StringFlag{ + Name: "mailchimp-token", + EnvVar: "HACK_BELLINGHAM_MAILCHIMP_TOKEN", + Usage: "api token for your mailchimp account", + }, + cli.StringFlag{ + Name: "mailchimp-list", + EnvVar: "HACK_BELLINGHAM_MAILCHIMP_LIST", + Usage: "id of the mailchimp list", + }, } app.Action = serve @@ -46,7 +56,7 @@ func main() { } func serve(c *cli.Context) { - http.HandleFunc("/request-invite", slackInviteRequestHandler(c)) + http.HandleFunc("/request-invite", inviteRequestHandler(c)) http.HandleFunc("/status", statusHandler(c)) http.Handle("/", http.FileServer(assetFS())) diff --git a/slack.go b/slack.go deleted file mode 100644 index f8d915a..0000000 --- a/slack.go +++ /dev/null @@ -1,57 +0,0 @@ -// Slack -// -// Provides a HTTP handler for signing up for a Slack invite -// via a JSON request. - -package main - -import ( - "encoding/json" - "net/http" - - "github.com/codegangsta/cli" - "github.com/nlopes/slack" -) - -type invitationRequest struct { - Email string `json:"email"` -} - -type invitationResponse struct { - Message string `json:"message"` - ErrorCode int `json:"errorCode,omitempty"` -} - -func slackInviteRequestHandler(c *cli.Context) handleFunc { - return func(w http.ResponseWriter, req *http.Request) { - - decoder := json.NewDecoder(req.Body) - var invitation invitationRequest - err := decoder.Decode(&invitation) - if err != nil { - jsonResponse(w, invitationResponse{ - Message: "There was an error processing your invitation. Please try again later.", - ErrorCode: 1, - }, http.StatusInternalServerError) - return - } - - err = inviteToSlack(c.String("slack-token"), c.String("slack-team"), "", "", invitation.Email) - if err != nil { - jsonResponse(w, invitationResponse{ - Message: "There was an error processing your invitation. Please try again later.", - ErrorCode: 2, - }, http.StatusInternalServerError) - return - } - - jsonResponse(w, invitationResponse{ - Message: "Your invitation has been sent. Please check your email.", - }, http.StatusOK) - } -} - -func inviteToSlack(slackToken, teamName, firstName, lastName, email string) error { - client := slack.New(slackToken) - return client.InviteToTeam(teamName, firstName, lastName, email) -}