email send eject
This commit is contained in:
parent
0c8bcab437
commit
e37f230deb
@ -80,48 +80,159 @@
|
|||||||
import nodeMailer from "nodemailer";
|
import nodeMailer from "nodemailer";
|
||||||
import { createTransport } from "nodemailer";
|
import { createTransport } from "nodemailer";
|
||||||
|
|
||||||
// Keep the original environment variable names
|
// Test connection to SMTP server first
|
||||||
const transporter = createTransport({
|
const testSMTPConnection = async () => {
|
||||||
host: process.env.SMPT_HOST,
|
console.log("Testing SMTP connection before sending...");
|
||||||
port: parseInt(process.env.SMPT_PORT, 10), // Convert string to number
|
|
||||||
// service: process.env.SMPT_SERVICE,
|
try {
|
||||||
auth: {
|
// Create a temporary transporter for testing
|
||||||
user: process.env.SMPT_MAIL,
|
const testTransporter = createTransport({
|
||||||
pass: process.env.SMPT_PASSWORD,
|
host: process.env.SMPT_HOST,
|
||||||
},
|
port: parseInt(process.env.SMPT_PORT, 10),
|
||||||
// Add timeout to avoid hanging connections
|
auth: {
|
||||||
connectionTimeout: 10000, // 10 seconds
|
user: process.env.SMPT_MAIL,
|
||||||
// Log transport operations if not in production
|
pass: process.env.SMPT_PASSWORD,
|
||||||
debug: process.env.NODE_ENV !== "production",
|
},
|
||||||
});
|
// Reduce timeout for testing to fail faster
|
||||||
|
connectionTimeout: 5000,
|
||||||
|
// Don't actually send emails during verification
|
||||||
|
pool: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verify connection configuration
|
||||||
|
await testTransporter.verify();
|
||||||
|
console.log("SMTP connection test successful!");
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("SMTP connection test failed:");
|
||||||
|
console.error(
|
||||||
|
`Host: ${process.env.SMPT_HOST}, Port: ${process.env.SMPT_PORT}`
|
||||||
|
);
|
||||||
|
console.error(`Error: ${error.message}`);
|
||||||
|
|
||||||
|
if (error.message.includes("timeout")) {
|
||||||
|
console.error(
|
||||||
|
"CONNECTION TIMEOUT: This likely indicates a network or firewall issue."
|
||||||
|
);
|
||||||
|
console.error(
|
||||||
|
"Your hosting provider may be blocking outgoing SMTP connections."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try both direct SMTP and API-based fallback approach
|
||||||
|
const createFallbackTransporter = () => {
|
||||||
|
// If we're in production and previously had timeout issues, try to use Brevo API instead
|
||||||
|
if (process.env.USE_BREVO_API === "true") {
|
||||||
|
console.log("Using Brevo API instead of SMTP");
|
||||||
|
|
||||||
|
// This requires installing the Brevo API library: npm install @sendinblue/client
|
||||||
|
// And setting BREVO_API_KEY in your environment variables
|
||||||
|
const SibApiV3Sdk = require("@sendinblue/client");
|
||||||
|
|
||||||
|
let apiInstance = new SibApiV3Sdk.TransactionalEmailsApi();
|
||||||
|
apiInstance.setApiKey(
|
||||||
|
SibApiV3Sdk.AccountApiApiKeys.apiKey,
|
||||||
|
process.env.BREVO_API_KEY
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isAPI: true,
|
||||||
|
sendMail: async (options) => {
|
||||||
|
const sendSmtpEmail = new SibApiV3Sdk.SendSmtpEmail();
|
||||||
|
sendSmtpEmail.subject = options.subject;
|
||||||
|
sendSmtpEmail.htmlContent =
|
||||||
|
options.html || "<p>" + (options.text || "") + "</p>";
|
||||||
|
sendSmtpEmail.sender = { email: options.from || process.env.SMPT_MAIL };
|
||||||
|
sendSmtpEmail.to = [{ email: options.to }];
|
||||||
|
|
||||||
|
const data = await apiInstance.sendTransacEmail(sendSmtpEmail);
|
||||||
|
return { messageId: data.messageId };
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise use standard SMTP
|
||||||
|
console.log("Using standard SMTP transport");
|
||||||
|
return createTransport({
|
||||||
|
host: process.env.SMPT_HOST,
|
||||||
|
port: parseInt(process.env.SMPT_PORT, 10),
|
||||||
|
auth: {
|
||||||
|
user: process.env.SMPT_MAIL,
|
||||||
|
pass: process.env.SMPT_PASSWORD,
|
||||||
|
},
|
||||||
|
// Increase timeout for production
|
||||||
|
connectionTimeout: 30000, // 30 seconds
|
||||||
|
// Retry failed connections
|
||||||
|
pool: true,
|
||||||
|
maxConnections: 5,
|
||||||
|
maxMessages: 100,
|
||||||
|
rateDelta: 1000,
|
||||||
|
rateLimit: 5,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize transporter
|
||||||
|
let transporter = null;
|
||||||
|
let connectionTested = false;
|
||||||
|
|
||||||
const sendEmail = async (options) => {
|
const sendEmail = async (options) => {
|
||||||
try {
|
try {
|
||||||
// Log attempt to help with debugging
|
// Test connection first time only
|
||||||
|
if (!connectionTested) {
|
||||||
|
await testSMTPConnection();
|
||||||
|
connectionTested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize transporter if needed
|
||||||
|
if (!transporter) {
|
||||||
|
transporter = createFallbackTransporter();
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Attempting to send email to ${options.to}`);
|
console.log(`Attempting to send email to ${options.to}`);
|
||||||
|
|
||||||
// Use Promise-based API instead of callback for better error handling
|
// Send email (handles both SMTP and API methods)
|
||||||
const info = await transporter.sendMail(options);
|
if (transporter.isAPI) {
|
||||||
console.log("Email sent successfully:", info.messageId);
|
// API-based sending
|
||||||
return info;
|
const info = await transporter.sendMail(options);
|
||||||
|
console.log("Email sent successfully via API:", info.messageId);
|
||||||
|
return info;
|
||||||
|
} else {
|
||||||
|
// SMTP-based sending
|
||||||
|
const info = await transporter.sendMail(options);
|
||||||
|
console.log("Email sent successfully via SMTP:", info.messageId);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Enhanced error logging with more details
|
|
||||||
console.error("Failed to send email:");
|
console.error("Failed to send email:");
|
||||||
console.error("Error name:", error.name);
|
console.error("Error name:", error.name);
|
||||||
console.error("Error message:", error.message);
|
console.error("Error message:", error.message);
|
||||||
console.error("Error code:", error.code);
|
console.error("Error code:", error.code);
|
||||||
|
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
console.error("SMTP Response:", error.response);
|
console.error("SMTP Response:", error.response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-throw so the calling code knows the email failed
|
// If we get timeout errors in production, suggest using API method
|
||||||
|
if (
|
||||||
|
error.message.includes("timeout") &&
|
||||||
|
process.env.NODE_ENV === "production"
|
||||||
|
) {
|
||||||
|
console.error(
|
||||||
|
"RECOMMENDATION: Try setting USE_BREVO_API=true to use API instead of SMTP"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default sendEmail;
|
export default sendEmail;
|
||||||
|
|
||||||
// Leave the MessageBird implementation unchanged
|
// Leave MessageBird implementation unchanged
|
||||||
import { initClient } from "messagebird";
|
import { initClient } from "messagebird";
|
||||||
const messagebird = initClient("p2YaqxU9uYx2F3d3dV8ywAFtk");
|
const messagebird = initClient("p2YaqxU9uYx2F3d3dV8ywAFtk");
|
||||||
export const sendOtp = async (recipient, message) => {
|
export const sendOtp = async (recipient, message) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user