diff --git a/README.md b/README.md index 6515bc4..5044e9d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ - [Tasks](#tasks) - [Medium](#medium) - [YouTube](#youtube) - - [Bounties](#Bounties) + - [Bounties](#bounties) + - [MailChimp](#mailchimp) - [Zoho](#zoho) - [Campaigns API](#campaigns-api) - [CRM API](#crm-api) @@ -79,6 +80,19 @@ Response is structured by network and fills it with whatever comes back from res } ``` +### MailChimp + +**`webtask-mailchimp.js`**: Task to add a new newsletter subscriber. + +Construct your `/` request url like so, e.g. locally: + +```bash +http://localhost:8080/newsletter/jelly@mcjellyfish.com + +# when published on webtask.io +https://TASK_URL/TASK_NAME/newsletter/jelly@mcjellyfish.com +``` + ### Zoho **`webtask-zoho.js`**: Generic task to subscribe users into lists on Zoho Campaigns & Zoho CRM. diff --git a/package.json b/package.json index 6ca0ed9..8540737 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "start": "wt serve webtask-bounties.js", + "start": "wt serve webtask-mailchimp.js", "test": "eslint ./*.js" }, "dependencies": { diff --git a/webtask-mailchimp.js b/webtask-mailchimp.js new file mode 100644 index 0000000..6141aac --- /dev/null +++ b/webtask-mailchimp.js @@ -0,0 +1,105 @@ +const express = require('express') +const Webtask = require('webtask-tools') +const cors = require('cors') +const crypto = require('crypto') +const bodyParser = require('body-parser') +const request = require('request') + +const server = express() + +server.listen(4430) +server.use(bodyParser.json()) + +// +// Allow requests from these domains only +// +const corsOptions = { + origin: ['https://oceanprotocol.com', /\.oceanprotocol\.com$/], + optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 +} + +server.use(cors(corsOptions)) + +const baseUrl = 'https://us16.api.mailchimp.com/3.0' +const listId = '3c6eed8b71' + +const md5 = data => crypto.createHash('md5').update(data).digest('hex') + +server.post('/newsletter/:email', (req, res) => { + const { email } = req.params + const { MAILCHIMP_API_KEY } = req.webtaskContext.secrets + const emailDecoded = decodeURIComponent(email) + const subscriberHash = md5(emailDecoded) + + const baseOptions = { + url: `${baseUrl}/lists/${listId}/members/${subscriberHash}`, + 'auth': { + 'user': 'oceanprotocol', + 'pass': MAILCHIMP_API_KEY + } + } + + const optionsCreate = { + ...baseOptions, + json: { + 'email_address': emailDecoded, + 'status': 'pending', // double opt-in + 'merge_fields': { + // our GDPR fallback + 'GDPR': 'yes' + } + } + } + + const optionsMarketing = marketingPermissionId => ( + { + ...baseOptions, + json: { + 'marketing_permissions': [{ + 'marketing_permission_id': marketingPermissionId, + 'text': 'Email', + 'enabled': true + }] + } + } + ) + + const addMarketingPermissions = (data, cb) => { + const marketingPermissionId = data.marketing_permissions[0].marketing_permission_id + + request.patch(optionsMarketing(marketingPermissionId), (error, response, body) => { + if (error) res.send(error) + + return cb(body) + }) + } + + // Check if user exists first + request.get(baseOptions, (error, response, body) => { + if (error) res.send(error) + + // Member exists and is subscribed + if (body.status === 'subscribed') { + // Patch in native GDPR permissions + addMarketingPermissions(body, () => { + res.send('{ "status": "exists" }') + }) + } else { + // Create user + request.put(optionsCreate, (error2, response, body2) => { + if (error2) res.send(error2) + + if (Number.isInteger(body2.status)) { + res.send(body2) + } + + // Patch in native GDPR permissions + addMarketingPermissions(body2, () => { + res.send('{ "status": "created" }') + }) + }) + } + }) +}) + +module.exports = Webtask.fromExpress(server)