| | const path = require('path'); |
| | const axios = require('axios'); |
| | const FormData = require('form-data'); |
| | const nodemailer = require('nodemailer'); |
| | const handlebars = require('handlebars'); |
| | const { logger } = require('@librechat/data-schemas'); |
| | const { logAxiosError, isEnabled, readFileAsString } = require('@librechat/api'); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const sendEmailViaMailgun = async ({ to, from, subject, html }) => { |
| | const mailgunApiKey = process.env.MAILGUN_API_KEY; |
| | const mailgunDomain = process.env.MAILGUN_DOMAIN; |
| | const mailgunHost = process.env.MAILGUN_HOST || 'https://api.mailgun.net'; |
| |
|
| | if (!mailgunApiKey || !mailgunDomain) { |
| | throw new Error('Mailgun API key and domain are required'); |
| | } |
| |
|
| | const formData = new FormData(); |
| | formData.append('from', from); |
| | formData.append('to', to); |
| | formData.append('subject', subject); |
| | formData.append('html', html); |
| | formData.append('o:tracking-clicks', 'no'); |
| |
|
| | try { |
| | const response = await axios.post(`${mailgunHost}/v3/${mailgunDomain}/messages`, formData, { |
| | headers: { |
| | ...formData.getHeaders(), |
| | Authorization: `Basic ${Buffer.from(`api:${mailgunApiKey}`).toString('base64')}`, |
| | }, |
| | }); |
| |
|
| | return response.data; |
| | } catch (error) { |
| | throw new Error(logAxiosError({ error, message: 'Failed to send email via Mailgun' })); |
| | } |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const sendEmailViaSMTP = async ({ transporterOptions, mailOptions }) => { |
| | const transporter = nodemailer.createTransport(transporterOptions); |
| | return await transporter.sendMail(mailOptions); |
| | }; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const sendEmail = async ({ email, subject, payload, template, throwError = true }) => { |
| | try { |
| | const { content: source } = await readFileAsString(path.join(__dirname, 'emails', template)); |
| | const compiledTemplate = handlebars.compile(source); |
| | const html = compiledTemplate(payload); |
| |
|
| | |
| | const fromName = process.env.EMAIL_FROM_NAME || process.env.APP_TITLE; |
| | const fromEmail = process.env.EMAIL_FROM; |
| | const fromAddress = `"${fromName}" <${fromEmail}>`; |
| | const toAddress = `"${payload.name}" <${email}>`; |
| |
|
| | |
| | if (process.env.MAILGUN_API_KEY && process.env.MAILGUN_DOMAIN) { |
| | logger.debug('[sendEmail] Using Mailgun provider'); |
| | return await sendEmailViaMailgun({ |
| | from: fromAddress, |
| | to: toAddress, |
| | subject: subject, |
| | html: html, |
| | }); |
| | } |
| |
|
| | |
| | logger.debug('[sendEmail] Using SMTP provider'); |
| | const transporterOptions = { |
| | |
| | secure: process.env.EMAIL_ENCRYPTION === 'tls', |
| | |
| | requireTls: process.env.EMAIL_ENCRYPTION === 'starttls', |
| | tls: { |
| | |
| | rejectUnauthorized: !isEnabled(process.env.EMAIL_ALLOW_SELFSIGNED), |
| | }, |
| | auth: { |
| | user: process.env.EMAIL_USERNAME, |
| | pass: process.env.EMAIL_PASSWORD, |
| | }, |
| | }; |
| |
|
| | if (process.env.EMAIL_ENCRYPTION_HOSTNAME) { |
| | |
| | transporterOptions.tls.servername = process.env.EMAIL_ENCRYPTION_HOSTNAME; |
| | } |
| |
|
| | |
| | if (process.env.EMAIL_SERVICE) { |
| | transporterOptions.service = process.env.EMAIL_SERVICE; |
| | } else { |
| | transporterOptions.host = process.env.EMAIL_HOST; |
| | transporterOptions.port = process.env.EMAIL_PORT ?? 25; |
| | } |
| |
|
| | const mailOptions = { |
| | |
| | from: fromAddress, |
| | to: toAddress, |
| | envelope: { |
| | |
| | |
| | from: fromEmail, |
| | to: email, |
| | }, |
| | subject: subject, |
| | html: html, |
| | }; |
| |
|
| | return await sendEmailViaSMTP({ transporterOptions, mailOptions }); |
| | } catch (error) { |
| | if (throwError) { |
| | throw error; |
| | } |
| | logger.error('[sendEmail]', error); |
| | return error; |
| | } |
| | }; |
| |
|
| | module.exports = sendEmail; |
| |
|