废话不多说。
目录:
一、TLS邮件发送涉及模块
二、CPAN上的实例
三、针对Email::Send::SMTP::TLS的使用做一个详细说明
四、总结,并含有完整perl脚本(html邮件,带附件)。
五、邮件发送时subject(主题)乱码问题解决——8月11日更新。
TLS邮件发送涉及模块:
Net::SMTP::TLS
Email::Send::SMTP::TLS
MIME::Entity
(Plus:如果不需要加密,使用net::smtp就可以了,如果需要发送ssl加密的邮件,使用Email::Send::Gmail模块)
其中,依赖模块如下:(可以直接在cpan上面查看依赖关系,然后下载还没有安装的模块)
Net::SMTP::TLS
Net::SSLeay
Test::More
MIME::Base64
ExtUtils::MakeMaker
IO::Socket::SSL
Scalar::Util
Digest::HMAC_MD5
Digest::MD5
Digest::SHA
IO::Socket::INET
Email::Send::SMTP::TLS
Test::More
Return::Value
strict
ExtUtils::MakeMaker
Exporter
Carp
Module::Build
Email::Address
Encode::MIME::Header
Email::Send
Scalar::Util
Capture::Tiny
IO::File
version
File::Spec
File::Temp
lib
Email::Abstract
Module::Pluggable
if
Email::Simple
Email::Date::Format
Time::Local
MRO::Compat
MIME::Entity
Mail::Header
Net::SMTP
Date::Format
MIME::Base64
File::Path
Test::Deep
Test::Tester
Test::NoWarnings
Net::SMTP::TLS::ButMaintained
Net::SSLeay
Digest::HMAC_MD5
Digest::MD5
Digest::SHA
IO::Socket::SSL
模块在cpan上下载,使用perl Makefile.PL / make install安装模块,这里不再赘述。
名义上,Email::Send::SMTP::TLS模块是供Gmail使用的,但实际测试,所有使用TLS加密的smtp服务器都是可以用的。
CPAN上的实例如下:
Net::SMTP::TLS使用示例:
#!/usr/bin/perl -w
use Net::SMTP::TLS;
my $mailer = new Net::SMTP::TLS(
'your.mail.host',
Hello => 'some.host.name',
Port => 25, #redundant
User => 'emailguy',
Password=> 's3cr3t');
$mailer->mail('emailguy@your.mail.host');
$mailer->to('someonecool@somewhere.else');
$mailer->data;
$mailer->datasend("Sent thru TLS!");
$mailer->dataend;
$mailer->quit;
Email::Send::SMTP::TLS使用示例:
#!/usr/bin/perl -w
use Email::Send;
my $mailer = Email::Send->new( {
mailer => 'SMTP::TLS',
mailer_args => [
Host => 'smtp.gmail.com',
Port => 587,
User => 'username@gmail.com',
Password => 'password',
Hello => 'fayland.org',
]
} );
use Email::Simple::Creator; # or other Email::
my $email = Email::Simple->create(
header => [
From => 'username@gmail.com',
To => 'to@mail.com',
Subject => 'Subject title',
],
body => 'Content.',
);
eval { $mailer->send($email) };
die "Error sending email: $@" if <a target=_blank href="mailto:$@;">$@;
</a>
测试结果,发现Net::SMTP::TLS模块是无法使用的,可能该模块只能支持默认端口为25的情况,一直提示:
invalid SSL_version specified at /usr/lib/perl5/site_perl/5.10.0/IO/Socket/SSL.pm line 467
按照CPAN的帮助提供任何版本的SSL都无法通过smtp服务。
而令人欣慰的是,虽然Email::Send::SMTP::TLS要求安装N多模块,但是是可以发送邮件的,不会报ssl版本问题。
下面针对Email::Send::SMTP::TLS(下面如果没有另外说明,默认TLS模块指代这个模块)的使用做一个详细说明。
一、基础
这个模块实际上是“继承”(姑且这么叫)Email::Send模块的,只是加入了TLS支持,所以所有方法都是和Email::Send模块相通的。
二、变化
TLS模块和Email::Send模块不同的地方,就仅仅在于构造邮件句柄的时候使用了SMTP::TLS作为“mailer”参数传入,当然,针对匿名的smtp服务,这里还需要输入用户名、密码等信息。
三、使用
使用TLS模块,首先要构造一个sender句柄(姑且这么叫吧,就是Email::Send->new出来的东东)。然后用 MIME::Entity、MIME::Lite或者 Email::Simple构造一个消息句柄,将这个句柄作为Email::Send->send方法的参数传入,就可以发送邮件了。
1. sender句柄构造方法:
方式一:
my $sender = Email::Send->new( {
mailer => 'SMTP::TLS',
mailer_args => [
Host => 'smtp.gmail.com',
Port => 587,
User => 'username@gmail.com',
Password => 'password',
Hello => 'fayland.org',
]
} );
方式二:
my $sender = Email::Send->new( {mailer => 'SMTP::TLS'});
$sender -> mailer_args (Host => 'smtp.gmail.com',
Port => 587,
User => 'username@gmail.com',
Password => 'password',
Hello => 'username');
都是一样的,另外,sender句柄的new方法还有一个message_modifier参数,不知道有啥用,看着貌似会pass很多东西,有钻研精神的同志研究出来后告诉一下我。
2. 邮件消息句柄构造方法:
使用Email::Simple:(不能带附件,不能带html格式)
my $email = Email::Simple->create(
header => [
From => 'sam-from<samsam@frommail.com>',
To => 'sam-to<samsam@tomail.com>',
Subject => 'Mail Test',
],
body => ${mail_content}, #mail_content就是邮件正文,仅支持纯文本
);
使用MIME::Entity、MIME::Lite(效果是一样的,这两个模块基本通用):
文本方式带附件:
my $email = MIME::Entity->build(From => 'sam-from<samsam@frommail.com>',
To => 'sam-to<samsam@tomail.com>',
Subject => "Mail Test with Attach",
Data => ${mail_content}
);
#附件,如果不需要附件就省略下面这一段
$email->attach(Path => "/home/sam/attach_test.txt",
Type => "AUTO"); #这个Type参数不能省略!
html方式带附件:
my $email = MIME::Entity->build(From => 'sam-from<samsam@frommail.com>',
To => 'sam-to<samsam@tomail.com>',
Subject => "Mail Test with Attach",
Type => "multipart/related"
);
#看懂了没,就是以附件的形式添加html格式的正文
$top -> attach(Type => 'Text/html',
Data => qq{${mail_content}}); #这里的content区别于上面的content,带有html格式
#附件,如果不需要附件就省略下面这一段
$email->attach(Path => "/home/sam/attach_test.txt",
Type => "AUTO"); #这个Type参数不能省略!
四、总结
上面的内容基本是抄袭CPAN的,不过CPAN是英文,看着真心累,于是翻译一下,以供参考。
下面是完整是使用html格式邮件发送带附件邮件的perl代码:
#!/usr/bin/perl -w
use Email::Send;
use MIME::Entity;
sub SendMail {
my $att_path = "/home/sam/tmpa.txt";
my $mail_host = 'smtp.sendmailhost.com';
my $mail_port = 587;
my $mail_user = 'username@sendmail.com';
my $mail_pass = 'this is your password';
my $from_add = '发件人<from@frommail.com>';
my $to_add = '收件人<to@tomail.com>';
my $subject = 'Mail Test with Attach and Html';
my @Hello = split(/\@/,${mail_user});
my $mail_content = '
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta></head>
<body style="FONT-FAMILY: 宋体; COLOR: rgb(0,0,0); FONT-SIZE: 13px">
<p> </p>
<p>亲爱的samsam(^_^):</p>
<table>这是邮件正文,带html格式</table>
</body></html>
';
#构造sender句柄
my $sender = Email::Send->new({mailer => 'SMTP::TLS'});
$sender -> mailer_args(Host => ${mail_host},
Port => ${mail_port},
User => ${mail_user},
Password => ${mail_pass},
Hello => ${Hello[0]});
#构造消息句柄
$email = MIME::Entity->build(From => ${from_add},
To => ${to_add},
Subject => ${subject},
Type => "multipart/related");
$email -> attach(Type => 'Text/html',
Data => qq{${mail_content}});
#添加附件
$email->attach(Path => ${att_path},
Type => "AUTO");
eval { $sender->send($top) };
die "Error sending email: $@" if $@;
}
SendMail();
五、邮件发送时subject(主题)乱码问题解决
上面代码发送英文邮件,或者邮件正文内含有中文,都没有问题(如果有问题,在$sender -> mailer_args里面加一个参数:Encoding => "base64")。
但是邮件的主题死活不能显示中文。
查阅相关帖子,针对邮件主题,需要进行base64编码才可以正常显示。
编码方式:
#!/usr/bin/perl -w
use MIME::Base64::Perl;
my $subject = encode_base64('测试123',"");
$subject = "=?gb2312?B?${subject}?=";
为了方便好看,我将编码行和格式化行分开写了,实际上直接一行过就ok:
my $subject = "=?gb2312?B?".encode_base64('测试123',"")."?=";
这样,在将subject变量代入$email = MIME::Entity->build中的Subject =>${subject},就可以了。
另外一点遗留问题,收件人和发件人如果别名含有中文,也会乱码,修改方式和主题雷同,不过要注意邮件地址和尖括号不能使用base64编码,不然会收不到邮件!
编码方式:
my $from_add = "=?gb2312?B?".encode_base64('我是发件人','')."?=".'<from_address@mail.com>';
my $to_add = "=?gb2312?B?".encode_base64('我是收件人1','')."?=".'<to_address@mail.com>';
————————————————————————————————————
参考文献:
Net::SMTP::TLS(http://search.cpan.org/~awestholm/Net-SMTP-TLS-0.12/lib/Net/SMTP/TLS.pm)
Email::Send::SMTP::TLS(http://search.cpan.org/~fayland/Email-Send-SMTP-TLS-0.04/lib/Email/Send/SMTP/TLS.pm)
Email::Send(http://search.cpan.org/~rjbs/Email-Send-2.199/lib/Email/Send.pm)
Email::Simple(http://search.cpan.org/~rjbs/Email-Simple-2.203/lib/Email/Simple.pm)
MIME::Entity(http://search.cpan.org/~dskoll/MIME-tools-5.505/lib/MIME/Entity.pm)
MIME::Lite(http://search.cpan.org/~rjbs/MIME-Lite-3.030/lib/MIME/Lite.pm)
perl发送html的邮件(http://bbs.chinaunix.net/thread-899782-1-1.html)
用Perl自动发送带有附件的电子邮件(http://www.hailongchang.org/index.php/archives/474)
Base-64编码及Perl实现(http://blog.csdn.net/delphiwcdj/article/details/8146836)(http://zh.wikipedia.org/wiki/Base64)