#Getting the body from a email-worker.

17 messages · Page 1 of 1 (latest)

charred tangle
#

Hello there! I am in the process of transitioning to Cloudflare. Upon discovering that Cloudflare Workers support the ability to send emails to channels like Slack, I'm eager to implement this feature. I aim to send the body of the email to an external API. Is there a method to achieve this, and is there any pertinent information within the 'message' variable that I might have overlooked?

Thanks in advance!

strange pasture
charred tangle
strange pasture
charred tangle
# strange pasture ah, misread. you would need to read the stream in the raw property of the messag...

Yea, only problem is I dont know how stream's work... I have read the docs but couldn't figure it out ;(

export default {
  async email(message, env, ctx) {
    switch (message.to) {
      case "EMAIL_CASE":
        await fetch("API_ENDPOINT", {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            "icon": "📨",
            "title": message.headers.get('subject'),
            "body": readable.getReader({ mode: 'byob' }),
            "source": message.from,
          }),
        });
        break;
      default:
        message.reject("Unknown address");
    }
  }
}
grand gulch
#

can't stringify a stream

#

would have to base64 it or escape it

#

what I've done in the past is just passed along the metadata as headers

strange pasture
grand gulch
#

It's an email, if his goal is to send it to slack or something he's really going to want to decode it first or it'd be a lot of useless junk

strange pasture
#

couldn't you do this?

const textDecoder = new TextDecoder();
let result = "";
for await (let chunk of message.raw) {
    result += textDecoder.decode(chunk, { stream: true });
}
grand gulch
grand gulch
# strange pasture couldn't you do this? ```js const textDecoder = new TextDecoder(); let result = ...

a raw email looks something like this:

MIME-Version: 1.0
References: <CABxEEohuqZBoVpsyY4pOFMYixhU2bzfxgs9tRLbUoV2NJMqCJw@mail.gmail.com> 
<CAL5Lp9Xyo0mEQ6-c1yAQ+SuKXrT4Xu5y-7BnvnGS4RMjZOBJ=g@mail.gmail.com>
In-Reply-To: <CAL5Lp9Xyo0mEQ6-c1yAQ+SuKXrT4Xu5y-7BnvnGS4RMjZOBJ=g@mail.gmail.com>
From: Chris <[email protected]>
Date: Wed, 9 Jan 2019 08:36:15 -0800
Message-ID: <CABxEEoizOPyCLkq4+FBGNaw7KC2TJDfTZF5dp8xD9aFjDQoL+Q@mail.gmail.com>
Subject: Re: food for thought
To: Paul <[email protected]>
Content-Type: multipart/related; boundary="000000000000382db9057f0910d6"

--000000000000382db9057f0910d6
Content-Type: multipart/alternative; boundary="000000000000382db0057f0910d5"

--000000000000382db0057f0910d5
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Ok.  Just a thought.  Got it.

--000000000000382db0057f0910d5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div><div dir=3D"auto">Ok.=C2=A0 Just a thought.=C2=A0 Got it. =C2=A0</div>=
</div><div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Jan 9, 2=

and that's a simple case. You'd want to run it through an email parser first to get the text/plain body, or the cleaned up text/html body if there is no text/plain

grand gulch
#

no problem! Yea you should be able to modify that repo to your needs, or you could just steal the parsing logic. It uses postal-mime and html-to-text, and the core of getting a useful contents to display is just:

   let rawEmail = new Response(message.raw);
    let arrayBuffer = await rawEmail.arrayBuffer();
    const parser = new PostalMime.default();
    const email = await parser.parse(arrayBuffer);
    let emailText = email.text;
    if (!emailText) {
      // If there is no text, try to get the text from the html
      emailText = convert(email.html);
    }
charred tangle
wet ruin
#

The postal-mime module API has changed, and it now includes built-in support for Cloudflare Email Workers. You can read about using it to parse emails from here: https://docs.emailengine.app/how-to-parse-emails-with-cloudflare-email-workers/

import PostalMime from 'postal-mime';
export default {
  async email(message, env, ctx) {
    const parser = new PostalMime();
    const email = await parser.parse(message.raw);
    // ... do something with the parsed email
  }
};