Anthony Breen · Nov 19, 2020

How to read an attachment file that is part of an attached email


I'm processing POP3 emails using the standard EnsLib.EMail.InboundAdapter adapter and %Net.MailMessage. I'm basically processing documents that are attached to received emails. This works fine if the document is simply attached to the email itself. But some systems are sending documents that are attached to an attached email which has content-type = message/rfc822.

How do I get the attached file from the attached email?

I'm using the following code to iterate through the email parts.. I can get as far as processing a MailMessagePart which has content-type = message/rfc822 but how do I process it as it's not really a MailMessagePart?

If pInput.IsMultiPart {
        Set tPartsCount = pInput.Parts.Count()
        $$$LOGINFO("This message has multiple parts; " _ tPartsCount)
        For tInd = 1:1:tPartsCount {
          Set tStatus = ..ProcessPart(pInput.Parts.GetAt(tInd),pInput.Subject,pInput.From,.attachedFilename,.status,.errorText)


1 0 3 150
Log in or sign up to continue

It's okay. I worked it out.

Just needed to call a method from the POP3 mail server that's accessible using the Adapter.

Anthony are you able to share a copy of your code with me please?

As we know, an email can contain one or more attached email(s), which in turn can contain other attached mails ... so we have to work recursively until the end. The following program excerpt should show the concept:

ClassMethod GetMails(popAddr, popUser, popPass)
   set pop=##class(%Net.POP3).%New(), cnt=0
   if pop.Connect(popAddr, popUser, popPass) {
      if pop.GetMailBoxStatus(.cnt,.siz) {
         for id=1:1:cnt {
            if pop.Fetch(id,.msg,0) do ..getParts(pop,msg,id,0)

ClassMethod getParts(pop, msg, id, lev)
   for i=1:1:msg.Parts.Count() {
      set part=msg.Parts.GetAt(i)
      set typ=$zcvt(part.CntentType,"l")
      set dsp=part.Headers.GetAt("content-disposition")
      if typ["message/rfc822" {
         // this is another email, we step one level deeper
         if pop.GetAttachedEmail(msg.Parts.GetAt(i), .new) do ..getParts(pop, new, id, lev+1)
      } elseif dsp["attachment" {
         // attachments
         if typ["application/pdf" {
         } elseif typ["image" {
         } elseif ... {
      } elseif typ["text" {
      } elseif ... {