Kevin
Kevin

Reputation: 465

Perl parse email and attachments from Outlook inbox

I'm using Mail::IMAPClient to connect to our Outlook mail server. I can get the mail just fine and print the text version of that mail to a file. But I'm having trouble using MIME::Parser to parse through the email.

I've tried giving the parser a file handle to the text file that I wrote the email to. I've tried giving the parser just the text of the email but it won't work how I'm expecting it to work. The entity parts always equals 0.

When I dump the entity skeleton I get

  Content-type: text/plain
  Effective-type: text/plain
  Body-file: NONE
  --

I can see all of the parts of the email in the file. The two PDFs that are attached are there, encoded in base64, so I know that the script is actually retrieving the email and the attachments. I've also tried parse and parse_data.

my $msgCount = 0;    
$msgCount = $imap->message_count();    
#or abortMission("", "Could not get message count: ". $imap->LastError );

if ( $msgCount > 0 ) {     

    #get all the messages from the inbox folder    
    my @msgseqnos = $imap->messages
            or abortMission("", "Could not retreive messages:". $imap->LastError);

    my ($x, $bh, $attachment, $attachmentName);

    foreach my $seqno ( @msgseqnos ) {

        my $input_file;
        my $parser = new MIME::Parser;
        my $emailText = $imap->body_string($seqno)   # should be the entire email as text. 
                or abortMission("", "Could not get message string: " . $imap->LastError);

        $parser->ignore_errors(1);
        $parser->output_to_core(1);

        open my $emailFileHandle, ">", "invoiceText.txt";
        print $emailFileHandle $emailText;
        #$imap->message_to_file($emailFileHandle, $seqno);

        my $entity = $parser->parse_data($emailText);
        $entity->dump_skeleton;

        if ( $entity->parts > 0 ) {

            for ( my $i = 0; $i < $entity->parts; $i++ ) {

                my $subentity = $entity->parts($i);

                # grab attachment name and contents
                foreach $x ( @attypes ) {

                    if ( $subentity->mime_type =~ m/$x/i ) {

                        $bh = $subentity->bodyhandle;
                        $attachment = $bh->as_string;
                        $attachmentName = $subentity->head->mime_attr('content-disposition.filename');

                        open FH, ">$attachmentName";
                        print FH $attachment;
                        close FH;

                        #push @attachment, $attachment;
                        #push @attname, $subentity->head->mime_attr('content-disposition.filename');
                    }
                }
            }
        }
        else {
            stillAGo("eData VehicleInvoices problem", "Perl can't find an attachment in an email in the VehicleInvoices folder of eData email address");
        }

        close $emailFileHandle;

        # say $emailText;
        # next;

        #open OUT_FILE, ">invoiceText.txt";
        #print OUT_FILE $emailText;
        #print OUT_FILE $imap->bodypart_string($seqno,1);
        #close OUT_FILE;

        #print $emailText;
    }
}

I'm trying to retrieve the attachments from emails automatically and save them to disk to be processed by another job.

I'd like to include the invoiceText.txt file so people can see the actual output but it's 1200 lines long. I'm not sure where to upload a file to link in here.

Upvotes: 0

Views: 2094

Answers (1)

Borodin
Borodin

Reputation: 126722

The body_string method doesn't return the entire email. As the documentation describes, and the name implies, it returns the body of the message, excluding the headers. That is why dump_skeleton shows no headers apart from the defaults

What you probably want, although I haven't tried it, is message_string, which does return the entire email

I see you've used message_to_file but commented it out. That would probably have worked if you got MIME::Parse to read from the file

Upvotes: 1

Related Questions