Tuesday 17 September 2013

Email::Postman - Yet another email sending package

I know I know, there is Email::Sender, and Mail::Sendmail, the 'send' method of MIME::Lite, Mail::Mailer  and probably other ones I don't know about on the CPAN and also the good old pipe to /bin/sendmail trick.

Each of them have their advantages, but none of them actually does what I wanted.

Email::Postman does all the following:

- It can send anything that's compatible with Email::Abstract (MIME::Entity, Email::Simple,  rfc822 String, etc..)

- It will manage multiple To, multiple Cc and multiple Bcc nicely.

- It will report on each of the recipients individually.

- It will speak to MX servers directly, according to the recipient's domain, so you don't need to manage a separate MTA to send emails.

- It has got a straight forward interface:



my $postman = Email::Postman->new({ hello => 'my-domain.com',
                                   from => 'postmaster@domain.com' }
);

my $email = ## any Email::Abstract compatible email.
            Email::Simple->create(
              header => [
                From => 'casey@geeknest.com',
                To => 'drain@example.com',
                Subject => 'Message in a bottle',
               ],
              body => '...',
            );

my @reports = $postman->deliver($email);

The only thing you need to be careful about is that depending on the responsiveness of the distant MX servers, calling deliver can be slow. So ideally you want to use it through some asynchronous mechanism. Gearman is a very popular one.

Give it a go!

Jerome.

6 comments:

  1. No option to send to the local MTA? Or is that the whole point, and if I want that, to use something else?

    ReplyDelete
    Replies
    1. If you want to delegate email sending to a Local MTA, this is not the right package to use :)

      Delete
  2. Email::Sender can provide a report for each delivery. Look at its Failure::Multi and Success::Partial classes.

    Your handling of Bcc is broken. There is no such thing as a Bcc header. The whole point of Bcc is that it doesn't go in the email headers! Email::Sender explains all this in its manual.

    Only sending via SMTP is not a good idea. You're forcing app developers to explicitly manage a retry queue. This is why any sane email sending solution involves delivering to a local MTA via sendmail and letting it handle retries.

    I'm not sure I see any value to this new module. You might want to join the #email channel on irc.perl.org to discuss the problem you're trying to solve.

    ReplyDelete
    Replies
    1. I'm fully aware of the Bcc header thing, but:

      - Email::Sender manual Bcc example 1 almost does the same as this code is doing (that is fiddling with the Bcc header so it's never sent to the To and Cc recipients).

      - People expect to be able to specify Bcc as a header of their MIME::Entities or email

      http://en.wikipedia.org/wiki/Email#Header_fields

      Also, bcc IS in http://tools.ietf.org/html/rfc822 . Section 4.5.3

      Sometimes, sending directly my SMTP is a good idea. For example, if it's a feature of your application to be able to send (lot of) emails and manage some retry delays/blacklisting correctly, it makes it much easier to talk to remote MX directly.

      Delete
    2. For use in web applications, sending directly to SMTP is now discouraged and will often fail (due to outgoing 25/587 port being blocked). Perhaps you can reconsider the option of sending to local MTA (sendmail, qmail-queue, etc) as well as sending to 3rd party services using their API.

      Delete
    3. Hi. Again, if you want to delegate to your local MTA, this is not the right package to use. There's plenty of very capable packages on the CPAN (starting with Email::Sender).

      Delete