Skip to content

Commit 02a00b7

Browse files
committed
fix: added back mailchimp as it is used in newsletter subscriptions
1 parent 8023ef8 commit 02a00b7

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

src/server/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { getRates as getExchangeRates } from 'services/money';
2424
import { toJson as xmlToJson } from 'utils/xml2json';
2525

2626
import cdnRouter from './routes/cdn';
27+
import mailChimpRouter from './routes/mailchimp';
2728
import mockDocuSignFactory from './__mocks__/docu-sign-mock';
2829
import recruitCRMRouter from './routes/recruitCRM';
2930
import mmLeaderboardRouter from './routes/mmLeaderboard';
@@ -239,6 +240,7 @@ async function onExpressJsSetup(server) {
239240
});
240241

241242
server.use('/api/cdn', cdnRouter);
243+
server.use('/api/mailchimp', mailChimpRouter);
242244
server.use('/api/recruit', recruitCRMRouter);
243245
server.use('/api/mml', mmLeaderboardRouter);
244246

src/server/routes/mailchimp.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* The routes that expose our content to Content Delivery Networks.
3+
*/
4+
5+
import express from 'express';
6+
import MailchimpService from '../services/mailchimp';
7+
import { sendEmail } from '../services/sendGrid';
8+
9+
const routes = express.Router();
10+
/* Sets Access-Control-Allow-Origin header to avoid CORS error.
11+
* TODO: Replace the wildcard value by an appropriate origin filtering. */
12+
routes.use((req, res, next) => {
13+
res.set('Access-Control-Allow-Origin', '*');
14+
res.set('Access-Control-Allow-Headers', 'authorization, content-type');
15+
res.set('Access-Control-Allow-Methods', 'GET,POST,PUT,OPTIONS');
16+
next();
17+
});
18+
19+
/* do regist member to mailchimp server. */
20+
routes.post('/:listId/members', (req, res, next) => new MailchimpService().doRegistMember(req).then(res.send.bind(res), next));
21+
22+
routes.get('/:listId/members/:emailHash', (req, res) => new MailchimpService().checkSubscription(req).then(res.send.bind(res)));
23+
24+
routes.put('/:listId/members/:emailHash', (req, res) => new MailchimpService().updateMember(req).then(res.send.bind(res)));
25+
26+
routes.post('/:listId/members/:emailHash/tags', (req, res) => new MailchimpService().subscribeTags(req).then(res.send.bind(res)));
27+
28+
routes.get('/campaign-folders', (req, res) => new MailchimpService().getCampaignFolder(req).then(res.send.bind(res)));
29+
30+
routes.get('/campaigns', (req, res) => new MailchimpService().getCampaigns(req).then(res.send.bind(res)));
31+
32+
routes.post('/email', (req, res) => sendEmail(req, res).then(res.send.bind(res)));
33+
34+
export default routes;

src/server/services/mailchimp.js

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* Server-side functions necessary for effective integration with mailchimp
3+
*/
4+
import fetch from 'isomorphic-fetch';
5+
import config from 'config';
6+
import qs from 'qs';
7+
8+
/**
9+
* Auxiliary class that handles communication with mailchimp
10+
* APIs in the same uniform manner.
11+
*/
12+
export default class MailchimpService {
13+
/**
14+
* Creates a new service instance.
15+
* @param {String} baseUrl The base API endpoint.
16+
*/
17+
constructor(baseUrl) {
18+
this.private = { baseUrl };
19+
const credentials = config.SECRET.MAILCHIMP.default;
20+
this.mailchimpBaseUrl = credentials.MAILCHIMP_BASE_URL;
21+
this.apiKey = credentials.API_KEY;
22+
this.authorization = `Basic ${Buffer.from(`apikey:${this.apiKey}`).toString('base64')}`;
23+
}
24+
25+
/**
26+
* Gets data from the specified endpoint.
27+
* @return {Promise}
28+
* @param {Object} the request.
29+
*/
30+
async checkSubscription(req) {
31+
const res = await fetch(`${this.mailchimpBaseUrl}/lists/${req.params.listId}/members/${req.params.emailHash}`, {
32+
method: 'GET',
33+
headers: {
34+
'Content-Type': req.headers['content-type'],
35+
Authorization: this.authorization,
36+
},
37+
});
38+
return res.json();
39+
}
40+
41+
async doRegistMember(req) {
42+
const formData = JSON.stringify(req.body);
43+
const res = await fetch(`${this.mailchimpBaseUrl}/lists/${req.params.listId}/members`, {
44+
method: 'POST',
45+
headers: {
46+
'Content-Type': req.headers['content-type'],
47+
Authorization: this.authorization,
48+
},
49+
body: formData,
50+
});
51+
return res.json();
52+
}
53+
54+
async updateMember(req) {
55+
const formData = JSON.stringify(req.body);
56+
const res = await fetch(`${this.mailchimpBaseUrl}/lists/${req.params.listId}/members/${req.params.emailHash}`, {
57+
method: 'PUT',
58+
headers: {
59+
'Content-Type': req.headers['content-type'],
60+
Authorization: this.authorization,
61+
},
62+
body: formData,
63+
});
64+
return res.json();
65+
}
66+
67+
async subscribeTags(req) {
68+
const formData = JSON.stringify(req.body);
69+
const res = await fetch(`${this.mailchimpBaseUrl}/lists/${req.params.listId}/members/${req.params.emailHash}/tags`, {
70+
method: 'POST',
71+
headers: {
72+
'Content-Type': req.headers['content-type'],
73+
Authorization: this.authorization,
74+
},
75+
body: formData,
76+
});
77+
return { status: res.status };
78+
}
79+
80+
/**
81+
* Gets campaign-folders endpoint.
82+
* @return {Promise}
83+
* @param {Object} the request.
84+
*/
85+
async getCampaignFolder(req) {
86+
const res = await fetch(`${this.mailchimpBaseUrl}/campaign-folders?count=500`, {
87+
method: 'GET',
88+
headers: {
89+
'Content-Type': req.headers['content-type'],
90+
Authorization: this.authorization,
91+
},
92+
});
93+
return res.json();
94+
}
95+
96+
/**
97+
* Gets campaigns endpoint.
98+
* @return {Promise}
99+
* @param {Object} the request.
100+
*/
101+
async getCampaigns(req) {
102+
const res = await fetch(`${this.mailchimpBaseUrl}/campaigns?${qs.stringify(req.query)}`, {
103+
method: 'GET',
104+
headers: {
105+
'Content-Type': req.headers['content-type'],
106+
Authorization: this.authorization,
107+
},
108+
});
109+
return res.json();
110+
}
111+
}

0 commit comments

Comments
 (0)