【问题标题】:How to check if last email sent was successfully delivered or not using MIME::Lite perl如何使用 MIME::Lite perl 检查上次发送的电子邮件是否已成功发送
【发布时间】:2014-11-15 00:10:44
【问题描述】:

我想用 perl 代码发送电子邮件。所以我使用了MIME::Lite 模块。

如果我删除了 last_send_successful 检查,我可以随意发送电子邮件,否则我会收到下面提到的错误。我想知道电子​​邮件是否发送成功。下面是我使用的代码 sn-p。

sub sendEmailWithCSVAttachments {
    my $retries        = 3;
    my $retry_duration = 500000;    # in microseconds
    my $return_status;
    my ( $from, $to, $cc, $subject, $body, @attachments_path_array );

    $from                   = shift;
    $to                     = shift;
    $cc                     = shift;
    $subject                = shift;
    $body                   = shift;
    @attachments_path_array = shift;

    my $msg = MIME::Lite->new(
        From    => $from,
        To      => $to,
        Cc      => $cc,
        Subject => $subject,
        Type    => 'multipart/mixed'
    ) or die "Error while creating multipart container for email: $!\n";

    $msg->attach(
        Type => 'text',
        Data => $body
    ) or die "Error while adding text message part to email: $!\n";

    foreach my $file_path (@attachments_path_array) {

        my $file_name = basename($file_path);
        $msg->attach(
            Type        => 'text/csv',
            Path        => $file_path,
            Filename    => $file_name,
            Disposition => 'attachment'
        ) or die "Error while adding attachment $file_name to email: $!\n";
    }

    my $sent = 0;
    while ( !$sent && $retries-- > 0 ) {

        eval { $msg->send(); };

        if ( !$@ && $msg->last_send_successful() ) {
            $sent = 1;
        } else {
            print "Sending failed to $to.";
            print "Will retry after $retry_duration microseconds.";
            print "Number of retries remaining $retries";
            usleep($retry_duration);
            print "Retrying...";
        }
    }

    if ($sent) {
        my $sent_message = $msg->as_string();
        print "Email sent successfully:";
        print "$sent_message\n";
        $return_status = 'success';
    } else {
        print "Email sending failed: $@";
        $return_status = 'failure';
    }
}

我得到的错误是:

Can't locate object method "last_send_successful" via package "MIME::Lite"

这意味着该方法不存在。但它在我使用的参考文献中给出。

  1. 那么我是否遗漏了什么,或者是否有其他方法可以检查上次发送是否成功或我使用的参考不正确?

  2. 因为我已经在使用 eval 块,所以这个检查是多余的吗?

  3. 使用 eval 会捕获电子邮件未送达的错误吗? (很可能没有,但想确认)

  4. 如何确保使用 MIME::Lite 发送电子邮件?

【问题讨论】:

  • perl -MMIME::Lite -e 'print $MIME::Lite::VERSION'

标签: perl email mime


【解决方案1】:

您无需使用eval 块或做任何花哨的事情来确保邮件已发送;这就是last_send_successful 的用途。当 send 子程序成功完成它的工作时,它会设置一个内部变量($object->{last_send_successful});这就是last_send_successful sub 正在检查的内容。通常不需要使用eval 块,除非您试图防止脚本死机或引发运行时或语法错误。

您可以将代码简化为以下内容:

$msg->send;

if ($msg->last_send_successful) {
    # woohoo! Message sent
}
else {
    # message did not send.
    # take appropriate action
}

$msg->send;

while (! $msg->last_send_successful) {
    # message did not send.
    # take appropriate action
}

【讨论】:

  • 感谢您的回复,但我在顶部使用“使用 MIME::Lite”。然后我也遇到了同样的错误。如果我不使用“使用 MIME::Lite”,我将无法自己创建 MIME 消息。
  • 如果你转储$msg的内容,内部变量$object->{last_send_successful}会出现吗?您可能在模块中发现了一个错误。您使用的是什么版本的 MIME::Lite 和 Perl?
  • 我使用的 MIME::Lite 版本是 3.027。这就是这个错误的原因。在 3.030 版中,它不会给出对象丢失错误。无论如何,谢谢大家。
  • 有没有办法检查邮件是否发送成功??
  • 发送一些测试消息并检查它们是否发送? perl 模块是您使用的任何后端(sendmail、SMTP、一些自定义子例程等)的包装器。如果后端报告消息传递成功,last_send_successful 将返回1。这仅涵盖实际的电子邮件发送;您可以向虚假地址发送电子邮件,后端会很高兴地报告发送成功。
猜你喜欢
  • 2017-07-09
  • 2011-05-23
  • 2012-04-22
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 2011-01-21
  • 2018-01-16
  • 2013-05-22
相关资源
最近更新 更多