mirror of
https://github.com/colanode/colanode.git
synced 2025-12-29 00:25:03 +01:00
Merge pull request #3 from neuronapp/send-emails-task
Add email sending functionality
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/multer": "^1.4.12",
|
||||
"@types/node": "^22.7.7",
|
||||
"@types/nodemailer": "^6.4.16",
|
||||
"@types/pg": "^8.11.10",
|
||||
"@types/ws": "^8.5.12",
|
||||
"nodemon": "^3.1.7",
|
||||
@@ -44,6 +45,7 @@
|
||||
"kafkajs": "^2.2.4",
|
||||
"kysely": "^0.27.4",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"nodemailer": "^6.9.16",
|
||||
"pg": "^8.13.0",
|
||||
"postgres": "^3.4.4",
|
||||
"redis": "^4.7.0",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { initRedis } from '@/data/redis';
|
||||
import { migrate } from '@/data/database';
|
||||
import { initEventWorker } from '@/queues/events';
|
||||
import { initTaskWorker } from '@/queues/tasks';
|
||||
import { initEmail } from '@/services/email';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
@@ -10,10 +11,11 @@ dotenv.config();
|
||||
const init = async () => {
|
||||
await migrate();
|
||||
await initRedis();
|
||||
await initEmail();
|
||||
await initApi();
|
||||
|
||||
initEventWorker();
|
||||
initTaskWorker();
|
||||
};
|
||||
|
||||
init();
|
||||
init();
|
||||
@@ -1,7 +1,8 @@
|
||||
import { database } from '@/data/database';
|
||||
import { redisConfig } from '@/data/redis';
|
||||
import { CleanDeviceDataTask, Task } from '@/types/tasks';
|
||||
import { CleanDeviceDataTask, SendEmailTask, Task } from '@/types/tasks';
|
||||
import { Job, Queue, Worker } from 'bullmq';
|
||||
import { sendEmail } from '@/services/email';
|
||||
|
||||
const taskQueue = new Queue('tasks', {
|
||||
connection: {
|
||||
@@ -36,6 +37,8 @@ const handleTaskJob = async (job: Job) => {
|
||||
switch (task.type) {
|
||||
case 'clean_device_data':
|
||||
return handleCleanDeviceDataTask(task);
|
||||
case 'send_email':
|
||||
return handleSendEmailTask(task);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,3 +61,9 @@ const handleCleanDeviceDataTask = async (
|
||||
.where('device_id', '=', task.deviceId)
|
||||
.execute();
|
||||
};
|
||||
|
||||
const handleSendEmailTask = async (
|
||||
task: SendEmailTask
|
||||
): Promise<void> => {
|
||||
await sendEmail(task.message);
|
||||
}
|
||||
43
apps/server/src/services/email.ts
Normal file
43
apps/server/src/services/email.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import nodemailer from 'nodemailer';
|
||||
import { EmailConfig, EmailMessage } from '@/types/email';
|
||||
|
||||
const SMTP_HOST = process.env.SMTP_HOST;
|
||||
const SMTP_PORT = process.env.SMTP_PORT;
|
||||
const SMTP_USER = process.env.SMTP_USER;
|
||||
const SMTP_PASS = process.env.SMTP_PASS;
|
||||
const EMAIL_FROM = process.env.EMAIL_FROM;
|
||||
|
||||
if (!SMTP_HOST || !SMTP_PORT || !SMTP_USER || !SMTP_PASS || !EMAIL_FROM) {
|
||||
throw new Error('SMTP configuration is missing');
|
||||
}
|
||||
|
||||
let transporter: nodemailer.Transporter;
|
||||
|
||||
const emailConfig: EmailConfig = {
|
||||
from: EMAIL_FROM,
|
||||
smtp: {
|
||||
host: SMTP_HOST,
|
||||
port: parseInt(SMTP_PORT),
|
||||
secure: true,
|
||||
auth: {
|
||||
user: SMTP_USER,
|
||||
pass: SMTP_PASS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const initEmail = async () => {
|
||||
transporter = nodemailer.createTransport(emailConfig.smtp);
|
||||
await transporter.verify();
|
||||
};
|
||||
|
||||
export const sendEmail = async (message: EmailMessage): Promise<void> => {
|
||||
if (!transporter) {
|
||||
throw new Error('Email service not initialized');
|
||||
}
|
||||
|
||||
await transporter.sendMail({
|
||||
from: emailConfig.from,
|
||||
...message,
|
||||
});
|
||||
};
|
||||
19
apps/server/src/types/email.ts
Normal file
19
apps/server/src/types/email.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export interface EmailConfig {
|
||||
from: string;
|
||||
smtp?: {
|
||||
host: string;
|
||||
port: number;
|
||||
secure: boolean;
|
||||
auth: {
|
||||
user: string;
|
||||
pass: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface EmailMessage {
|
||||
to: string | string[];
|
||||
subject: string;
|
||||
text?: string;
|
||||
html?: string;
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
export type Task = CleanDeviceDataTask;
|
||||
import { EmailMessage } from '@/types/email';
|
||||
|
||||
export type Task = CleanDeviceDataTask | SendEmailTask;
|
||||
|
||||
export type CleanDeviceDataTask = {
|
||||
type: 'clean_device_data';
|
||||
deviceId: string;
|
||||
};
|
||||
|
||||
export type SendEmailTask = {
|
||||
type: 'send_email';
|
||||
message: EmailMessage;
|
||||
};
|
||||
Reference in New Issue
Block a user