Search code examples
perlemailmultipart

Email with 2 multiparts shows as one


I'm trying to figure out why my multi-part email all comes out as one:

enter image description here

The code I'm using to create 2 "parts" for my email, is:

  use Email::MIME;
  use Email::Address::XS;
  use Email::Sender::Simple qw(sendmail);

  # multipart message
  my @parts = (
      Email::MIME->create(
          attributes => {
              content_type => "text/plain",
              disposition  => "inline",
              charset      => "UTF-8",
          },
          body_str => "Hello there é!",
          attributes => {
                encoding => 'quoted-printable',
                charset  => "UTF-8",
          }
      ),
      Email::MIME->create(
          attributes => {
              content_type => "text/html",
              disposition  => "inline",
              charset      => "UTF-8",
          },
          body_str => "Hello there éíó!",
          attributes => {
                encoding => 'quoted-printable',
                charset  => "UTF-8",
          }
      )
  );

  my $email = Email::MIME->create(
      header_str => [
          From => 'andy@mysite.org',
          To => [ 'Name <andy@foo.com>' ],
          Subject => "foo"
      ]
  );
  $email->parts_set( \@parts );

  print $email->as_string;

  sendmail($email->as_string);

The email is sent and comes out like so:

Delivered-To: andy@foo.com
Received: by 10.223.130.5 with SMTP id 5csp329339wrb;
        Thu, 11 Jan 2018 01:09:17 -0800 (PST)
X-Google-Smtp-Source: ACJfBotkcH6W0rsnQMkLx9pPqbt1rUgKaC9ShvWLQbn6u8muQbVnCjTCZRmf0d5RzegqW4AGpFHP
X-Received: by 10.28.92.146 with SMTP id q140mr474098wmb.5.1515661757887;
        Thu, 11 Jan 2018 01:09:17 -0800 (PST)
Return-Path: <andy@mysite.org>
From: andy@mysite.org
To: Name <andy@foo.com>
Subject: foo
Date: Thu, 11 Jan 2018 09:09:17 +0000
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/mixed; boundary="15156617570.82fd1E.6414"
Message-Id: <E1eZYrN-0001fT-Hp@admin.myserver.org>

--15156617570.82fd1E.6414
Date: Thu, 11 Jan 2018 09:09:17 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello there =C3=A9!
--15156617570.82fd1E.6414
Date: Thu, 11 Jan 2018 09:09:17 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello there =C3=A9=C3=AD=C3=B3!
--15156617570.82fd1E.6414--

I can see the split "parts", but for some reason they show up together?

UPDATE: : I thought I had fixed this - I had 2 of these attributes => { } values for each @part, and that was causing the content_type to be text/plain as a default. So I now have:

  my @parts = (
      Email::MIME->create(
          body_str => "Hello there <b>é!</b>",
          attributes => {
                encoding => 'quoted-printable',
                charset  => "UTF-8",
                content_type => "text/plain",
                disposition  => "inline",
          }
      ),
      Email::MIME->create(

          body_str => "Hello there <b>éíó!</b>",
          attributes => {
                content_type => "text/html",
                disposition  => "inline",
                charset      => "UTF-8",
                encoding     => 'quoted-printable',
          }
      )
  );

...and the email comes out as:

From: andy@mysite.org
To: Name <andy@foo.com>
Subject: foo
Date: Thu, 11 Jan 2018 09:45:21 +0000
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/mixed; boundary="15156639210.d5dF6bf.14583"


--15156639210.d5dF6bf.14583
Date: Thu, 11 Jan 2018 09:45:21 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hello there <b>=C3=A9!</b>


--15156639210.d5dF6bf.14583
Date: Thu, 11 Jan 2018 09:45:21 +0000
MIME-Version: 1.0
Content-Type: text/html; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hello there <b>=C3=A9=C3=AD=C3=B3!</b>


--15156639210.d5dF6bf.14583--

...but its still showing both the plain text and HTML parts at the same time. The weird part, is that if I put tags around some of it, I get what I would expect:

enter image description here

...but it just shows them both side by side :/


Solution

  • I finally worked it out by comparing an email that I knew worked as I was expecting, to mine.

    The emails I was sending out, had:

    Content-Type: multipart/mixed; boundary="_----------=xxxxx"
    

    But the working ones had:

    Content-Type: multipart/alternative; boundary="_----------=xxxxx"
    

    Sure enough, seeing the multipart/mixed, it now works fine:

    $email->content_type_set( 'multipart/alternative' );