go-mail icon indicating copy to clipboard operation
go-mail copied to clipboard

Add eml parser to generate Msg from .eml files

Open wneessen opened this issue 2 years ago • 4 comments

Is your feature request related to a problem? Please describe.

As requested on discord, it would be nice to generate a new Msg from a given .eml file.

Describe the solution you'd like

Ideally the parser would read all headers supported by go-mail and add them to the Msg automatically and then fill the body with the mail contents of the .eml. Parsing attachments could be tricky though.

Describe alternatives you've considered

No response

Additional context

No response

wneessen avatar Sep 13 '23 08:09 wneessen

Hi @wneessen, thanks for all your hard work on this library! Any update on this issue, or recommended work-arounds?

I have a scenario where the network may be unavailable at the time of sending, so I initially used your msg.WriteToFile(filepath) to write EMLs to disk in a retry folder, then I have another service that checks for any files there and calls the following, passing in from the caller a new msg object like so msg := mail.NewMsg():

func readMailFromDisk(msg *mail.Msg, filepath string) (err error) {
	conLib.Log.Debugf("Entered readMailFromDisk")
	defer conLib.Log.Debugf("Exited readMailFromDisk")

	// read the mail message from disk into a bytes buffer
	messageBytes, err := os.ReadFile(filepath)
	if err != nil {
		err = fmt.Errorf("failed to read file %s: %v", filepath, err)
		return
	}

	// load the bytes buffer into the mail message object by reference
	length, err := msg.NewReader().Read(messageBytes)
	if err != nil {
		err = fmt.Errorf("failed to read message: %v", err)
		return
	}

	if length == 0 {
		err = fmt.Errorf("message is empty")
		return
	}

	return
}

Today I learned this issue is open :) Thanks in advance for your help and time.

jameshueston avatar Apr 24 '24 21:04 jameshueston

Hi @jameshueston,

unfortunately I haven't had much time to work on this lately. The branch https://github.com/wneessen/go-mail/tree/feature/145_add-eml-parser-to-generate-msg-from-eml-files has what I would call a poorly tested, yet working PoC for simple mails. The big issue currently are mutlipart mails, which are not that easy to "decode". If the mails you are sending are simple mails with maybe just a single attachment, the code might be working for you already, if they are multi-part, it will most likely do nothing yet.

I'll check if I can dedicate some time for this in the next few weeks, to get this finished.

Sorry I don't have a more satisfying response right now.

wneessen avatar Apr 25 '24 07:04 wneessen

Hi @wneessen, thanks for your fast reply! I understand not having time lately. Much respect for the good you've already done :) I dug deep into your code changes today to understand them, then tested your branch in my use case successfully parsing headers and body with 0 attachments. Monday, I plan to test with 1 and 2 attachments - very small XLSX and JSON files. My Content Type is "text/plain".

If your code doesn't work, I thought about trying k3a/parsemail to read message parts into your mail.Msg. Off the cuff, do you think that could work?

No pressure over the weekend. If all else fails, I could save raw data to disk and rebuild mail for retries, which in my case happens often with mobile devices on intermittent cellular service.

Thank you again, kindly.

jameshueston avatar Apr 26 '24 23:04 jameshueston

That sounds good. Crossing fingers that the branch works. Otherwise I'm positive that k3a/parsemail would work as well. From what I can see it extracts all the important parts that would be needed to create a fresh mail.Msg.

wneessen avatar Apr 27 '24 09:04 wneessen

It took a lot of time (due to other priorities and time constraints on my end), but https://github.com/wneessen/go-mail/tree/feature/145_add-eml-parser-to-generate-msg-from-eml-files is now at a state that is usable. It's not complete, but most functionality is given (from what I can see and from what I was able to test).

Currently missing:

  • Lots of unit test cases/test coverage
  • Combined multipart/related mails (meaning inline/embeded attachment and normal attachments) are currently not supported yet
  • Some edge cases that I haven't come up with yet, might cause issues

Please feel free to give the branch a try and provide some feedback.

wneessen avatar Jun 19 '24 12:06 wneessen

Update:

  • multipart/related should now be working as expected
  • More test coverage (almost 90%)
  • Minor API changes have been made

Again, the branch should be ready to test and feedback is appreciated.

wneessen avatar Jun 24 '24 13:06 wneessen