如何使用MIME::Lite perl检查最后一封电子邮件是否成功发送并被成功接收。

3

我想在perl代码中发送电子邮件。因此,我使用了MIME::Lite模块。

如果我删除last_send_successful检查,我就能按照自己的意愿发送电子邮件,否则我会得到下面提到的错误。我想知道电子邮件是否成功发送。以下是我使用的代码片段。

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发送的电子邮件已被投递?


2
perl -MMIME::Lite -e 'print $MIME::Lite::VERSION' - askovpen
1个回答

5
您不需要使用eval块或做任何花哨的操作来确保邮件已发送;这就是last_send_successful的作用。当发送子例程成功完成其工作时,它会设置一个内部变量($object->{last_send_successful});这就是last_send_successful子例程所检查的内容。通常情况下,除非您想防止脚本死亡或引发运行时或语法错误,否则不必使用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
}

谢谢您的回复,但我在顶部使用了"use MIME::Lite"。然后我仍然遇到了相同的错误。如果我没有使用"use MIME::Lite",我就无法创建MIME消息本身。 - chammu
如果你转储 $msg 的内容,内部变量 $object->{last_send_successful} 是否会显示出来?你可能已经发现了模块中的一个错误。你使用的 MIME::Lite 和 Perl 版本是什么? - i alarmed alien
我使用的MIME::Lite版本是3.027。这就是出现此错误的原因。使用版本3.030时,它不会出现对象丢失的错误。无论如何,感谢大家。 - chammu
有没有办法检查电子邮件是否成功发送? - chammu
发送一些测试消息并检查它们是否被成功传送?Perl模块是对你正在使用的后端(sendmail、SMTP、某些自定义子程序等)的包装器。如果后端报告消息已成功传递,last_send_successful将返回1。这仅涵盖实际的电子邮件发送;你可以向虚假地址发送电子邮件,后端将高兴地报告发送成功。 - i alarmed alien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接