Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
4257686f35
|
|||
|
2f25937a94
|
|||
|
658b8d4dd8
|
|||
|
df6381fd5e
|
|||
|
a11e5f2f3e
|
|||
|
7a8e484632
|
|||
|
1f771fb73f
|
|||
|
34c8f03571
|
|||
|
dfac4c0fe9
|
|||
|
9860014420
|
|||
|
bfce0c22c0
|
|||
|
828290d9ba
|
|||
|
96e3be543b
|
|||
|
c8781e3a3d
|
|||
|
22ab25045c
|
|||
|
2230259e4a
|
|||
|
57f3a910f6
|
|||
|
9076a9488e
|
@@ -6,6 +6,8 @@ EMAIL_FROM="noreply@lauf-fuer-kaya.de"
|
||||
EMAIL_REPLYTO="info@lauf-fuer-kaya.de"
|
||||
REDIS_URL=redis://localhost:6379
|
||||
FRONTEND_URL="https://run.lauf-fuer-kaya.de"
|
||||
DOCUMENT_SERVER_URL="https://documents.run.lauf-fuer-kaya.de"
|
||||
AUTHKEY=""
|
||||
EVENT_DATE="23.05.2025"
|
||||
EVENT_NAME="Lauf für Kaya! 2025"
|
||||
EVENT_NAME="Lauf für Kaya! 2025"
|
||||
NODE_ENV=production
|
||||
@@ -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:
|
||||
|
||||
16
Dockerfile
16
Dockerfile
@@ -1,21 +1,7 @@
|
||||
FROM oven/bun:1.1.36-slim
|
||||
# FROM oven/bun:1.0.25
|
||||
|
||||
FROM oven/bun:1.1.40-slim
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
|
||||
# Install dependencies
|
||||
COPY package.json .
|
||||
RUN bun i
|
||||
# COPY package.json bun.lockb ./
|
||||
# RUN bun install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Expose the application port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start the application
|
||||
CMD ["bun", "run", "start"]
|
||||
11
package.json
11
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@odit/lfk-mailer",
|
||||
"version": "1.0.0",
|
||||
"version": "1.2.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -11,11 +11,10 @@
|
||||
"@hono/node-server": "1.13.7",
|
||||
"@hono/swagger-ui": "0.5.0",
|
||||
"@hono/zod-openapi": "0.18.3",
|
||||
"@hono/zod-validator": "0.4.1",
|
||||
"bullmq": "5.34.0",
|
||||
"bwip-js": "4.5.1",
|
||||
"@hono/zod-validator": "0.4.2",
|
||||
"bullmq": "5.34.3",
|
||||
"handlebars": "4.7.8",
|
||||
"hono": "4.6.13",
|
||||
"hono": "4.6.14",
|
||||
"ioredis": "5.4.1",
|
||||
"nodemailer": "6.9.16",
|
||||
"zod": "3.24.1"
|
||||
@@ -23,6 +22,6 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "22.10.2",
|
||||
"@types/nodemailer": "6.4.17",
|
||||
"bun-types": "1.1.38"
|
||||
"bun-types": "1.1.40"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ import { z } from 'zod'
|
||||
import { EmailService } from '../services/email'
|
||||
import { getEmailTemplate } from '../templates'
|
||||
import { Language } from '../types'
|
||||
import { toBuffer } from 'bwip-js/node'
|
||||
import { Attachment } from 'nodemailer/lib/mailer'
|
||||
|
||||
const emailRouter = new Hono()
|
||||
const emailService = new EmailService()
|
||||
@@ -18,24 +18,12 @@ const sendEmailSchema = z.object({
|
||||
})
|
||||
|
||||
async function generateBarcodeDataURL(data) {
|
||||
const buffer = await toBuffer({
|
||||
bcid: 'code128',
|
||||
text: data,
|
||||
scale: 3,
|
||||
height: 10,
|
||||
includetext: true,
|
||||
textxalign: 'center',
|
||||
});
|
||||
|
||||
const base64Data = buffer.toString('base64');
|
||||
const dataURL = `data:image/png;base64,${base64Data}`;
|
||||
|
||||
return dataURL;
|
||||
return `${process.env.DOCUMENT_SERVER_URL}/v1/barcodes/code128/${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") {
|
||||
@@ -45,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\nBEGIN:VEVENT\nSUMMARY:Lauf für Kaya! 2025\nDTSTART:20250523T110000Z\nDTEND:20250523T160000Z\nDTSTAMP:20250318T230306Z\nUID:1742338986492-lfk2025\nDESCRIPTION:Der Lauf für Kaya! 2025 findet am 23.05.2025 auf dem Sportplatz des Gymnasium Herzogenaurach statt - Bürgerlauf von 13 bis 18 Uhr.\nLOCATION:Sportplatz Gymnasium Herzogenaurach\nORGANIZER:info@lauf-fuer-kaya.de\nSTATUS:CONFIRMED\nPRIORITY:5\nEND:VEVENT\nEND:VCALENDAR`,
|
||||
contentType: 'text/calendar; method=REQUEST',
|
||||
}
|
||||
attachments.push(attachment)
|
||||
}
|
||||
if (templateName === "password-reset") {
|
||||
if (data.token) {
|
||||
@@ -58,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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,6 +3,8 @@ Hallo {{name}} 👋
|
||||
vielen Dank für deine Registrierung beim {{event_name}}
|
||||
|
||||
Am Lauftag ({{event_date}}) musst du nur noch deinen Barcode vorzeigen, damit erhältst du deine Läuferkarte.
|
||||
Der Bürger- & Firmenlauf findet von 13:00 bis 18:00 Uhr statt.
|
||||
|
||||
Deinen Registrierungs-Code, Rundenzeiten und weitere Infos kannst du jederzeit im Lauf für Kaya! Selfservice unter {{link}} einsehen.
|
||||
|
||||
Wir freuen uns schon auf dich und einen erfolgreichen Lauf für Kaya!
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,6 +3,8 @@ Hello {{name}} 👋
|
||||
Thank you for registering for the {{event_name}}
|
||||
|
||||
On the day of the run ({{event_date}}) you only have to show your barcode to receive your runner's card.
|
||||
The Citizens' & Company Run will take place from 1:00 p.m. to 6:00 p.m.
|
||||
|
||||
You can view your registration code, lap times and further information at any time from the Lauf für Kaya! Selfservice at {{link}}.
|
||||
|
||||
We look forward to seeing you and to a successful Lauf für Kaya!
|
||||
|
||||
Reference in New Issue
Block a user