feat(analytics-mailer): replace mailgun with stalwart smtp
Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 3s
Monorepo Pipeline / 🧹 Lint (push) Failing after 1m23s
Monorepo Pipeline / 🧪 Test (push) Successful in 40s
Monorepo Pipeline / 🏗️ Build (push) Successful in 2m7s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 3s
Monorepo Pipeline / 🧹 Lint (push) Failing after 1m23s
Monorepo Pipeline / 🧪 Test (push) Successful in 40s
Monorepo Pipeline / 🏗️ Build (push) Successful in 2m7s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
This commit is contained in:
@@ -28,9 +28,11 @@ jobs:
|
|||||||
UMAMI_BASE_URL: ${{ secrets.UMAMI_BASE_URL }}
|
UMAMI_BASE_URL: ${{ secrets.UMAMI_BASE_URL }}
|
||||||
UMAMI_USERNAME: ${{ secrets.UMAMI_USERNAME }}
|
UMAMI_USERNAME: ${{ secrets.UMAMI_USERNAME }}
|
||||||
UMAMI_PASSWORD: ${{ secrets.UMAMI_PASSWORD }}
|
UMAMI_PASSWORD: ${{ secrets.UMAMI_PASSWORD }}
|
||||||
MAILGUN_API_KEY: ${{ secrets.MAILGUN_API_KEY }}
|
SMTP_HOST: ${{ secrets.SMTP_HOST }}
|
||||||
MAILGUN_DOMAIN: ${{ secrets.MAILGUN_DOMAIN }}
|
SMTP_PORT: ${{ secrets.SMTP_PORT }}
|
||||||
MAILGUN_SENDER: ${{ secrets.MAILGUN_SENDER }}
|
SMTP_USER: ${{ secrets.SMTP_USER }}
|
||||||
|
SMTP_PASS: ${{ secrets.SMTP_PASS }}
|
||||||
|
SMTP_SENDER: ${{ secrets.SMTP_SENDER }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
"@mintel/mail": "workspace:*",
|
"@mintel/mail": "workspace:*",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"form-data": "^4.0.1",
|
"nodemailer": "^9.0.3"
|
||||||
"mailgun.js": "^10.3.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@mintel/eslint-config": "workspace:*",
|
"@mintel/eslint-config": "workspace:*",
|
||||||
"@mintel/tsconfig": "workspace:*",
|
"@mintel/tsconfig": "workspace:*",
|
||||||
"@types/node": "^22.19.10",
|
"@types/node": "^22.19.10",
|
||||||
|
"@types/nodemailer": "^8.0.1",
|
||||||
"tsup": "^8.3.5",
|
"tsup": "^8.3.5",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.7.2",
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import axios from "axios";
|
|||||||
import { render } from "@mintel/mail";
|
import { render } from "@mintel/mail";
|
||||||
import { AnalyticsTemplate } from "@mintel/mail";
|
import { AnalyticsTemplate } from "@mintel/mail";
|
||||||
import { getLast7Days, getThisMonth, getThisYear } from "./utils/time-calculator";
|
import { getLast7Days, getThisMonth, getThisYear } from "./utils/time-calculator";
|
||||||
import Mailgun from "mailgun.js";
|
import nodemailer from "nodemailer";
|
||||||
import formData from "form-data";
|
|
||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
@@ -15,10 +14,11 @@ const UMAMI_USERNAME = process.env.UMAMI_USERNAME;
|
|||||||
const UMAMI_PASSWORD = process.env.UMAMI_PASSWORD;
|
const UMAMI_PASSWORD = process.env.UMAMI_PASSWORD;
|
||||||
const UMAMI_API_KEY = process.env.UMAMI_API_KEY;
|
const UMAMI_API_KEY = process.env.UMAMI_API_KEY;
|
||||||
|
|
||||||
const MAILGUN_API_KEY = process.env.MAILGUN_API_KEY;
|
const SMTP_HOST = process.env.SMTP_HOST || "mail.infra.mintel.me";
|
||||||
const MAILGUN_DOMAIN = process.env.MAILGUN_DOMAIN;
|
const SMTP_PORT = parseInt(process.env.SMTP_PORT || "587", 10);
|
||||||
const MAILGUN_SENDER = process.env.MAILGUN_SENDER || "reports@mintel.me";
|
const SMTP_USER = process.env.SMTP_USER;
|
||||||
const MAILGUN_URL = process.env.MAILGUN_URL || "https://api.eu.mailgun.net";
|
const SMTP_PASS = process.env.SMTP_PASS;
|
||||||
|
const SMTP_SENDER = process.env.SMTP_SENDER || "reports@mintel.me";
|
||||||
|
|
||||||
interface ConfigClient {
|
interface ConfigClient {
|
||||||
websiteId: string;
|
websiteId: string;
|
||||||
@@ -116,9 +116,16 @@ async function main() {
|
|||||||
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
||||||
const api = axios.create({ baseURL: `${UMAMI_BASE_URL}/api`, headers, httpsAgent });
|
const api = axios.create({ baseURL: `${UMAMI_BASE_URL}/api`, headers, httpsAgent });
|
||||||
|
|
||||||
// Setup Mailgun
|
// Setup SMTP Transporter (Nodemailer)
|
||||||
const mailgun = new Mailgun(formData);
|
const transporter = nodemailer.createTransport({
|
||||||
const mg = mailgun.client({ username: "api", key: MAILGUN_API_KEY || "dummy", url: MAILGUN_URL });
|
host: SMTP_HOST,
|
||||||
|
port: SMTP_PORT,
|
||||||
|
secure: SMTP_PORT === 465,
|
||||||
|
auth: SMTP_USER && SMTP_PASS ? {
|
||||||
|
user: SMTP_USER,
|
||||||
|
pass: SMTP_PASS,
|
||||||
|
} : undefined,
|
||||||
|
});
|
||||||
|
|
||||||
const timeRanges = [getLast7Days(), getThisMonth(), getThisYear()];
|
const timeRanges = [getLast7Days(), getThisMonth(), getThisYear()];
|
||||||
|
|
||||||
@@ -153,12 +160,12 @@ async function main() {
|
|||||||
await fs.writeFile(debugPath, html);
|
await fs.writeFile(debugPath, html);
|
||||||
console.log(`[DRY-RUN] Saved HTML preview to ${debugPath}`);
|
console.log(`[DRY-RUN] Saved HTML preview to ${debugPath}`);
|
||||||
} else {
|
} else {
|
||||||
if (!MAILGUN_API_KEY) {
|
if (!SMTP_HOST) {
|
||||||
throw new Error("MAILGUN_API_KEY is missing for live run.");
|
throw new Error("SMTP_HOST is missing for live run.");
|
||||||
}
|
}
|
||||||
await mg.messages.create(MAILGUN_DOMAIN!, {
|
await transporter.sendMail({
|
||||||
from: MAILGUN_SENDER,
|
from: SMTP_SENDER,
|
||||||
to: [client.clientEmail],
|
to: client.clientEmail,
|
||||||
subject,
|
subject,
|
||||||
html,
|
html,
|
||||||
});
|
});
|
||||||
|
|||||||
51
pnpm-lock.yaml
generated
51
pnpm-lock.yaml
generated
@@ -115,12 +115,9 @@ importers:
|
|||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.4.7
|
specifier: ^16.4.7
|
||||||
version: 16.6.1
|
version: 16.6.1
|
||||||
form-data:
|
nodemailer:
|
||||||
specifier: ^4.0.1
|
specifier: ^9.0.3
|
||||||
version: 4.0.5
|
version: 9.0.3
|
||||||
mailgun.js:
|
|
||||||
specifier: ^10.3.0
|
|
||||||
version: 10.4.0
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@mintel/eslint-config':
|
'@mintel/eslint-config':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
@@ -131,6 +128,9 @@ importers:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.19.10
|
specifier: ^22.19.10
|
||||||
version: 22.19.10
|
version: 22.19.10
|
||||||
|
'@types/nodemailer':
|
||||||
|
specifier: ^8.0.1
|
||||||
|
version: 8.0.1
|
||||||
tsup:
|
tsup:
|
||||||
specifier: ^8.3.5
|
specifier: ^8.3.5
|
||||||
version: 8.5.1(@swc/core@1.15.11(@swc/helpers@0.5.18))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)
|
version: 8.5.1(@swc/core@1.15.11(@swc/helpers@0.5.18))(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)
|
||||||
@@ -3599,6 +3599,9 @@ packages:
|
|||||||
'@types/node@22.19.10':
|
'@types/node@22.19.10':
|
||||||
resolution: {integrity: sha512-tF5VOugLS/EuDlTBijk0MqABfP8UxgYazTLo3uIn3b4yJgg26QRbVYJYsDtHrjdDUIRfP70+VfhTTc+CE1yskw==}
|
resolution: {integrity: sha512-tF5VOugLS/EuDlTBijk0MqABfP8UxgYazTLo3uIn3b4yJgg26QRbVYJYsDtHrjdDUIRfP70+VfhTTc+CE1yskw==}
|
||||||
|
|
||||||
|
'@types/nodemailer@8.0.1':
|
||||||
|
resolution: {integrity: sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==}
|
||||||
|
|
||||||
'@types/parse-json@4.0.2':
|
'@types/parse-json@4.0.2':
|
||||||
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
|
||||||
|
|
||||||
@@ -4303,9 +4306,6 @@ packages:
|
|||||||
bare-url@2.3.2:
|
bare-url@2.3.2:
|
||||||
resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==}
|
resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==}
|
||||||
|
|
||||||
base-64@1.0.0:
|
|
||||||
resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
|
|
||||||
|
|
||||||
base64-arraybuffer@1.0.2:
|
base64-arraybuffer@1.0.2:
|
||||||
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
|
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
|
||||||
engines: {node: '>= 0.6.0'}
|
engines: {node: '>= 0.6.0'}
|
||||||
@@ -6478,10 +6478,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
|
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
mailgun.js@10.4.0:
|
|
||||||
resolution: {integrity: sha512-YrdaZEAJwwjXGBTfZTNQ1LM7tmkdUaz2NpZEu7+zULcG4Wrlhd7cWSNZW0bxT3bP48k5N0mZWz8C2f9gc2+Geg==}
|
|
||||||
engines: {node: '>=18.0.0'}
|
|
||||||
|
|
||||||
map-stream@0.1.0:
|
map-stream@0.1.0:
|
||||||
resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
|
resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
|
||||||
|
|
||||||
@@ -6777,6 +6773,10 @@ packages:
|
|||||||
node-releases@2.0.27:
|
node-releases@2.0.27:
|
||||||
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
|
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
|
||||||
|
|
||||||
|
nodemailer@9.0.3:
|
||||||
|
resolution: {integrity: sha512-n+YP+NKwR5zRWa60k3GiQ6Q3B4KXCoAw40dAKeCtYn020iNN74aWK2liXIC3ZEATeGql7we3tE3t8QwhY0eskw==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
normalize-path@3.0.0:
|
normalize-path@3.0.0:
|
||||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -8368,9 +8368,6 @@ packages:
|
|||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||||
|
|
||||||
url-join@4.0.1:
|
|
||||||
resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
|
|
||||||
|
|
||||||
use-context-selector@2.0.0:
|
use-context-selector@2.0.0:
|
||||||
resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==}
|
resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -11655,6 +11652,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.21.0
|
undici-types: 6.21.0
|
||||||
|
|
||||||
|
'@types/nodemailer@8.0.1':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.19.33
|
||||||
|
|
||||||
'@types/parse-json@4.0.2': {}
|
'@types/parse-json@4.0.2': {}
|
||||||
|
|
||||||
'@types/pg-pool@2.0.7':
|
'@types/pg-pool@2.0.7':
|
||||||
@@ -12049,7 +12050,7 @@ snapshots:
|
|||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
sirv: 3.0.2
|
sirv: 3.0.2
|
||||||
tinyglobby: 0.2.15
|
tinyglobby: 0.2.15
|
||||||
tinyrainbow: 3.0.3
|
tinyrainbow: 3.1.0
|
||||||
vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.33)(@vitest/ui@4.0.18)(happy-dom@20.5.3)(jiti@2.6.1)(jsdom@27.4.0(canvas@3.2.1))(lightningcss@1.30.2)(sass@1.97.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -12465,8 +12466,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
bare-path: 3.0.0
|
bare-path: 3.0.0
|
||||||
|
|
||||||
base-64@1.0.0: {}
|
|
||||||
|
|
||||||
base64-arraybuffer@1.0.2: {}
|
base64-arraybuffer@1.0.2: {}
|
||||||
|
|
||||||
base64-js@0.0.8: {}
|
base64-js@0.0.8: {}
|
||||||
@@ -14143,7 +14142,7 @@ snapshots:
|
|||||||
|
|
||||||
happy-dom@20.5.3:
|
happy-dom@20.5.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.33
|
'@types/node': 22.19.10
|
||||||
'@types/whatwg-mimetype': 3.0.2
|
'@types/whatwg-mimetype': 3.0.2
|
||||||
'@types/ws': 8.18.1
|
'@types/ws': 8.18.1
|
||||||
entities: 6.0.1
|
entities: 6.0.1
|
||||||
@@ -14950,14 +14949,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
mailgun.js@10.4.0:
|
|
||||||
dependencies:
|
|
||||||
axios: 1.13.5
|
|
||||||
base-64: 1.0.0
|
|
||||||
url-join: 4.0.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- debug
|
|
||||||
|
|
||||||
map-stream@0.1.0: {}
|
map-stream@0.1.0: {}
|
||||||
|
|
||||||
marked@14.0.0: {}
|
marked@14.0.0: {}
|
||||||
@@ -15197,6 +15188,8 @@ snapshots:
|
|||||||
|
|
||||||
node-releases@2.0.27: {}
|
node-releases@2.0.27: {}
|
||||||
|
|
||||||
|
nodemailer@9.0.3: {}
|
||||||
|
|
||||||
normalize-path@3.0.0: {}
|
normalize-path@3.0.0: {}
|
||||||
|
|
||||||
normalize-svg-path@1.1.0:
|
normalize-svg-path@1.1.0:
|
||||||
@@ -17165,8 +17158,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
url-join@4.0.1: {}
|
|
||||||
|
|
||||||
use-context-selector@2.0.0(react@19.2.4)(scheduler@0.25.0):
|
use-context-selector@2.0.0(react@19.2.4)(scheduler@0.25.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.2.4
|
react: 19.2.4
|
||||||
|
|||||||
Reference in New Issue
Block a user