diff --git a/ansible/inventory.yaml b/ansible/inventory.yaml
index a14fcdadca7..f9ed7d98ebe 100644
--- a/ansible/inventory.yaml
+++ b/ansible/inventory.yaml
@@ -15,3 +15,4 @@ all:
backend3.freesewing.org:
monorepo: /fs/monorepo
+
diff --git a/config/newsletter-testers.mjs b/config/newsletter-testers.mjs
index 523410dab12..ddb771e2e37 100644
--- a/config/newsletter-testers.mjs
+++ b/config/newsletter-testers.mjs
@@ -1,10 +1,14 @@
-export const testers = [
- {
- email: 'joost@joost.at',
- ehash: 'asefsdfsdfsdlfsllehash',
- },
- {
- email: 'joost@decock.org',
- ehash: 'zlasdadfsdlfsjjuehash',
- },
-]
+export const testers = {
+ en: [
+ {
+ email: 'joost@joost.at',
+ ehash: 'asefsdfsdfsdlfsllehash',
+ },
+ ],
+ nl: [
+ {
+ email: 'joost@decock.org',
+ ehash: 'zlasdadfsdlfsjjuehash',
+ },
+ ],
+}
diff --git a/config/templates/newsletter.html b/config/templates/newsletter.html
index 7de792f5083..161aa0919e8 100644
--- a/config/templates/newsletter.html
+++ b/config/templates/newsletter.html
@@ -19,7 +19,7 @@
-
FreeSewing Newsletter
+ {{ title }}
@@ -323,7 +323,7 @@
"
>
Support FreeSewing: Become a Patron{{ support }}
@@ -356,8 +356,7 @@
>
- You can unsubscribe at any time. Or just reply and
- tell us you want out.
+ {{ unsub1 }}. {{ unsub2 }}
diff --git a/package.json b/package.json
index ab1361e07e5..b23e892d98b 100644
--- a/package.json
+++ b/package.json
@@ -103,6 +103,7 @@
"c8": "^8.0.0",
"eslint-config-next": "^14.0.1",
"glob": "^10.3.10",
+ "rehype-format": "^5.0.0",
"yarn": "^1.22.19"
},
"packageManager": "yarn@1.22.19"
diff --git a/scripts/newsletter-lib.mjs b/scripts/newsletter-lib.mjs
index 742f481344f..0619cf8962c 100644
--- a/scripts/newsletter-lib.mjs
+++ b/scripts/newsletter-lib.mjs
@@ -12,10 +12,50 @@ import { testers } from '../config/newsletter-testers.mjs'
import { fileURLToPath } from 'url'
import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2'
+console.log({ edition: process.env.NL_EDITION })
// Current working directory
const cwd = path.dirname(fileURLToPath(import.meta.url))
-const backend = 'https://backend.freesewing.org/'
+const backend = 'https://backend3.freesewing.org/'
+
+const i18n = {
+ en: {
+ title: 'FreeSewing newsletter',
+ support: 'Support FreeSewing: Become a patron',
+ unsub1: 'You can unsubscribe at any time',
+ unsub2: 'Or reply and tell us you want out',
+ },
+ nl: {
+ title: 'FreeSewing nieuwsbrief',
+ support: 'Steun FreeSewing: Wordt mecenas',
+ unsub1: 'Je kan je op elk moment uitschrijven',
+ unsub2: 'Of stuur een reply en laat ons weten dat het niet meer hoeft',
+ },
+ fr: {
+ title: "Bulletin d'info FreeSewing",
+ support: 'Soutenir FreeSewing : Devenir mécène',
+ unsub1: 'Vous pouvez vous désabonner à tout moment',
+ unsub2: 'Ou répondez et dites-nous que vous voulez vous désabonner',
+ },
+ de: {
+ title: 'FreeSewing-Newsletter',
+ support: 'Unterstützen Sie FreeSewing: Werden Sie Gönner',
+ unsub1: 'Sie können sich jederzeit wieder abmelden',
+ unsub2: 'Oder antworten Sie uns und sagen Sie uns, dass Sie nicht mehr wollen',
+ },
+ de: {
+ title: 'FBoletín FreeSewing',
+ support: 'Apoya FreeSewing: Hazte mecenas',
+ unsub1: 'Puedes darte de baja en cualquier momento',
+ unsub2: 'O contesta y dinos que quieres darte de baja',
+ },
+ de: {
+ title: 'Інформаційний бюлетень FreeSewing',
+ support: 'Підтримайте FreeSewing: Стати меценатом',
+ unsub1: 'Ви можете відписатися в будь-який час',
+ unsub2: 'Або надішліть нам відповідь і скажіть, що хочете відмовитися',
+ },
+}
const asHtml = async (text) => {
const content = await unified()
@@ -29,20 +69,13 @@ const asHtml = async (text) => {
return content.value
}
-const getToken = async () => {
- let res = await axios.post(`${backend}login`, {
- username: process.env.FS_USER,
- password: process.env.FS_PASSWORD,
- })
- if (res.data) return res.data.token
- else if (res.err) return console.log(res.err)
-}
-
const getSubscribers = async (test = true) => {
if (test) return testers
- let token = await getToken()
let res = await axios.get(`${backend}admin/subscribers`, {
- headers: { Authorization: 'Bearer ' + token },
+ auth: {
+ username: process.env.NL_API_KEY,
+ password: process.env.NL_API_SECRET,
+ },
})
if (res.data) return res.data
else return false
@@ -51,75 +84,82 @@ const getSubscribers = async (test = true) => {
const send = async (test = true) => {
const us = 'FreeSewing '
const template = fs.readFileSync(`${cwd}/../config/templates/newsletter.html`, 'utf8')
- let edition
- try {
- edition = await axios.get(
- `https://posts.freesewing.org/newsletters?slug_eq=${process.env.NL_EDITION}`,
- 'utf8'
- )
- } catch (err) {
- console.log(err)
- process.exit()
- }
- const text = edition.data[0].body
-
const subscribers = await getSubscribers(test)
- const content = await asHtml(text)
- const inject = { content }
// Oh AWS your APIs are such a clusterfuck
const client = new SESv2Client({ region: 'us-east-1' })
let i = 1
- subscribers.sort()
- let subs = subscribers.length
- for (let sub of subscribers) {
- // If your SMTP relay start rate-limiting midway through
- // you can use this if loop to start just after the last
- // successful delivery
- if (i > 0) {
- let unsub = `${backend}newsletter/unsubscribe/${sub.ehash}`
- inject.unsubscribe = unsub
- let body = mustache.render(template, inject)
- console.log(`${i}/${subs} Sending to ${sub.email}`)
+ let l = 1
+ for (const lang in subscribers) {
+ let edition
+ try {
+ edition = await axios.get(
+ `https://raw.githubusercontent.com/freesewing/freesewing/develop/markdown/org/newsletter/${process.env.NL_EDITION}/${lang}.md`,
+ 'utf8'
+ )
+ } catch (err) {
+ console.log(err)
+ process.exit()
+ }
+ console.log(edition.data)
+ const text = edition.data[0].body
+ const content = await asHtml(text)
- // Via API
- const command = new SendEmailCommand({
- ConfigurationSetName: 'Newsletter',
- Content: {
- Simple: {
- Body: {
- Text: {
- Charset: 'utf-8',
- Data: text,
+ console.log(content)
+
+ process.exit()
+
+ subscribers[lang].sort()
+ let subs = subscribers[lang].length
+ for (let sub of subscribers[lang]) {
+ if (i > 0) {
+ let unsub = `${backend}newsletter/unsubscribe/${sub.ehash}`
+ inject.unsubscribe = unsub
+ let body = mustache.render(template, {
+ ...i18n[lang],
+ content,
+ })
+ console.log(`[${lang}] ${i}/${subs} Sending to ${sub.email}`)
+
+ // Via API
+ const command = new SendEmailCommand({
+ ConfigurationSetName: 'Newsletter',
+ Content: {
+ Simple: {
+ Body: {
+ Text: {
+ Charset: 'utf-8',
+ Data: text,
+ },
+ Html: {
+ Charset: 'utf-8',
+ Data: body,
+ },
},
- Html: {
+ Subject: {
Charset: 'utf-8',
- Data: body,
+ Data: 'FreeSewing newsletter: Autumn 2023',
},
},
- Subject: {
- Charset: 'utf-8',
- Data: 'FreeSewing newsletter: Autumn 2023',
- },
},
- },
- Destination: {
- ToAddresses: [sub.email],
- },
- //FeedbackForwardingEmailAddress: us,
- FromEmailAddress: us,
- //FromEmailAddressIdentityArn: "arn:aws:ses:us-east-1:550348293871:identity/freesewing.org",
- //ReplyToAddresses: us,
- })
- try {
- await client.send(command)
- } catch (err) {
- console.log(err)
- return false
+ Destination: {
+ ToAddresses: [sub.email],
+ },
+ //FeedbackForwardingEmailAddress: us,
+ FromEmailAddress: us,
+ //FromEmailAddressIdentityArn: "arn:aws:ses:us-east-1:550348293871:identity/freesewing.org",
+ //ReplyToAddresses: us,
+ })
+ //try {
+ // await client.send(command)
+ //} catch (err) {
+ // console.log(err)
+ // return false
+ //}
}
+ i++
}
- i++
}
}