aboutsummaryrefslogtreecommitdiff
path: root/emailing/send
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2020-12-28 06:38:05 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2020-12-28 06:38:05 +0100
commitda6a25065b6e300527a392ff66c74bbeb90ba192 (patch)
tree88e092adb9249963667328c5ef1cf561fe2982cf /emailing/send
parent4c066bedb82d4b705d0e60308ceee64daf97388c (diff)
downloadmitjafelicijan.com-da6a25065b6e300527a392ff66c74bbeb90ba192.tar.gz
Added new weekly links
Diffstat (limited to 'emailing/send')
-rwxr-xr-xemailing/send129
1 files changed, 129 insertions, 0 deletions
diff --git a/emailing/send b/emailing/send
new file mode 100755
index 0000000..66bdeb9
--- /dev/null
+++ b/emailing/send
@@ -0,0 +1,129 @@
1#!/usr/bin/env node
2
3const fs = require('fs');
4const path = require('path');
5const axios = require('axios');
6const dayjs = require('dayjs');
7const weekOfYear = require('dayjs/plugin/weekOfYear');
8const handlebars = require('handlebars');
9const yesno = require('yesno');
10const meow = require('meow');
11const { reverse } = require('dns');
12
13dayjs.extend(weekOfYear);
14
15(async function () {
16
17 const cli = meow(`
18 Usage
19 $ ./send <input>
20
21 Options
22 --production, -p Uses production mailing list
23
24 Examples
25 $ ./send campaigns/2020-51.json --production
26 `, {
27 flags: {
28 production: {
29 type: 'boolean',
30 alias: 'p'
31 }
32 }
33 });
34
35 if (cli.input.length === 0) {
36 console.log('You must provide campagin JSON file.');
37 process.exit(1);
38 }
39
40 const campaignJSONFile = cli.input[0];
41 const year = path.basename(cli.input[0]).split('.')[0].split('-')[0];
42 const week = path.basename(cli.input[0]).split('.')[0].split('-')[1];
43 const from = { name: 'Mitja Felicijan', email: 'weekly@mitjafelicijan.com' };
44 const mailingList = cli.flags.production
45 ? { env: 'production', id: 'b03de6fc-ff95-40a0-8707-c0706b3c0b31' }
46 : { env: 'testing', id: '2bbcdedb-49d8-48f3-9f33-df6e04c9e5bf' };
47
48 const headers = {
49 'Authorization': 'Bearer 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',
50 'Content-Type': 'application/json',
51 };
52
53 // gets current week
54 let campaign = null;
55 try {
56 campaign = require(`./${campaignJSONFile}`);
57 } catch (err) {
58 console.error(err);
59 process.exit(1);
60 }
61
62 // gets list subscribers
63 const personalizations = [];
64 const contacts = await axios.get('https://api.sendgrid.com/v3/marketing/contacts', { headers: headers }).catch(error => { console.log(error) });
65 if (contacts) {
66 for (const contact of contacts.data.result) {
67 if (contact.list_ids.includes(mailingList.id)) {
68 personalizations.push({ to: [{ email: contact.email }] });
69 }
70 }
71 }
72
73 // gets handlebars template contents
74 let template = null;
75 try {
76 template = handlebars.compile(fs.readFileSync('templates/mailing.hbs', 'utf8'));
77 template = template({ title: `${year}: Week #${week} Links`, campaign });
78 } catch (e) {
79 console.error(err);
80 process.exit(1);
81 }
82
83 fs.writeFileSync(`generated/${year}-${week}.html`, template);
84
85 // asks for user input to allow sending emails
86 console.log(`\nWill send to ${personalizations.length} subscribers from list "${mailingList.env}":`)
87 for (const subscriber of personalizations) {
88 console.log(' - ', subscriber.to[0].email)
89 }
90
91 const consent = await yesno({
92 question: '\nAre you sure you want to continue?'
93 });
94
95 if (consent) {
96 // send actual emails
97 await axios.post('https://api.sendgrid.com/v3/mail/send', {
98 from,
99 subject: `Week #${week} Links`,
100 personalizations,
101 content: [{
102 type: 'text/html',
103 value: template
104 }]
105 }, { headers: headers }).catch(error => { console.log(error) });
106 }
107
108 console.log('\nAnd we are done.\n');
109
110 // generates index file
111
112 const HTMLFiles = fs.readdirSync('./generated/');
113 const indexFile = HTMLFiles.indexOf('index.html');
114 if (indexFile > -1) HTMLFiles.splice(indexFile, 1);
115
116 HTMLFiles.forEach((item, idx) => {
117 const parts = item.split('.')[0].split('-');
118 HTMLFiles[idx] = {
119 year: parts[0],
120 week: parts[1],
121 file: item,
122 }
123 });
124
125 let indexTemplate = handlebars.compile(fs.readFileSync('templates/index.hbs', 'utf8'));
126 indexTemplate = indexTemplate({ files: HTMLFiles.reverse() });
127 fs.writeFileSync(`generated/index.html`, indexTemplate);
128
129}());