4 Commits
1.2.0 ... 1.2.2

Author SHA1 Message Date
2f25937a94 feat: add ical 2025-03-18 23:57:01 +01:00
658b8d4dd8 chore: 1.2.1 2025-03-18 23:38:08 +01:00
df6381fd5e feat: new email templates 2025-03-18 23:37:28 +01:00
a11e5f2f3e ci: drop main branch
All checks were successful
ci/woodpecker/push/build Pipeline was successful
2024-12-18 18:01:12 +01:00
7 changed files with 218 additions and 46 deletions

View File

@@ -1,19 +1,4 @@
steps:
- name: build latest
image: woodpeckerci/plugin-docker-buildx
settings:
repo: registry.odit.services/lfk/mailer
tags:
- latest
registry: registry.odit.services
platforms: linux/amd64,linux/arm64
cache_from: registry.odit.services/lfk/mailer:dev
username:
from_secret: odit-registry-builder-username
password:
from_secret: odit-registry-builder-password
when:
branch: main
- name: build dev
image: woodpeckerci/plugin-docker-buildx
settings:

View File

@@ -1,6 +1,6 @@
{
"name": "@odit/lfk-mailer",
"version": "1.2.0",
"version": "1.2.1",
"private": true,
"type": "module",
"scripts": {

View File

@@ -2,11 +2,13 @@ import { createTransport } from "nodemailer";
import { Queue, Worker, QueueEvents } from "bullmq";
import { config } from "../config/env";
import Redis from "ioredis";
import { Attachment } from "nodemailer/lib/mailer";
interface EmailJob {
to: string;
subject: string;
html: string;
attachments: Attachment[];
text: string;
}
@@ -40,12 +42,13 @@ const worker = new Worker<EmailJob>(
QUEUE_NAME,
async (job) => {
await transporter.sendMail({
from: config.email.from,
from: { address: config.email.from, name: "Lauf für Kaya!" },
replyTo: config.email.replyTo,
to: job.data.to,
subject: job.data.subject,
text: job.data.text,
html: job.data.html,
attachments: job.data.attachments,
});
},
{

View File

@@ -5,6 +5,7 @@ import { z } from 'zod'
import { EmailService } from '../services/email'
import { getEmailTemplate } from '../templates'
import { Language } from '../types'
import { Attachment } from 'nodemailer/lib/mailer'
const emailRouter = new Hono()
const emailService = new EmailService()
@@ -22,7 +23,7 @@ async function generateBarcodeDataURL(data) {
emailRouter.post('/', bearerAuth({ token: process.env.AUTHKEY }), zValidator('json', sendEmailSchema), async (c) => {
let { to, templateName, language, data } = c.req.valid('json')
const attachments: Attachment[] = []
try {
const template = getEmailTemplate(templateName, language as Language)
if (templateName === "welcome") {
@@ -32,6 +33,12 @@ emailRouter.post('/', bearerAuth({ token: process.env.AUTHKEY }), zValidator('js
} else {
return c.json({ success: false, error: "required params 'data.name', 'data.link', 'data.barcode_content' not provided" }, 406)
}
const attachment: Attachment = {
filename: 'invite.ics',
content: `BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//ICS Generator//NONSGML ICS Generator//DE\nBEGIN:VEVENT\nUID:1742337822408-5ghrzyi@icsgenerator.local\nDTSTAMP:20250318T224342Z\nSUMMARY:Lauf für Kaya! 2025\nDTSTART:20250523T110000Z\nDTEND:20250523T160000Z\nDESCRIPTION:Der Lauf für Kaya! 2025 findet am 23.05.2025 auf dem Sportplatz des Gymnasium Herzogenaurach statt. Zur Anmeldung einfach zum Infozelt kommen.\nLOCATION:Sportplatz Gymnasium Herzogenaurach\nBEGIN:VALARM\nACTION:DISPLAY\nDESCRIPTION:Erinnerung: Lauf für Kaya! 2025\nTRIGGER:-PT1440M\nEND:VALARM\nEND:VEVENT\nEND:VCALENDAR`,
contentType: 'text/calendar; method=REQUEST',
}
attachments.push(attachment)
}
if (templateName === "password-reset") {
if (data.token) {
@@ -45,6 +52,7 @@ emailRouter.post('/', bearerAuth({ token: process.env.AUTHKEY }), zValidator('js
data.event_name = process.env.EVENT_NAME
await emailService.sendEmail({
to,
attachments,
subject: template.subject(data),
html: template.html(data),
text: template.text(data)

View File

@@ -1,10 +1,12 @@
import { emailQueue } from '../queues/email.queue'
import { config } from '../config/env'
import { Attachment } from 'nodemailer/lib/mailer'
interface EmailOptions {
to: string
subject: string
html: string
attachments: Attachment[]
text: string
}

View File

@@ -175,8 +175,10 @@
-moz-osx-font-smoothing: grayscale;
"
>
Am Lauftag (<strong>{{event_date}}</strong>) musst du nur noch diesen
Barcode vorzeigen, damit erhältst du deine Läuferkarte.
Am Lauftag (<strong>{{event_date}}</strong>) musst du nur noch
diesen Barcode vorzeigen, damit erhältst du deine Läuferkarte.<br />Der
Bürger- & Firmenlauf findet von
<strong>13:00 bis 18:00 Uhr</strong> statt.
</p>
<table
align="center"
@@ -223,20 +225,103 @@
"
>
Deinen Registrierungs-Code, Rundenzeiten und weitere Infos kannst
du jederzeit im
du jederzeit im Lauf für Kaya! Selfservice einsehen.
</p>
<table
align="center"
width="100%"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="max-width: 100%; text-align: center; margin-bottom: 20px"
>
<tbody>
<tr style="width: 100%">
<td>
<a
href="{{link}}"
rel="noopener noreferrer nofollow"
style="
color: #111827;
text-decoration: underline;
line-height: 100%;
text-decoration: none;
display: inline-block;
max-width: 100%;
mso-padding-alt: 0px;
color: #ffffff;
background-color: #3a4bdd;
border-color: #3a4bdd;
border-width: 2px;
border-style: solid;
font-size: 14px;
font-weight: 500;
border-radius: 0px;
padding: 12px 32px 12px 32px;
"
target="_blank"
>Lauf für Kaya! Selfservice</a
><span
><!--[if mso
]><i
style="mso-font-width: 400%; mso-text-raise: 18"
hidden
>&#8202;&#8202;&#8202;&#8202;</i
><!
[endif]--></span
><span
style="
max-width: 100%;
display: inline-block;
line-height: 120%;
mso-padding-alt: 0px;
mso-text-raise: 9px;
"
>Zum Selfservice Portal</span
><span
><!--[if mso
]><i style="mso-font-width: 400%" hidden
>&#8202;&#8202;&#8202;&#8202;&#8203;</i
><!
[endif]--></span
></a
>
</td>
</tr>
</tbody>
</table>
<p
style="
font-size: 15px;
line-height: 26.25px;
margin: 0 0 20px 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #374151;
"
>
Wenn der Button nicht funktioniert, kannst du diesen Link in
deinen Browser kopieren:
<code
style="
background-color: #efefef;
color: #111827;
padding: 2px 4px;
border-radius: 6px;
font-family: SFMono-Regular, Menlo, Monaco, Consolas,
'Liberation Mono', 'Courier New', monospace;
font-weight: 400;
letter-spacing: 0;
"
>{{link}}</code
>
einsehen.
</p>
<hr
style="
width: 100%;
border: none;
border-top: 1px solid #eaeaea;
margin-top: 32px;
margin-bottom: 32px;
"
/>
<p
style="
font-size: 15px;

View File

@@ -175,7 +175,10 @@
-moz-osx-font-smoothing: grayscale;
"
>
On the day of the run (<strong>{{event_date}}</strong>) you only have to show your barcode to receive your runner's card.
On the day of the run (<strong>{{event_date}}</strong>) you only
have to show your barcode to receive your runner's card.<br />The
Citizens' & Company Run will take place from
<strong> 1:00 p.m. to 6:00 p.m.</strong>
</p>
<table
align="center"
@@ -221,19 +224,104 @@
-moz-osx-font-smoothing: grayscale;
"
>
You can view your registration code, lap times and further information at any time from the
You can view your registration code, lap times and further
information at any time from the Lauf für Kaya! Selfservice
</p>
<table
align="center"
width="100%"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="max-width: 100%; text-align: center; margin-bottom: 20px"
>
<tbody>
<tr style="width: 100%">
<td>
<a
href="{{link}}"
rel="noopener noreferrer nofollow"
style="
color: #111827;
text-decoration: underline;
line-height: 100%;
text-decoration: none;
display: inline-block;
max-width: 100%;
mso-padding-alt: 0px;
color: #ffffff;
background-color: #3a4bdd;
border-color: #3a4bdd;
border-width: 2px;
border-style: solid;
font-size: 14px;
font-weight: 500;
border-radius: 0px;
padding: 12px 32px 12px 32px;
"
target="_blank"
>Lauf für Kaya! Selfservice</a
><span
><!--[if mso
]><i
style="mso-font-width: 400%; mso-text-raise: 18"
hidden
>&#8202;&#8202;&#8202;&#8202;</i
><!
[endif]--></span
><span
style="
max-width: 100%;
display: inline-block;
line-height: 120%;
mso-padding-alt: 0px;
mso-text-raise: 9px;
"
>To the self-service portal</span
><span
><!--[if mso
]><i style="mso-font-width: 400%" hidden
>&#8202;&#8202;&#8202;&#8202;&#8203;</i
><!
[endif]--></span
></a
>
</td>
</tr>
</tbody>
</table>
<p
style="
font-size: 15px;
line-height: 26.25px;
margin: 0 0 20px 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #374151;
"
>
If the button doesn't work, you can copy this link into your
browser:
<code
style="
background-color: #efefef;
color: #111827;
padding: 2px 4px;
border-radius: 6px;
font-family: SFMono-Regular, Menlo, Monaco, Consolas,
'Liberation Mono', 'Courier New', monospace;
font-weight: 400;
letter-spacing: 0;
"
>{{link}}</code
>
</p>
<hr
style="
width: 100%;
border: none;
border-top: 1px solid #eaeaea;
margin-top: 32px;
margin-bottom: 32px;
"
/>
<p
style="
font-size: 15px;
@@ -262,7 +350,8 @@
-moz-osx-font-smoothing: grayscale;
"
>
If you have any questions, please reply to this e-mail at any time or write to
If you have any questions, please reply to this e-mail at any time
or write to
<u
><strong
><a