Email Worker not actually forwarding

So I’ve got a worker with the following code:

export default {
  async email(message, env, ctx) {
    const regex = /.*\.(j|m|jm)@example\.com$/i;
    console.log(message.to);
    const matches = message.to.match(regex);

    const addresses = {
      m:["[email protected]"]
    }
    if (matches[1]&&addresses[matches[1]]) {
      console.log(addresses[matches[1]]);
      await ((addresses[matches[1]]).map(async address => {
        console.log("sending to: ", address);
        await message.forward(address);
        console.log("Sent");
      }))
    }
  }
}

And looking at the log, I have the following matching log:

{
  "outcome": "ok",
  "scriptName": "gentle-cake-e7a0",
  "exceptions": [],
  "logs": [
    {
      "message": [
        "[email protected]"
      ],
      "level": "log",
      "timestamp": 1675133951546
    },
    {
      "message": [
        [
          "[email protected]"
        ]
      ],
      "level": "log",
      "timestamp": 1675133951546
    },
    {
      "message": [
        "sending to: ",
        "[email protected]"
      ],
      "level": "log",
      "timestamp": 1675133951546
    }
  ],
  "eventTimestamp": 1675133951396,
  "event": {
    "rawSize": 8005,
    "rcptTo": "[email protected]",
    "mailFrom": "[email protected]"
  },
  "id": 1
}

But it doesn’t actually log that it returns from message.forward, and when I look at the dashboard, it says the email was ‘Dropped’. The email address it’s forwarded to is listed on my account as a verified destination address.

The intent is that I can wildcard anything in front of the [email protected] address, and it shows up in my mailbox without having to explicitly set it up as an address is the routing interface. Instead I just set the worker to the catch-all route. Also, for some partial routes, I want to be able to have both me and someone else receive the email, so I can have an array of addresses to send to (hence the map).

.map doesn’t return a single promise to await on, it returns an array of promises, and since it’s not a promise, await instantly returns the array as-is and moves on. You can confirm this by adding a console.log(“done”) after the map, and you’ll see it exits right away. What is happening is your worker is exiting early before the forward finishes.

You could do all of the forwards concurrently with a small change, using Promise.all to await all of the promises

await Promise.all((addresses[matches[1]]).map(async address => {
        console.log("sending to: ", address);
        await message.forward(address);
        console.log("Sent");
      }));

Or you could use a bit more modern syntax, and do them one at a time

for (let address of addresses[matches[1]]) {
        console.log("sending to: ", address);
        await message.forward(address);
        console.log("Sent");
      }

Shouldn’t really matter. The workers runtime limits you to six requests at the same time, and any more just get queued and wait.

Email handled by workers currently show as Dropped, and that doesn’t mean they didn’t work.
Email Workers erroring shows differently, example:

1 Like

Ok, so it was strictly a “my not understanding JS well enough” issue. Thank you.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.