简体   繁体   English

如何在 Perl 脚本中发送邮件?

[英]How can I send mail in a Perl script?

I have adapted a script from the Perl Cookbook.我改编了 Perl Cookbook 中的脚本。 I am testing it to send mail to myself in gmail.我正在测试它以在 gmail 中向自己发送邮件。

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

use MIME::Lite;
my $msg;
    $msg = MIME::Lite->new(From => 'zmumba@gmail.com',
    To => 'zmumba@gmail.com',
    Subject => 'My office photo',
    Type => 'multipart/mixed');

 $msg->attach(Type => 'image/png',
         Path => '/home/zmumba/ZMD_Proj/Docs/Reporting',
         Filename => 'office_lyout.png');

$msg->attach(Type => 'TEXT',
         Data => 'I hope you can use this!');

  $msg->send( );

When I run this script, I get the message "/home/zmumba/ZMD_Proj/Docs/Reporting" not readable.当我运行此脚本时,我收到消息“/home/zmumba/ZMD_Proj/Docs/Reporting”不可读。 From here How can I send mail through Gmail with Perl?从这里如何使用 Perl 通过 Gmail 发送邮件? , I now understand that I have to send mail through a mailserver to use MIME::Lite. ,我现在明白我必须通过邮件服务器发送邮件才能使用 MIME::Lite。 So I replaced所以我换了

$msg = MIME::Lite->new(From => 'zmumba@gmail.com

with

$msg = Email::Send::Gmail->new(From => 'zmumba@gmail.com

and I get the error "Can't locate object method "new" via package Email::Send::Gmail".我收到错误“无法通过 package Email::Send::Gmail 找到 object 方法“新”。

Then I tried然后我尝试了

    $msg = Net::IMAP::Simple::SSL->new(From => 'zmumba@gmail.com',

and I get "Odd number of elements in hash assignment at /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm line 25. Can't call method "attach" on an undefined value at...".我在 /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm 第 25 行得到“hash 分配中的奇数个元素。无法在...处调用未定义值的方法“附加” . Any assistance on how to go about it?有关如何 go 的任何帮助? Thanks in anticipation.感谢期待。

The Perl Cookbook is 20 years old and its recommendations will be out of date. Perl 食谱已有 20 年历史,其建议将过时。 Using MIME::Lite is discouraged .不鼓励使用 MIME::Lite

MIME::Lite is not recommended by its current maintainer. MIME::Lite 不被当前的维护者推荐。 There are a number of alternatives, like Email::MIME or MIME::Entity and Email::Sender, which you should probably use instead.有许多替代方案,例如 Email::MIME 或 MIME::Entity 和 Email::Sender,您可能应该使用它们。 MIME::Lite continues to accrue weird bug reports, and it is not receiving a large amount of refactoring due to the availability of better alternatives. MIME::Lite 继续产生奇怪的错误报告,并且由于有更好的替代方案,它没有收到大量的重构。 Please consider using something else.请考虑使用其他东西。

You should probably follow their recommendation and use Email::Sender .您可能应该遵循他们的建议并使用Email::Sender


"Can't locate object method "new" via package Email::Send::Gmail" “通过 package Email::Send::Gmail 找不到 object 方法“新”

You need to load Email::Send::Gmail with use Email::Send::Gmail .您需要use Email::Send::Gmail

You may need to install the Email::Send::Gmail module.您可能需要安装Email::Send::Gmail模块。 It's simplest to do this using either cpanminus or install a fresh Perl with perlbrew and then use cpanminus.最简单的方法是使用cpanminus或使用 perlbrew安装新的 Perl然后使用 cpanminus。


Then I tried然后我尝试了

$msg = Net::IMAP::Simple::SSL->new(From => 'zmumba@gmail.com',

and I get "Odd number of elements in hash assignment at /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm line 25.我在 /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm 第 25 行得到“hash 分配中的奇数个元素。

MIME::Lite, Email::Send::Gmail, and Net::IMAP::Simple::SSL are different libraries with different interfaces that take different arguments differently. MIME::Lite, Email::Send::Gmail, and Net::IMAP::Simple::SSL are different libraries with different interfaces that take different arguments differently. Refer to their documentation for how to use them.请参阅他们的文档以了解如何使用它们。

As mentioned before, both MIME::Lite and Email::Send is discouraged -如前所述,不鼓励 MIME::Lite 和 Email::Send -

Email::Send is going away... well, not really going away, but it's being officially marked "out of favor." Email::Send 正在消失……嗯,并没有真正消失,但它被官方标记为“失宠”。 It has API design problems that make it hard to usefully extend and rather than try to deprecate features and slowly ease in a new interface, we've released Email::Sender which fixes these problems and others它有 API 设计问题,使其难以有效扩展,而不是尝试弃用功能并在新界面中慢慢缓解,我们发布了 Email::Sender 修复了这些问题和其他问题

I have created a script which uses Email::MIME, Email::Sender::Simple, Email::Sender::Transport::SMTP for sending mail. I have created a script which uses Email::MIME, Email::Sender::Simple, Email::Sender::Transport::SMTP for sending mail. You can take a look at https://github.com/rai-gaurav/perl-toolkit/tree/master/Mail and use it as per your requirement.您可以查看https://github.com/rai-gaurav/perl-toolkit/tree/master/Mail并根据您的要求使用它。 Important lines from that code are -该代码中的重要行是 -

sub create_mail {
    my ( $self, $file_attachments, $mail_subject, $mail_body ) = @_;

    my @mail_attachments;
    if (@$file_attachments) {
        foreach my $attachment (@$file_attachments) {
            my $single_attachment = Email::MIME->create(
                attributes => {
                    filename     => basename($attachment),
                    content_type => "application/json",
                    disposition  => 'attachment',
                    encoding     => 'base64',
                    name         => basename($attachment)
                },
                body => io->file($attachment)->all
            );
            push( @mail_attachments, $single_attachment );
        }
    }
    # Multipart message : It contains attachment as well as html body
    my @parts = (
        @mail_attachments,
        Email::MIME->create(
            attributes => {
                content_type => 'text/html',
                encoding     => 'quoted-printable',
                charset      => 'US-ASCII'
            },
            body_str => $mail_body,
        ),
    );

    my $mail_to_users    = join ', ', @{ $self->{config}->{mail_to} };
    my $cc_mail_to_users = join ', ', @{ $self->{config}->{mail_cc_to} };

    my $email = Email::MIME->create(
        header => [
            From    => $self->{config}->{mail_from},
            To      => $mail_to_users,
            Cc      => $cc_mail_to_users,
            Subject => $mail_subject,
        ],
        parts => [@parts],
    );
    return $email;
}

sub send_mail {
    my ( $self, $email ) = @_;
    my $transport = Email::Sender::Transport::SMTP->new(
        {
            host => $self->{config}->{smtp_server}
        }
    );
    eval { sendmail( $email, { transport => $transport } ); };
    if ($@) {
        return 0, $@;
    }
    else {
        return 1;
    }
}

Gmail and other mail servers will not allow unauthorized relay. Gmail 和其他邮件服务器不允许未经授权的中继。 In most cases you will need authorized access.在大多数情况下,您将需要授权访问。

Here is what I use, after also trying many modules.这是我在尝试了许多模块之后使用的。 Maybe this solution seems a little bit overdone, but it's easy to change for HTML with plain text as alternative or other attachments.也许这个解决方案似乎有点过头了,但是使用纯文本作为替代或其他附件的 HTML 很容易更改。 Parameters of the transport are the most common ones.传输参数是最常见的参数。

#!perl

use strict;
use warnings;
use utf8;

use Email::Sender::Simple qw(sendmail try_to_sendmail);
use Email::Sender::Transport::SMTPS;
use Email::Simple ();
use Email::Simple::Creator ();
use Email::MIME;

send_my_mail('john.doe@hisdomain.com','Test','Test, pls ignore');

sub send_my_mail {
  my ($to_mail_address, $subject, $body_text) = @_;

  my $smtpserver   = 'smtp.mydomain.com';
  my $smtpport     = 587;
  my $smtpuser     = 'me@mydomain.com';
  my $smtppassword = 'mysecret';

  my $transport = Email::Sender::Transport::SMTPS->new({
    host          => $smtpserver,
    ssl           => 'starttls',
    port          => $smtpport,
    sasl_username => $smtpuser,
    sasl_password => $smtppassword,
    #debug => 1,
  });

  my $text_part = Email::MIME->create(
    attributes => {
        'encoding'     => 'quoted-printable',
        'content_type' => 'text/plain',
        'charset'      => 'UTF-8',
    },
    'body_str' => $body_text,
  );

  my $alternative_part = Email::MIME->create(
    attributes => {
        'content_type' => 'multipart/alternative',
    },
    parts => [ $text_part, ],
  );

  my $email = Email::MIME->create(
    header_str => [
        To      => $to_mail_address,
        From    => "Website <$smtpuser>",
        Subject => $subject,
    ],
    attributes => {
             'content_type' => 'multipart/mixed',
         },
    parts => [  $alternative_part   ],
  );

  my $status = try_to_sendmail($email, { transport => $transport });

  return $status;
}

Take a look at Email::Send::Gmail module.看看Email::Send::Gmail模块。 It might solve your problem.它可能会解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM