problem sending email using MIME::Lite from gmail's stmp server

T

Ted Byers

I am using Activestate perl 5.10.0 on WXP, if that matters.

I can get all the examples to work properly for trivially simple
emails. However, the following:

MIME::Lite->send('smtp','smtp.gmail.com',AuthUser=>$un, AuthPass=>
$pw, Timeout => 60);

produces the error:

SMTP auth() command not supported on smtp.gmail.com

If I remove the credentials, I get an error about the need to
establish a secure channel, specifically:

SMTP mail() command failed:
5.7.0 Must issue a STARTTLS command first. 11sm9055536vcp.45

Alas, MIME::Lite documentation makes no mention of anything related to
possible issues using stml.gmail.com and thus the question is, "What
needs to be done to set MIME::Lite up to use gmail properly?" A
related question is "What needs to be changed from the usual
configuration in order to use a gmail account that has a domain
different from gmail.com?"

Yes, I did see Email::Send::Gmail, but it is not clear how to use it
in a manner equivalent to:

my $msg = MIME::Lite->new(
From => $sender,
To => $recipient,
Subject => $subject_line,
Type =>'multipart/related'
);
$msg->attach(Type => 'text/html',
Data => $html_template,
);
$msg->attach(Type => 'image/jpg',
Id => 'logo.jpg',
Path => 'template.files/image002.jpg',
);
MIME::Lite->send('smtp','smtp.gmail.com',AuthUser=>$un, AuthPass=>
$pw, Timeout => 60);
$msg->send();

Thanks,

Ted
 
A

Andrzej Adam Filip

Ted Byers said:
I am using Activestate perl 5.10.0 on WXP, if that matters.

I can get all the examples to work properly for trivially simple
emails. However, the following:

MIME::Lite->send('smtp','smtp.gmail.com',AuthUser=>$un, AuthPass=>
$pw, Timeout => 60);

produces the error:

SMTP auth() command not supported on smtp.gmail.com

If I remove the credentials, I get an error about the need to
establish a secure channel, specifically:

SMTP mail() command failed:
5.7.0 Must issue a STARTTLS command first. 11sm9055536vcp.45
[...]

1) smtp.gmail.com offers support of AUTH command in SMTP session *AFTER*
receiving STARTTLS (after switching to encrypted connection).

#v+
.... Connecting to smtp.gmail.com via esmtp...
220 mx.google.com ESMTP x16sm15625549bku.5250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250 PIPELINING250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250 PIPELINING
#v-

2) MIME::Lite uses Net::SMTP for sending via SMTP.

Net::SMTP due to its design requires non trivial rewrite to support both
encrypted and non encrypted connections.

Possible fix:
a) use MIME::Lite to compose the message $msg->as_string
b) send message using Net::SMTP::TLS module from CPAN
[ I have not used Net::SMTP::TLS myself ]
 
T

Ted Byers

Ted Byers said:
I am using Activestate perl 5.10.0 on WXP, if that matters.
I can get all the examples to work properly for trivially simple
emails.  However, the following:
  MIME::Lite->send('smtp','smtp.gmail.com',AuthUser=>$un, AuthPass=>
$pw, Timeout => 60);
produces the error:
SMTP auth() command not supported on smtp.gmail.com
If I remove the credentials, I get an error about the need to
establish a secure channel, specifically:
SMTP mail() command failed:
5.7.0 Must issue a STARTTLS command first. 11sm9055536vcp.45
[...]

1) smtp.gmail.com offers support of AUTH command in SMTP session *AFTER*
   receiving STARTTLS (after switching to encrypted connection).

#v+
... Connecting to smtp.gmail.com via esmtp...
220 mx.google.com ESMTP x16sm15625549bku.5>>> EHLO xxxx

250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250 PIPELINING>>> STARTTLS

220 2.0.0 Ready to start TLS>>> EHLO xxxx

250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250 PIPELINING
#v-

2) MIME::Lite uses Net::SMTP for sending via SMTP.

Net::SMTP due to its design requires non trivial rewrite to support both
encrypted and non encrypted connections.

Possible fix:
a) use MIME::Lite to compose the message $msg->as_string
b) send message using Net::SMTP::TLS module from CPAN
   [ I have not used Net::SMTP::TLS myself ]

--
[pl>en Andrew] Andrzej Adam Filip : (e-mail address removed) : (e-mail address removed)
... A solemn, unsmiling, sanctimonious old iceberg who looked like he
was waiting for a vacancy in the Trinity.
  -- Mark Twain

Thanks Andrzej

So far so good. I have been able to connect to gmail and send plain
text email using Net::SMTP::TLS. However, I suspect there is a bug in
$msg->as_string because my logo.jpg is damaged, and the <img ...> tag
seems broken (i.e. the image does not appear in the right place in the
html body). This is in contrast to when I use the defaults in
MIME::Lite but the smtp services of my M$ Exchange server (the only
reason I am not using that server here is that the domain required for
sending is on the gmail email account).

Since MIME::Lite uses Net::SMTP, and I can use Net::SMTP::TLS to
connect to gmail, is there a way to tell MIME::Lite to use the sender
I make using Net::SMTP::TLS, or that it should use Net::SMTP::TLS
instead of Net::SMTP?

Thanks

Ted
 
A

Andrzej Adam Filip

Ted Byers said:
Ted Byers said:
I am using Activestate perl 5.10.0 on WXP, if that matters.
I can get all the examples to work properly for trivially simple
emails.  However, the following:
  MIME::Lite->send('smtp','smtp.gmail.com',AuthUser=>$un, AuthPass=>
$pw, Timeout => 60);
produces the error:
SMTP auth() command not supported on smtp.gmail.com
If I remove the credentials, I get an error about the need to
establish a secure channel, specifically:
SMTP mail() command failed:
5.7.0 Must issue a STARTTLS command first. 11sm9055536vcp.45
[...]

1) smtp.gmail.com offers support of AUTH command in SMTP session *AFTER*
   receiving STARTTLS (after switching to encrypted connection).

#v+
... Connecting to smtp.gmail.com via esmtp...
220 mx.google.com ESMTP x16sm15625549bku.5>>> EHLO xxxx

250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250 PIPELINING>>> STARTTLS

220 2.0.0 Ready to start TLS>>> EHLO xxxx

250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250 PIPELINING
#v-

2) MIME::Lite uses Net::SMTP for sending via SMTP.

Net::SMTP due to its design requires non trivial rewrite to support both
encrypted and non encrypted connections.

Possible fix:
a) use MIME::Lite to compose the message $msg->as_string
b) send message using Net::SMTP::TLS module from CPAN
   [ I have not used Net::SMTP::TLS myself ]

Thanks Andrzej

So far so good. I have been able to connect to gmail and send plain
text email using Net::SMTP::TLS. However, I suspect there is a bug in
$msg->as_string because my logo.jpg is damaged, and the <img ...> tag
seems broken (i.e. the image does not appear in the right place in the
html body). This is in contrast to when I use the defaults in
MIME::Lite but the smtp services of my M$ Exchange server (the only
reason I am not using that server here is that the domain required for
sending is on the gmail email account).

Since MIME::Lite uses Net::SMTP, and I can use Net::SMTP::TLS to
connect to gmail, is there a way to tell MIME::Lite to use the sender
I make using Net::SMTP::TLS, or that it should use Net::SMTP::TLS
instead of Net::SMTP?

*Test* the hack below to make MIME::Lite use Net::SMTP::TLS instead of
Net::SMTP:

use MIME::Lite;
use Net::SMTP::TLS;
BEGIN { @MIME::Lite::SMTP::ISA = qw(Net::SMTP::TLS); }
 
T

Ted Byers

Ted Byers said:
I am using Activestate perl 5.10.0 on WXP, if that matters.
I can get all the examples to work properly for trivially simple
emails.  However, the following:
  MIME::Lite->send('smtp','smtp.gmail.com',AuthUser=>$un, AuthPass=>
$pw, Timeout => 60);
produces the error:
SMTP auth() command not supported on smtp.gmail.com
If I remove the credentials, I get an error about the need to
establish a secure channel, specifically:
SMTP mail() command failed:
5.7.0 Must issue a STARTTLS command first. 11sm9055536vcp.45
[...]
1) smtp.gmail.com offers support of AUTH command in SMTP session *AFTER*
   receiving STARTTLS (after switching to encrypted connection).
#v+
... Connecting to smtp.gmail.com via esmtp...
220 mx.google.com ESMTP x16sm15625549bku.5>>> EHLO xxxx
250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250 PIPELINING>>> STARTTLS
220 2.0.0 Ready to start TLS>>> EHLO xxxx
250-mx.google.com at your service, [aaa.bbb.ccc.ddd]
250-SIZE 35651584
250-8BITMIME
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250 PIPELINING
#v-
2) MIME::Lite uses Net::SMTP for sending via SMTP.
Net::SMTP due to its design requires non trivial rewrite to support both
encrypted and non encrypted connections.
Possible fix:
a) use MIME::Lite to compose the message $msg->as_string
b) send message using Net::SMTP::TLS module from CPAN
   [ I have not used Net::SMTP::TLS myself ]
Thanks Andrzej
So far so good.  I have been able to connect to gmail and send plain
text email using Net::SMTP::TLS.  However, I suspect there is a bug in
$msg->as_string because my logo.jpg is damaged, and the <img ...> tag
seems broken (i.e. the image does not appear in the right place in the
html body).  This is in contrast to when I use the defaults in
MIME::Lite but the smtp services of my  M$ Exchange server (the only
reason I am not using that server here is that the domain required for
sending is on the gmail email account).
Since MIME::Lite uses Net::SMTP, and I can use Net::SMTP::TLS to
connect to gmail, is there a way to tell MIME::Lite to use the sender
I make using Net::SMTP::TLS, or that it should use Net::SMTP::TLS
instead of Net::SMTP?

*Test* the hack below to make MIME::Lite use Net::SMTP::TLS instead of
Net::SMTP:

use MIME::Lite;
use Net::SMTP::TLS;
BEGIN { @MIME::Lite::SMTP::ISA = qw(Net::SMTP::TLS); }

Thanks, that changes things. But I get a different error:

Can't locate object method "supports" via package "MIME::Lite::SMTP"
at C:/Perl/site/lib/MIME/Lite.pm line 2872, <GEN3> line 7.

Does this tell you more than it tells me?

Thanks

Ted
 
C

Chris Nehren

I am using Activestate perl 5.10.0 on WXP, if that matters.

Yes, it does. Everyone using Windows has abandoned ActiveState in favor
of Strawberry. ActiveState Perl is for ActiveState to sell support
contracts and should be treated as such (much as RHELL is for RedHat to
sell support contracts). You should contact your support representative
for help with this issue.

[snip 1995-era MIME::Lite code that doesn't work]

People living in the 21st century write email code using Email::MIME,
Email::Sender, and optionally Email::MIME::Kit. For sending through
Gmail, you'll want Email::Sender::Transport::SMTP::TLS. The example in
the synopsis should get you started. It's specifically written for
Gmail.
 
T

Ted Byers

I am using Activestate perl 5.10.0 on WXP, if that matters.

Yes, it does. Everyone using Windows has abandoned ActiveState in favor
of Strawberry. ActiveState Perl is for ActiveState to sell support
contracts and should be treated as such (much as RHELL is for RedHat to
sell support contracts). You should contact your support representative
for help with this issue.

[snip 1995-era MIME::Lite code that doesn't work]

People living in the 21st century write email code using Email::MIME,
Email::Sender, and optionally Email::MIME::Kit. For sending through
Gmail, you'll want Email::Sender::Transport::SMTP::TLS. The example in
the synopsis should get you started. It's specifically written for
Gmail.

Thanks guys. great. We have progress.

I can now send email in which the body is html, and from a gmail
account to an arbitrary account.

But there is a problem. While the html displays OK, the top haif of
it is repeated at the end. Equally badly, the link between the jpg
file (containing the logo) and the img tag in the html is broken.

The first few lines, showing the package I am using are:

use strict;
use warnings;

use Email::Sender::Transport::SMTP::TLS;
#use Email::Simple::Creator; # or other Email::
use Email::MIME::Creator;
use IO::All;

my $first_name = 'Ted';
my $html_template = slurp_file();
$html_template =~ s/>NAME</>$first_name</;

And, following the examples in the packages' documentation, I made the
following:

my $sender = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.gmail.com',
port => 587,
username => '(e-mail address removed)',
password => 'cbs2010',
helo => 'capitalbusinessservices.net',
);
my $subject = "A test sending MIME content from gmail to an arbitrary
address (mine)";

my $html_part = Email::MIME->create(
attributes => {
content_type => "text/html",
},
body => "$html_template",
);
my $image_part = Email::MIME->create(
attributes => {
content_type => "image/jpg",
name => "logo.jpg",
},
body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
header => [
From => '(e-mail address removed)',
To => '(e-mail address removed)',
Subject => $subject,
],
parts => \@parts,
);

eval {
$sender->send($message, {
from => '(e-mail address removed)',
to => [ '(e-mail address removed)' ],
} );
};
die "Error sending email: $@" if $@;

It could hardly be simpler.

The img tag is:

<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

I have undoubtedly missed something in making each of the parts, but I
have yet to find what. What I see of the image suggests that
"io( "template.files/image002.jpg" )->all" loses half of the jpeg file
(only half of the image is visible in the attachment, even though the
image is intact if I use my image editor to view it).

Any information you can provide as to what I missed would be
appreciated.

Thanks

Ted
 
T

Ted Byers


Hi Ben,

Thanks.
Have you printed out $html_template to verify it contains what you think
it does?
Yes. That was the first thing I had done.
I sincerely hope this isn't your actual password. If it is, change it
*right* *now*.
Damn. That's what happens when you rush. That will be corrected
promptly.
Are you sending this from a machine called capitalbusinessservices.net?
If not you should not be claiming you are. In any case, it's probably
better to let HELO/EHLO default to your machine's actual hostname.
Actually, we have a rather more complex network, where the same
hardware lives in different domains, and we make use of Gmail's
support for relating a given gmail account to different domains.
Those quotes don't do anything for you. See perldoc -q quote.


Have you tried this without IO::All? Since a JPEG is a binary file, are
you reading the file in binmode, if that matters?

yes, I'll test that next.

I wonder if I need to uuencode it, and if so, how that would change
the headers I tell it to use. Isn't there an encoding attribute that
can be attached to a MIME object?
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
);
eval {
        $sender->send($message, {
            from => '(e-mail address removed)',
            to   => [ '(e-mail address removed)' ],
        } );
    };
    die "Error sending email: $@" if $@;

It's safer to write this like

    eval {
        $sender->send(...);
        1;
    } or die "...";

There are circumstances under which $@ can be cleared between the end of
the eval and the start of the next statement (signal handlers, for
instance) and it's important to know there was an error even if you've
lost the message by then. (Yes, this is annoying, and generally regarded
as a flaw in Perl's exception mechanism.) You may also want to look at
Try::Tiny, which handles the unpleasant details for you.
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

What happens if you take out that v:shapes attribute? It's not HTML.
The original of the html document was an MS Word document. I guess I
better clean out the crap that M$ apps add to html files.
When you say 'in the attachment' do you mean 'embedded in the HTML
section of the message'? What happens if you save just the JPEG
somewhere and compare it to the original file: are they identical?

Instead of showing up embedded in the html body, it appeared at the
end of the message where, using the web client to gmail, places
attachments.
Are you using IE/Outlook/something else MS to view the email? ISTR that
v:shapes attribute is something Word puts in HTML; possibly it's causing
mshtml to display only part of the image. What happens if you use a
different browser? What happens if you just view the original HTML file,
without incorporating it into an email?
When I save the html as a local file, it appears as it is supposed to
appear regardless of whether I use Firefox or MS IE.

But to be sure, I'll strip out anything that isn't routine HTML, and
see hwo that affects things.

Thanks again

Ted
 
A

Andrzej Adam Filip

Ben Morrow said:
MIME::Lite is using the undocumented Net::SMTP method ->supports. This
is arguably a bug in MIME::Lite;
OTOH changind a class's @ISA behind its back isn't very polite either.

I do agree that "external messing with ISA is not very polite" :)

Another *dirty* hack to test is to make Net::SMTP use IO::Socket::SSL
instead of IO::Socket::INET and use SMTPS connection to SMTPS (465)
port [AFAIR I have been able to make Net::NNTP "support" NNTPS but I
have conducted a little more than basic tests ].

use MIME::Lite;
use Net::SMTP;
BEGIN { grep{ s/^IO::Socket::INET$/IO::Socket::SSL/ || 1 } @Net::SMTP::ISA }
....
MIME::Lite->send('smtp','smtp.gmail.com',Port=>465,...);
 
C

Chris Nehren

$html_template =~ s/>NAME</>$first_name</;

All the improvements Ben helpfully suggested, plus:

Don't parse or modify html with regular expressions! See one of
HTML::parser's subclasses: HTML::TokeParser, HTML::TokeParser::Simple,
HTML::TreeBuilder:):Xpath)?, HTML::TableExtract, etc. See also
http://is.gd/cVdG0. If your response begins "that's
overkill. i only want to..." you are wrong, see also
http://tinyurl.com/ydb4j9j

(yes, a bot factoid)

Email::MIME::Kit makes it really, really easy to use templates to
generate your HTML. If you want to stick to something resembling HTML,
try HTML::Mason. If the idea of including logic in your templates makes
it hard for you to sleep at night, see Template Toolkit. The
Email::MIME::Kit::Renderer namespace on CPAN provides many ways to
render HTML messages.
When I save the html as a local file, it appears as it is supposed to
appear regardless of whether I use Firefox or MS IE.

If it appears as it should outside of Gmail, it's a Gmail rendering
issue, and I don't think there's much you can do about it. Perhaps you
can report it to their support (*ha*!) and they'll fix it in a later
release (*ROFL*).
 
C

Chris Nehren

use MIME::Lite;
use Net::SMTP;
BEGIN { grep{ s/^IO::Socket::INET$/IO::Socket::SSL/ || 1 } @Net::SMTP::ISA }
...
MIME::Lite->send('smtp','smtp.gmail.com',Port=>465,...);

Why monkeypatch when there are robust libraries already written to do
the job?

Also, you're abusing grep for side effects.
 
P

Peter J. Holzer

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.

The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
attributes => {
content_type => "text/html",
},
body => "$html_template",
);
my $image_part = Email::MIME->create(
attributes => {
content_type => "image/jpg",
name => "logo.jpg",
},
body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
header => [
From => '(e-mail address removed)',
To => '(e-mail address removed)',
Subject => $subject,
],
parts => \@parts,
); [...]
It could hardly be simpler.

The img tag is:

<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
From => '(e-mail address removed)',
To => '(e-mail address removed)',
Subject => 'HTML test message',
Type => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
Type => 'text/html; charset=UTF-8',
Data => "<title>Message text</title>\n" .
"<h1>Hallo</h1>\n" .
"<p>Hier ist ein Text mit einem Bild:</p>\n" .
"<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
"<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
Type => 'image/png',
Path => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
Type => 'image/gif',
Path => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);


$msg->print(\*STDOUT);
__END__

hp
 
P

Peter J. Holzer

I wonder if I need to uuencode it,

No. Uuencode is sort of a precursor to MIME. You should use either MIME
or uuencode, but not both. In fact, since MIME can do everything
uuencode can (and much more) and is actually standardized, you should
always use MIME and never use uuencode (unless you need to talk to some
legacy software from the 1980's).

hp
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp
Thanks All,

I have tried everything suggested in this thread. Always the result
was the same, even after using cid as directed. I do not understand
why.

However, I do have progress.

In my quest for additional information, I found
Email::MIME::CreateHTML. It does make things much simpler. With it,
I need only two statements to make the message:

my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);

$message = Email::MIME->create_html(
header => [
From => $from_user,
To => $to_user,
Subject => "testing Connie's email",
],
body => $html_template,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);

The improvement this produces is twofold. First, the html body is
invariably properly displayed. Second, ythe linked in image is
displayed in the right place. However, also invariably, only half of
the logo.jpg is displayed; this despite there being enough space being
available in the browser to display it all.

The body of the html file now begins with:

<p><img width="634" height="95" src='cid:logo.jpg'></p>

NB: The result is the same regardless of whether I use a file named
logo.jpg or template.files/image002.jpg.

If I use the following:

my $logo = io( "logo.jpg" )->binary->all;
open(FOUT,"> logo.output.jpg");
binmode(FOUT);
print FOUT $logo;
close(FOUT);

I can compare the images using both Windows explorer and Irfanview,
and the files (logo.jpg and logo.output.jpg) are identical. However,
when I download and examine the image that accompanies the email, I
see it is defective.

Any ideas on why the image sent with the email is defective and how
that can be fixed?

Thanks

Ted
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp
Thanks All,

I have tried everything suggested in this thread. Always the result
was the same, even after using cid as directed. I do not understand
why.

However, I do have progress.

In my quest for additional information, I found
Email::MIME::CreateHTML. It does make things much simpler. With it,
I need only two statements to make the message:

my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);

$message = Email::MIME->create_html(
header => [
From => $from_user,
To => $to_user,
Subject => "testing Connie's email",
],
body => $html_template,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);

The improvement this produces is twofold. First, the html body is
invariably properly displayed. Second, ythe linked in image is
displayed in the right place. However, also invariably, only half of
the logo.jpg is displayed; this despite there being enough space being
available in the browser to display it all.

The body of the html file now begins with:

<p><img width="634" height="95" src='cid:logo.jpg'></p>

NB: The result is the same regardless of whether I use a file named
logo.jpg or template.files/image002.jpg.

If I use the following:

my $logo = io( "logo.jpg" )->binary->all;
open(FOUT,"> logo.output.jpg");
binmode(FOUT);
print FOUT $logo;
close(FOUT);

I can compare the images using both Windows explorer and Irfanview,
and the files (logo.jpg and logo.output.jpg) are identical. However,
when I download and examine the image that accompanies the email, I
see it is defective.

Any ideas on why the image sent with the email is defective and how
that can be fixed?

Thanks

Ted
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp
Thanks All,

I have tried everything suggested in this thread. Always the result
was the same, even after using cid as directed. I do not understand
why.

However, I do have progress.

In my quest for additional information, I found
Email::MIME::CreateHTML. It does make things much simpler. With it,
I need only two statements to make the message:

my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);

$message = Email::MIME->create_html(
header => [
From => $from_user,
To => $to_user,
Subject => "testing Connie's email",
],
body => $html_template,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);

The improvement this produces is twofold. First, the html body is
invariably properly displayed. Second, ythe linked in image is
displayed in the right place. However, also invariably, only half of
the logo.jpg is displayed; this despite there being enough space being
available in the browser to display it all.

The body of the html file now begins with:

<p><img width="634" height="95" src='cid:logo.jpg'></p>

NB: The result is the same regardless of whether I use a file named
logo.jpg or template.files/image002.jpg.

If I use the following:

my $logo = io( "logo.jpg" )->binary->all;
open(FOUT,"> logo.output.jpg");
binmode(FOUT);
print FOUT $logo;
close(FOUT);

I can compare the images using both Windows explorer and Irfanview,
and the files (logo.jpg and logo.output.jpg) are identical. However,
when I download and examine the image that accompanies the email, I
see it is defective.

Any ideas on why the image sent with the email is defective and how
that can be fixed?

Thanks

Ted
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp

OK, I am beginning to suspect there is a bug in Email::MIME
somewhere. I know the files I am using to make the email are OK,
since, if I replace the content of the email you construct in your
example, and send it from my exchange server, the result is perfect
except that it is sent from the wrong email address. The email
address that should be used exists only on the gmail account I have
been trying to use.

I can send email using the following, but the image is cut in half:

use strict;
use warnings;

use Email::MIME::CreateHTML;
use Email::Sender::Transport::SMTP::TLS;

#example modified so that there is text after image as well as before
it
my $html = qq{
<html><head><title>My Document</title></head><body>
<p>Here is a picture:</p><img
src="cid:logo.jpg"></p><p>qwerty qwerty</p>
</body></html>
};
my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);
my $quick_to_assemble_mime = Email::MIME->create_html(
header => [
From => 'YYYYYYYYYYYYYYYYYYYYYYY',
To => 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ',
Subject => 'My speedy HTML',
],
body => $html,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);
my $sender = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.gmail.com',
port => 587,
username => 'YYYYYYYYYYYYYYYYYYYYYYY',
password => 'XXXXXXXXXXXXX',
);
eval {
$sender->send($quick_to_assemble_mime, {
from => 'YYYYYYYYYYYYYYYYYYYYYYY',
to => [ 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ' ],
} );
} or die "Error sending email: $@";

In fact, if I tell it to use the png version of the logo, the image
does not display at all, and instead, if I select it from thelist of
attachments to view it, I get an error message that it is damaged.
But the original file as it exists on my machine is perfect. What
else can it be but Email::MIME->create_html (or rather the Email::MIME
package it uses) breaking my graphics files? We know that it isn't
the link between the html and the jpg file that is broken, because the
part of the jpg that is maintained appears in the right place.
Rather, it must be a problem with how it is handling the binary data
in the jpg (and png file).

I am stuck with two options, each of which has a show stopper
problem. If I use MIME::Lite, I can't connect to gmail in order to
send the email from the right email address, and if I use Email::MIME-
create_html, my graphics files are damaged (as sent within the
email). I will be content if I can have a viable solution to either
so that at least I can assemble and send the emails.

Thanks

Ted
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp

OK, I am beginning to suspect there is a bug in Email::MIME
somewhere. I know the files I am using to make the email are OK,
since, if I replace the content of the email you construct in your
example, and send it from my exchange server, the result is perfect
except that it is sent from the wrong email address. The email
address that should be used exists only on the gmail account I have
been trying to use.

I can send email using the following, but the image is cut in half:

use strict;
use warnings;

use Email::MIME::CreateHTML;
use Email::Sender::Transport::SMTP::TLS;

#example modified so that there is text after image as well as before
it
my $html = qq{
<html><head><title>My Document</title></head><body>
<p>Here is a picture:</p><img
src="cid:logo.jpg"></p><p>qwerty qwerty</p>
</body></html>
};
my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);
my $quick_to_assemble_mime = Email::MIME->create_html(
header => [
From => 'YYYYYYYYYYYYYYYYYYYYYYY',
To => 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ',
Subject => 'My speedy HTML',
],
body => $html,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);
my $sender = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.gmail.com',
port => 587,
username => 'YYYYYYYYYYYYYYYYYYYYYYY',
password => 'XXXXXXXXXXXXX',
);
eval {
$sender->send($quick_to_assemble_mime, {
from => 'YYYYYYYYYYYYYYYYYYYYYYY',
to => [ 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ' ],
} );
} or die "Error sending email: $@";

In fact, if I tell it to use the png version of the logo, the image
does not display at all, and instead, if I select it from thelist of
attachments to view it, I get an error message that it is damaged.
But the original file as it exists on my machine is perfect. What
else can it be but Email::MIME->create_html (or rather the Email::MIME
package it uses) breaking my graphics files? We know that it isn't
the link between the html and the jpg file that is broken, because the
part of the jpg that is maintained appears in the right place.
Rather, it must be a problem with how it is handling the binary data
in the jpg (and png file).

I am stuck with two options, each of which has a show stopper
problem. If I use MIME::Lite, I can't connect to gmail in order to
send the email from the right email address, and if I use Email::MIME-
create_html, my graphics files are damaged (as sent within the
email). I will be content if I can have a viable solution to either
so that at least I can assemble and send the emails.

Thanks

Ted
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp

OK, I am beginning to suspect there is a bug in Email::MIME
somewhere. I know the files I am using to make the email are OK,
since, if I replace the content of the email you construct in your
example, and send it from my exchange server, the result is perfect
except that it is sent from the wrong email address. The email
address that should be used exists only on the gmail account I have
been trying to use.

I can send email using the following, but the image is cut in half:

use strict;
use warnings;

use Email::MIME::CreateHTML;
use Email::Sender::Transport::SMTP::TLS;

#example modified so that there is text after image as well as before
it
my $html = qq{
<html><head><title>My Document</title></head><body>
<p>Here is a picture:</p><img
src="cid:logo.jpg"></p><p>qwerty qwerty</p>
</body></html>
};
my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);
my $quick_to_assemble_mime = Email::MIME->create_html(
header => [
From => 'YYYYYYYYYYYYYYYYYYYYYYY',
To => 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ',
Subject => 'My speedy HTML',
],
body => $html,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);
my $sender = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.gmail.com',
port => 587,
username => 'YYYYYYYYYYYYYYYYYYYYYYY',
password => 'XXXXXXXXXXXXX',
);
eval {
$sender->send($quick_to_assemble_mime, {
from => 'YYYYYYYYYYYYYYYYYYYYYYY',
to => [ 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ' ],
} );
} or die "Error sending email: $@";

In fact, if I tell it to use the png version of the logo, the image
does not display at all, and instead, if I select it from thelist of
attachments to view it, I get an error message that it is damaged.
But the original file as it exists on my machine is perfect. What
else can it be but Email::MIME->create_html (or rather the Email::MIME
package it uses) breaking my graphics files? We know that it isn't
the link between the html and the jpg file that is broken, because the
part of the jpg that is maintained appears in the right place.
Rather, it must be a problem with how it is handling the binary data
in the jpg (and png file).

I am stuck with two options, each of which has a show stopper
problem. If I use MIME::Lite, I can't connect to gmail in order to
send the email from the right email address, and if I use Email::MIME-
create_html, my graphics files are damaged (as sent within the
email). I will be content if I can have a viable solution to either
so that at least I can assemble and send the emails.

Thanks

Ted
 
T

Ted Byers

While the html displays OK, the top haif of it is repeated at the end.
Equally badly, the link between the jpg file (containing the logo) and
the img tag in the html is broken.
The first few lines, showing the package I am using are: [...]
use Email::MIME::Creator; [...]
my $html_part = Email::MIME->create(
          attributes => {
             content_type => "text/html",
          },
          body => "$html_template",
);
my $image_part = Email::MIME->create(
          attributes => {
             content_type => "image/jpg",
             name         => "logo.jpg",
          },
          body => io( "template.files/image002.jpg" )->all,
);
my @parts = ($html_part,$image_part);
my $message = Email::MIME->create(
      header => [
          From => '(e-mail address removed)',
          To   => '(e-mail address removed)',
     Subject => $subject,
      ],
      parts => \@parts,
); [...]
It could hardly be simpler.
The img tag is:
<img width=634 height=95 src="logo.jpg" v:shapes="_x0000_i1025">

That doesn't work. You cannot use a relative URL like "logo.jpg" in an
email. You can either use an http: URL (but many mailers won't resolve
them by default for privacy reasons (google "web bugs" for details)) or
a cid: URL to refer to an image within the email (this is a better idea
and obviously what you are trying to do). To use cid: URLs, all the
related parts of the message (in this case the HTML part and the image)
need to be enclosed in a multipart/related message. You don't seem to do
that.

Here is an example using MIME::Lite to build an HTML mail with embedded
images. Adapting it to Email::MIME::Creator is left as an exercise to
the reader:

#!/usr/bin/perl
use warnings;
use strict;

use MIME::Lite;

my $msg = MIME::Lite->new(
    From => '(e-mail address removed)',
    To   => '(e-mail address removed)',
    Subject => 'HTML test message',
    Type    => 'multipart/related; type=text/html',
);

my $unique = time();
my $tb_logo_cid = "tb-logo.$unique\@hjp.at";
my $smiley_cid = "smiley.$unique\@hjp.at";

$msg->attach(
    Type => 'text/html; charset=UTF-8',
    Data => "<title>Message text</title>\n" .
            "<h1>Hallo</h1>\n" .
            "<p>Hier ist ein Text mit einem Bild:</p>\n" .
            "<p><img alt='TB Logo' src='cid:$tb_logo_cid'></p>\n" .
            "<p>Es funktioniert! <img alt=':)' src='cid:$smiley_cid'></p>\n",
);

my $part = MIME::Lite->new(
    Type         => 'image/png',
    Path         => 'Mozilla_Thunderbird_logo.png',
);
$part->attr('Content-Id', "<$tb_logo_cid>");
$msg->attach($part);

$part = MIME::Lite->new(
    Type         => 'image/gif',
    Path         => 'smiley16.gif',
);
$part->attr('Content-Id', "<$smiley_cid>");
$msg->attach($part);

$msg->print(\*STDOUT);
__END__

        hp

OK, I am beginning to suspect there is a bug in Email::MIME
somewhere. I know the files I am using to make the email are OK,
since, if I replace the content of the email you construct in your
example, and send it from my exchange server, the result is perfect
except that it is sent from the wrong email address. The email
address that should be used exists only on the gmail account I have
been trying to use.

I can send email using the following, but the image is cut in half:

use strict;
use warnings;

use Email::MIME::CreateHTML;
use Email::Sender::Transport::SMTP::TLS;

#example modified so that there is text after image as well as before
it
my $html = qq{
<html><head><title>My Document</title></head><body>
<p>Here is a picture:</p><img
src="cid:logo.jpg"></p><p>qwerty qwerty</p>
</body></html>
};
my %objects = (
"logo.jpg" => "template.files/image002.jpg"
);
my $quick_to_assemble_mime = Email::MIME->create_html(
header => [
From => 'YYYYYYYYYYYYYYYYYYYYYYY',
To => 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ',
Subject => 'My speedy HTML',
],
body => $html,
embed => 0, #<--
inline_css => 0, #<--
objects => \%objects #<--
);
my $sender = Email::Sender::Transport::SMTP::TLS->new(
host => 'smtp.gmail.com',
port => 587,
username => 'YYYYYYYYYYYYYYYYYYYYYYY',
password => 'XXXXXXXXXXXXX',
);
eval {
$sender->send($quick_to_assemble_mime, {
from => 'YYYYYYYYYYYYYYYYYYYYYYY',
to => [ 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ' ],
} );
} or die "Error sending email: $@";

In fact, if I tell it to use the png version of the logo, the image
does not display at all, and instead, if I select it from thelist of
attachments to view it, I get an error message that it is damaged.
But the original file as it exists on my machine is perfect. What
else can it be but Email::MIME->create_html (or rather the Email::MIME
package it uses) breaking my graphics files? We know that it isn't
the link between the html and the jpg file that is broken, because the
part of the jpg that is maintained appears in the right place.
Rather, it must be a problem with how it is handling the binary data
in the jpg (and png file).

I am stuck with two options, each of which has a show stopper
problem. If I use MIME::Lite, I can't connect to gmail in order to
send the email from the right email address, and if I use Email::MIME-
create_html, my graphics files are damaged (as sent within the
email). I will be content if I can have a viable solution to either
so that at least I can assemble and send the emails.

Thanks

Ted
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top