initialize git, basic setup for crm
This commit is contained in:
255
src/services/email.service.js
Normal file
255
src/services/email.service.js
Normal file
@@ -0,0 +1,255 @@
|
||||
import axios from 'axios';
|
||||
import { logger } from '../utils/logger.js';
|
||||
|
||||
const JMAP_CONFIG = {
|
||||
server: process.env.JMAP_SERVER || 'https://mail.truemail.sk/jmap/',
|
||||
username: process.env.JMAP_USERNAME || 'info1_test@truemail.sk',
|
||||
password: process.env.JMAP_PASSWORD || 'info1',
|
||||
accountId: process.env.JMAP_ACCOUNT_ID || 'ba',
|
||||
};
|
||||
|
||||
/**
|
||||
* Získa JMAP session
|
||||
*/
|
||||
const getJmapSession = async () => {
|
||||
try {
|
||||
const response = await axios.get(`${JMAP_CONFIG.server}session`, {
|
||||
auth: {
|
||||
username: JMAP_CONFIG.username,
|
||||
password: JMAP_CONFIG.password,
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
logger.error('Failed to get JMAP session', error);
|
||||
throw new Error('Email service nedostupný');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Validuje JMAP credentials a vráti account ID
|
||||
* @param {string} email - Email address
|
||||
* @param {string} password - Email password
|
||||
* @returns {Promise<{accountId: string, session: object}>}
|
||||
*/
|
||||
export const validateJmapCredentials = async (email, password) => {
|
||||
try {
|
||||
const response = await axios.get(`${JMAP_CONFIG.server}session`, {
|
||||
auth: {
|
||||
username: email,
|
||||
password: password,
|
||||
},
|
||||
});
|
||||
|
||||
const session = response.data;
|
||||
|
||||
// Získaj account ID z session
|
||||
const accountId = session.primaryAccounts?.['urn:ietf:params:jmap:mail'] ||
|
||||
session.primaryAccounts?.['urn:ietf:params:jmap:core'] ||
|
||||
Object.keys(session.accounts || {})[0];
|
||||
|
||||
if (!accountId) {
|
||||
throw new Error('Nepodarilo sa získať JMAP account ID');
|
||||
}
|
||||
|
||||
logger.success(`JMAP credentials validated for ${email}, accountId: ${accountId}`);
|
||||
|
||||
return {
|
||||
accountId,
|
||||
session,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`Failed to validate JMAP credentials for ${email}`, error);
|
||||
|
||||
if (error.response?.status === 401) {
|
||||
throw new Error('Nesprávne prihlasovacie údaje k emailu');
|
||||
}
|
||||
|
||||
throw new Error('Nepodarilo sa overiť emailový účet');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pošle email pomocou JMAP
|
||||
*/
|
||||
const sendJmapEmail = async ({ to, subject, htmlBody, textBody }) => {
|
||||
try {
|
||||
const session = await getJmapSession();
|
||||
const apiUrl = session.apiUrl;
|
||||
|
||||
const emailObject = {
|
||||
from: [{ email: JMAP_CONFIG.username }],
|
||||
to: [{ email: to }],
|
||||
subject,
|
||||
htmlBody: [
|
||||
{
|
||||
partId: '1',
|
||||
type: 'text/html',
|
||||
value: htmlBody,
|
||||
},
|
||||
],
|
||||
textBody: [
|
||||
{
|
||||
partId: '2',
|
||||
type: 'text/plain',
|
||||
value: textBody || subject,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const response = await axios.post(
|
||||
apiUrl,
|
||||
{
|
||||
using: ['urn:ietf:params:jmap:core', 'urn:ietf:params:jmap:mail'],
|
||||
methodCalls: [
|
||||
[
|
||||
'Email/set',
|
||||
{
|
||||
accountId: JMAP_CONFIG.accountId,
|
||||
create: {
|
||||
draft: emailObject,
|
||||
},
|
||||
},
|
||||
'0',
|
||||
],
|
||||
[
|
||||
'EmailSubmission/set',
|
||||
{
|
||||
accountId: JMAP_CONFIG.accountId,
|
||||
create: {
|
||||
submission: {
|
||||
emailId: '#draft',
|
||||
envelope: {
|
||||
mailFrom: { email: JMAP_CONFIG.username },
|
||||
rcptTo: [{ email: to }],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'1',
|
||||
],
|
||||
],
|
||||
},
|
||||
{
|
||||
auth: {
|
||||
username: JMAP_CONFIG.username,
|
||||
password: JMAP_CONFIG.password,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
logger.success(`Email sent to ${to}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to send email to ${to}`, error);
|
||||
throw new Error('Nepodarilo sa odoslať email');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Email templates
|
||||
*/
|
||||
|
||||
export const sendVerificationEmail = async (to, username, verificationToken) => {
|
||||
const verificationUrl = `${process.env.BETTER_AUTH_URL}/api/auth/verify-email?token=${verificationToken}`;
|
||||
|
||||
const htmlBody = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; }
|
||||
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 12px 24px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.footer { margin-top: 30px; font-size: 12px; color: #666; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Vitajte v CRM systéme, ${username}!</h2>
|
||||
<p>Prosím, verifikujte svoju emailovú adresu kliknutím na tlačidlo nižšie:</p>
|
||||
<a href="${verificationUrl}" class="button">Verifikovať email</a>
|
||||
<p>Alebo skopírujte tento link do prehliadača:</p>
|
||||
<p>${verificationUrl}</p>
|
||||
<p class="footer">
|
||||
Tento link vyprší za 24 hodín.<br>
|
||||
Ak ste tento email neočakávali, môžete ho ignorovať.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const textBody = `
|
||||
Vitajte v CRM systéme, ${username}!
|
||||
|
||||
Prosím, verifikujte svoju emailovú adresu kliknutím na tento link:
|
||||
${verificationUrl}
|
||||
|
||||
Tento link vyprší za 24 hodín.
|
||||
Ak ste tento email neočakávali, môžete ho ignorovať.
|
||||
`;
|
||||
|
||||
return sendJmapEmail({
|
||||
to,
|
||||
subject: 'Verifikácia emailu - CRM systém',
|
||||
htmlBody,
|
||||
textBody,
|
||||
});
|
||||
};
|
||||
|
||||
export const sendWelcomeEmail = async (to, username) => {
|
||||
const htmlBody = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; }
|
||||
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h2>Vitajte v CRM systéme, ${username}!</h2>
|
||||
<p>Váš účet bol úspešne vytvorený a nastavený.</p>
|
||||
<p>Môžete sa prihlásiť a začať používať systém.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const textBody = `
|
||||
Vitajte v CRM systéme, ${username}!
|
||||
|
||||
Váš účet bol úspešne vytvorený a nastavený.
|
||||
Môžete sa prihlásiť a začať používať systém.
|
||||
`;
|
||||
|
||||
return sendJmapEmail({
|
||||
to,
|
||||
subject: 'Vitajte v CRM systéme',
|
||||
htmlBody,
|
||||
textBody,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchrónne posielanie emailov (non-blocking)
|
||||
*/
|
||||
export const sendEmailAsync = (emailFunction, ...args) => {
|
||||
// Spustí email sending v pozadí
|
||||
emailFunction(...args).catch((error) => {
|
||||
logger.error('Async email sending failed', error);
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user