Email worker error (reconstructing FROM address)

HI all, Im currently seeing an issue that I just cannot get my head around... I have a catch-all address set up to send to Duck Email protection which gives a @duck address. When this comes back filtered of trackers the original email From address is sent back in a "Originaluser_at_domain.com_duckuser@duck.com" and id like a worker to convert this back to the original address before forwarding on to my main account. I have come up with the following code however I am getting fetch errors and the emails are either not coming through or coming through with the incorrectly formated senders email still. They do however show up correctly on the cloudflare overview page for the domain. any help would be much appreciated, im very new to coding and cloudflare in general! Code in following post as it was too long.
6 Replies
WD13
WD133w ago
export default {
// Handle HTTP requests
async fetch(request) {
// Respond to HTTP requests with a simple message
return new Response('This worker is configured to handle email events.', {
status: 200,
headers: { 'Content-Type': 'text/plain' }
});
},

// Handle email events
async email(message, env, ctx) {
try {
// Get the "From" address from the incoming email
let originalFrom = message.headers.get('from');
console.log(Original From: ${originalFrom});

// Extract the email address (assuming format: originaluser_at_domain.com_duckuser@duck.com)
let emailRegex = /"[^"]*" <([^<]+?)_at_([^>]+?)@[^>]+>/;
let match = originalFrom.match(emailRegex);

let modifiedFrom;

// If match is found, reconstruct the email address
if (match) {
let username = match[1].trim(); // e.g., originaluser
let domain = match[2].trim(); // e.g., domain.com

// Create the new "From" address, ensuring only username and domain are included
modifiedFrom = ${username}@${domain};
console.log(Modified From: ${modifiedFrom});
} else {
// No match found, use the original sender's address as fallback
modifiedFrom = originalFrom;
console.log(No match found. Using original sender address: ${modifiedFrom});
}

// Forward the email to forwardemail@domain.com
await message.forward("forwardemail@domain.com");

console.log('Email forwarded successfully');

} catch (err) {
console.error("Error processing email:", err);
console.error("Stack trace:", err.stack);
}
}
};
export default {
// Handle HTTP requests
async fetch(request) {
// Respond to HTTP requests with a simple message
return new Response('This worker is configured to handle email events.', {
status: 200,
headers: { 'Content-Type': 'text/plain' }
});
},

// Handle email events
async email(message, env, ctx) {
try {
// Get the "From" address from the incoming email
let originalFrom = message.headers.get('from');
console.log(Original From: ${originalFrom});

// Extract the email address (assuming format: originaluser_at_domain.com_duckuser@duck.com)
let emailRegex = /"[^"]*" <([^<]+?)_at_([^>]+?)@[^>]+>/;
let match = originalFrom.match(emailRegex);

let modifiedFrom;

// If match is found, reconstruct the email address
if (match) {
let username = match[1].trim(); // e.g., originaluser
let domain = match[2].trim(); // e.g., domain.com

// Create the new "From" address, ensuring only username and domain are included
modifiedFrom = ${username}@${domain};
console.log(Modified From: ${modifiedFrom});
} else {
// No match found, use the original sender's address as fallback
modifiedFrom = originalFrom;
console.log(No match found. Using original sender address: ${modifiedFrom});
}

// Forward the email to forwardemail@domain.com
await message.forward("forwardemail@domain.com");

console.log('Email forwarded successfully');

} catch (err) {
console.error("Error processing email:", err);
console.error("Stack trace:", err.stack);
}
}
};
How would I go about that? Something like this? export default { async email(message, env, ctx) { try { // Get the "From" address from the incoming email let originalFrom = message.headers.get('from'); console.log(Original From: ${originalFrom}); // Extract the email address let emailRegex = /"[^"]*" <([^<]+?)at([^>]+?)@[^>]+>/; let match = originalFrom.match(emailRegex); let modifiedFrom; // If match is found, reconstruct the email address if (match) { let username = match[1].trim(); // e.g., let domain = match[2].trim(); // e.g., .com // Create the new "From" address, ensuring only username and domain are included modifiedFrom = ${username}@${domain}; console.log(Modified From: ${modifiedFrom}); } else { // No match found, use the original sender's address as fallback modifiedFrom = originalFrom; console.log(No match found. Using original sender address: ${modifiedFrom}); } await env.EMAILS.send({ from: modifiedFrom, to: "**@gmail.com", // Send to the desired recipient subject: message.headers.get('subject') || "No Subject", text: await message.text(), // Use the body of the original email }); console.log('Email forwarded successfully with modified From address'); } catch (err) { console.error("Error processing email:", err); console.error("Stack trace:", err.stack); } } }; shows up as forwarded on the overview page but I do no recieve the email??
D Trombett
D Trombett3w ago
Afaik you can send emails from the worker only to a verified address (one that you've added in Cloudflare) Are you sure it is one of them?
WD13
WD133w ago
tried a different way... export default { async email(message, env, ctx) { try { // Get the "From" address from the incoming email let originalFrom = message.headers.get('from'); console.log(Original From: ${originalFrom}); // Extract the email address let emailRegex = /"[^"]*" <([^<]+?)at([^>]+?)@[^>]+>/; let match = originalFrom.match(emailRegex); let modifiedFrom; // If match is found, reconstruct the email address if (match) { let username = match[1].trim(); // let domain = match[2].trim(); // // Create the new "From" address, ensuring only username and domain are included modifiedFrom = ${username}@${domain}; console.log(Modified From: ${modifiedFrom}); } else { // No match found, use the original sender's address as fallback modifiedFrom = originalFrom; console.log(No match found. Using original sender address: ${modifiedFrom}); } // Create a new email with the modified "From" address and forward it let newMessage = new EmailMessage({ from: modifiedFrom, to: "verified@email.com", subject: message.headers.get('subject'), text: await message.text(), cc: message.headers.get('cc'), bcc: message.headers.get('bcc'), }); // Send the new email await newMessage.send(); console.log('Email forwarded successfully with modified From address'); } catch (err) { console.error("Error processing email:", err); console.error("Stack trace:", err.stack); } } }; yes the email has been updated to a verified one but I am still recieving nothing. This code doesn't even seem to forward or process the original message. Pretty confused now!
D Trombett
D Trombett3w ago
Do you mean that you're not getting any console log whatsoever?
WD13
WD133w ago
nope, doesnt look like it now! ignore that, it is working now. Errors look like this { "message": [ "Error processing email:", "ReferenceError: EmailMessage is not defined" ], "level": "error", "timestamp": 1725464885937 }, { "message": [ "Stack trace:", "ReferenceError: EmailMessage is not defined\n at Object.email (worker.js:29:24)" ], "level": "error", "timestamp": 1725464885937 }
D Trombett
D Trombett3w ago
Import it from cloudflare:email, I'd suggest you to follow this example https://developers.cloudflare.com/email-routing/email-workers/send-email-workers/#example-worker
Cloudflare Docs
Send emails from Workers | Cloudflare Email Routing docs
You can send an email about your Worker’s activity from your Worker to an email address verified on Email Routing. This is useful for when you want to know about certain types of events being triggered, for example.
Want results from more Discord servers?
Add your server