【问题标题】:How can I send mail in a Perl script?如何在 Perl 脚本中发送邮件?
【发布时间】:2020-04-26 16:25:47
【问题描述】:

我改编了 Perl Cookbook 中的脚本。我正在测试它以在 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( );

当我运行此脚本时,我收到消息“/home/zmumba/ZMD_Proj/Docs/Reporting”不可读。 从这里How can I send mail through Gmail with Perl?,我现在明白我必须通过邮件服务器发送邮件才能使用 MIME::Lite。所以我换了

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

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

我收到错误“无法通过包 Email::Send::Gmail 找到对象方法“新””。

然后我尝试了

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

我在 /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm 第 25 行得到“散列分配中的奇数个元素”。 无法在...处的未定义值上调用方法“附加”。 关于如何去做的任何帮助? 感谢期待。

【问题讨论】:

  • 我删除了链接。请勿链接盗版书籍! (我注意到它也是 Perl 4 的一本书。它可怕地过时了,与最佳实践相去甚远)
  • @Quentin 尽管有那个 URL,Perl Cookbook 还是 perl5。自 2003 年以来,它仍然非常过时。
  • 看看这个话题的recently updated perlfaq entry
  • 对不起,但这看起来像是在摆弄,没有任何理解你在做什么,尤其是没有阅读文档 - 因此被否决。由于 IMAP 协议仅用于阅读邮件,因此甚至不可能使用 IMAP 发送电子邮件。

标签: perl


【解决方案1】:

Perl Cookbook 已有 20 年历史,其建议将过时。 Using MIME::Lite is discouraged.

MIME::Lite 不被当前维护者推荐。有许多替代方案,例如 Email::MIME 或 MIME::Entity 和 Email::Sender,您可能应该使用它们。 MIME::Lite 继续产生奇怪的错误报告,并且由于有更好的替代方案,它没有收到大量的重构。请考虑使用其他东西。

您可能应该听从他们的建议并使用Email::Sender


“无法通过包 Email::Send::Gmail 定位对象方法“new””

您需要使用 use Email::Send::Gmail 加载 Email::Send::Gmail。

您可能需要安装Email::Send::Gmail 模块。最简单的方法是使用 cpanminusinstall a fresh Perl with perlbrew 然后使用 cpanminus。


然后我尝试了

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

我在 /home/zmumba/perl5/lib/perl5/Net/IMAP/Simple.pm 第 25 行得到“散列分配中的奇数个元素”。

MIME::Lite、Email::Send::Gmail 和Net::IMAP::Simple::SSL 是具有不同接口的不同库,它们采用不同的参数。请参阅他们的文档以了解如何使用它们。

【讨论】:

    【解决方案2】:

    如前所述,不鼓励 MIME::Lite 和 Email::Send -

    Email::Send 正在消失...嗯,并没有真正消失,但它正在消失 被官方标记为“失宠”。它有 API 设计问题 这使得它很难有效地扩展,而不是试图弃用 功能并在新界面中慢慢缓解,我们已经发布 Email::Sender 解决了这些问题和其他问题

    我创建了一个脚本,它使用 Email::MIME、Email::Sender::Simple、Email::Sender::Transport::SMTP 来发送邮件。您可以查看https://github.com/rai-gaurav/perl-toolkit/tree/master/Mail 并根据您的要求使用它。 该代码中的重要行是 -

    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;
        }
    }
    

    【讨论】:

      【解决方案3】:

      Gmail 和其他邮件服务器不允许未经授权的中继。在大多数情况下,您需要授权访问。

      这是我在尝试了许多模块之后使用的。也许这个解决方案似乎有点过头了,但很容易将纯文本作为替代或其他附件更改为 HTML。传输参数是最常见的。

      #!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;
      }
      

      【讨论】:

        【解决方案4】:

        看看Email::Send::Gmail 模块。它可能会解决您的问题。

        【讨论】:

          猜你喜欢
          • 2015-01-20
          • 2015-06-15
          • 2013-06-15
          • 2014-04-14
          • 1970-01-01
          • 2010-11-15
          • 2013-08-17
          • 2014-09-20
          • 2013-07-07
          相关资源
          最近更新 更多