diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2020-12-29 00:44:19 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2020-12-29 00:44:19 +0100 |
| commit | d4728e6972882e09ead61214367a35c5c6feafef (patch) | |
| tree | 59106b2fb5e18519e8f415ec0716528340734558 /newsletter/send | |
| parent | da6a25065b6e300527a392ff66c74bbeb90ba192 (diff) | |
| download | mitjafelicijan.com-d4728e6972882e09ead61214367a35c5c6feafef.tar.gz | |
Added newsletter
Diffstat (limited to 'newsletter/send')
| -rwxr-xr-x | newsletter/send | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/newsletter/send b/newsletter/send new file mode 100755 index 0000000..66bdeb9 --- /dev/null +++ b/newsletter/send | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | #!/usr/bin/env node | ||
| 2 | |||
| 3 | const fs = require('fs'); | ||
| 4 | const path = require('path'); | ||
| 5 | const axios = require('axios'); | ||
| 6 | const dayjs = require('dayjs'); | ||
| 7 | const weekOfYear = require('dayjs/plugin/weekOfYear'); | ||
| 8 | const handlebars = require('handlebars'); | ||
| 9 | const yesno = require('yesno'); | ||
| 10 | const meow = require('meow'); | ||
| 11 | const { reverse } = require('dns'); | ||
| 12 | |||
| 13 | dayjs.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 | }()); | ||
