1 package Catalyst::View::Email;
6 use Encode qw(encode decode);
7 use Email::Sender::Simple qw/ sendmail /;
8 use Email::MIME::Creator;
9 extends 'Catalyst::View';
11 our $VERSION = '0.32';
12 $VERSION = eval $VERSION;
18 default => sub { "sendmail" }
21 has '_mailer_obj' => (
23 does => 'Email::Sender::Transport',
25 builder => '_build_mailer_obj',
32 default => sub { "email" }
38 default => sub { { content_type => 'text/plain' } },
46 default => sub { { mailer => shift->mailer } }
49 has 'content_type' => (
52 default => sub { shift->default->{content_type} },
58 Catalyst::View::Email - Send Email from Catalyst
62 This module sends out emails from a stash key specified in the
63 configuration settings.
67 WARNING: since version 0.10 the configuration options slightly changed!
69 Use the helper to create your View:
71 $ script/myapp_create.pl view Email Email
73 In your app configuration:
77 # Where to look in the stash for the email information.
78 # 'email' is the default, so you don't have to specify it.
80 # Define the defaults for the mail
82 # Defines the default content type (mime type). Mandatory
83 content_type => 'text/plain',
84 # Defines the default charset for every MIME part with the
86 # According to RFC2049 a MIME part without a charset should
87 # be treated as US-ASCII by the mail client.
88 # If the charset is not set it won't be set for all MIME parts
89 # without an overridden one.
93 # Setup how to send the email
94 # all those options are passed directly to Email::Sender::Simple
96 # if mailer doesn't start with Email::Sender::Simple::Transport::,
97 # then this is prepended.
99 # mailer_args is passed directly into Email::Sender::Simple
101 host => 'smtp.example.com', # defaults to localhost
102 sasl_username => 'sasl_username',
103 sasl_password => 'sasl_password',
111 If you use SMTP and don't specify host, it will default to localhost and
112 attempt delivery. This often means an email will sit in a queue and
119 Sending email is just filling the stash and forwarding to the view:
121 sub controller : Private {
122 my ( $self, $c ) = @_;
124 $c->stash->{email} = {
125 to => 'jshirley@gmail.com',
126 cc => 'abraxxa@cpan.org',
127 from => 'no-reply@foobar.com',
128 subject => 'I am a Catalyst generated email',
129 body => 'Body Body Body',
132 $c->forward( $c->view('Email') );
135 Alternatively you can use a more raw interface and specify the headers as
136 an array reference like it is passed to L<Email::MIME::Creator>.
137 Note that you may also mix both syntaxes if you like ours better but need to
138 specify additional header attributes.
139 The attributes are appended to the header array reference without overwriting
142 $c->stash->{email} = {
144 To => 'jshirley@gmail.com',
145 Cc => 'abraxxa@cpan.org',
146 Bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
147 From => 'no-reply@foobar.com',
148 Subject => 'Note the capitalization differences',
150 body => qq{Ain't got no body, and nobody cares.},
155 content_type => 'text/plain',
156 disposition => 'attachment',
157 charset => 'US-ASCII',
159 body => qq{Got a body, but didn't get ahead.},
164 You can set the envelope sender and recipient as well:
166 $c->stash->{email} = {
168 envelope_from => 'envelope-from@example.com',
169 from => 'header-from@example.com',
171 envelope_to => [ 'foo@example.com', 'bar@example.com' ],
172 to => 'Undisclosed Recipients:;',
177 =head1 HANDLING ERRORS
179 If the email fails to send, the view will die (throw an exception).
180 After your forward to the view, it is a good idea to check for errors:
182 $c->forward( $c->view('Email') );
184 if ( scalar( @{ $c->error } ) ) {
185 $c->error(0); # Reset the error condition if you need to
186 $c->response->body('Oh noes!');
188 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
191 =head1 USING TEMPLATES FOR EMAIL
193 Now, it's no fun to just send out email using plain strings.
194 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
195 favourite template engine to render the mail body.
203 Validates the base config and creates the L<Email::Sender::Simple> object for later use
211 my $stash_key = $self->stash_key;
212 croak "$self stash_key isn't defined!"
213 if ( $stash_key eq '' );
217 sub _build_mailer_obj {
219 my $transport_class = ucfirst $self->sender->{mailer};
221 # borrowed from Email::Sender::Simple -- apeiron, 2010-01-26
222 if ( $transport_class !~ /^Email::Sender::Transport::/ ) {
223 $transport_class = "Email::Sender::Transport::$transport_class";
226 Class::MOP::load_class($transport_class);
228 return $transport_class->new( $self->sender->{mailer_args} || {} );
233 The process method does the actual processing when the view is dispatched to.
235 This method sets up the email parts and hands off to L<Email::Sender::Simple> to handle
236 the actual email delivery.
241 my ( $self, $c ) = @_;
243 croak "Unable to send mail, bad mail configuration"
244 unless $self->sender->{mailer};
246 my $email = $c->stash->{ $self->stash_key };
247 croak "Can't send email without a valid email structure"
250 # Default content type
251 if ( $self->content_type and not $email->{content_type} ) {
252 $email->{content_type} = $self->content_type;
255 my $header = $email->{header} || [];
256 push @$header, ( 'To' => delete $email->{to} )
258 push @$header, ( 'Cc' => delete $email->{cc} )
260 push @$header, ( 'From' => delete $email->{from} )
263 ( 'Subject' => Encode::encode( 'MIME-Header', delete $email->{subject} ) )
264 if $email->{subject};
265 push @$header, ( 'Content-type' => $email->{content_type} )
266 if $email->{content_type};
268 my $parts = $email->{parts};
269 my $body = $email->{body};
271 unless ( $parts or $body ) {
272 croak "Can't send email without parts or body, check stash";
275 my %mime = ( header => $header, attributes => {} );
277 if ( $parts and ref $parts eq 'ARRAY' ) {
278 $mime{parts} = $parts;
284 $mime{attributes}->{content_type} = $email->{content_type}
285 if $email->{content_type};
286 if ( $mime{attributes}
287 and not $mime{attributes}->{charset}
288 and $self->{default}->{charset} )
290 $mime{attributes}->{charset} = $self->{default}->{charset};
293 $mime{attributes}->{encoding} = $email->{encoding}
294 if $email->{encoding};
296 my $message = $self->generate_message( $c, \%mime );
299 my $return = sendmail( $message,
301 exists $email->{envelope_from} ? ( from => $email->{envelope_from} ) : (),
302 exists $email->{envelope_to} ? ( to => $email->{envelope_to} ) : (),
303 transport => $self->_mailer_obj,
306 # return is a Return::Value object, so this will stringify as the error
307 # in the case of a failure.
308 croak "$return" if !$return;
311 croak "Unable to create message";
315 =item setup_attributes($c, $attr)
317 Merge attributes with the configured defaults. You can override this method to
318 return a structure to pass into L<generate_message> which subsequently
319 passes the return value of this method to Email::MIME->create under the
324 sub setup_attributes {
325 my ( $self, $c, $attrs ) = @_;
327 my $default_content_type = $self->default->{content_type};
328 my $default_charset = $self->default->{charset};
329 my $default_encoding = $self->default->{encoding};
333 if ( exists $attrs->{content_type}
334 && defined $attrs->{content_type}
335 && $attrs->{content_type} ne '' )
337 $c->log->debug( 'C::V::Email uses specified content_type '
338 . $attrs->{content_type}
341 $e_m_attrs->{content_type} = $attrs->{content_type};
343 elsif ( defined $default_content_type && $default_content_type ne '' ) {
345 "C::V::Email uses default content_type $default_content_type.")
347 $e_m_attrs->{content_type} = $default_content_type;
350 if ( exists $attrs->{charset}
351 && defined $attrs->{charset}
352 && $attrs->{charset} ne '' )
354 $e_m_attrs->{charset} = $attrs->{charset};
356 elsif ( defined $default_charset && $default_charset ne '' ) {
357 $e_m_attrs->{charset} = $default_charset;
360 if ( exists $attrs->{encoding}
361 && defined $attrs->{encoding}
362 && $attrs->{encoding} ne '' )
365 'C::V::Email uses specified encoding '
369 $e_m_attrs->{encoding} = $attrs->{encoding};
371 elsif ( defined $default_encoding && $default_encoding ne '' ) {
373 "C::V::Email uses default encoding $default_encoding.")
375 $e_m_attrs->{encoding} = $default_encoding;
381 =item generate_message($c, $attr)
383 Generate a message part, which should be an L<Email::MIME> object and return it.
385 Takes the attributes, merges with the defaults as necessary and returns a
390 sub generate_message {
391 my ( $self, $c, $attr ) = @_;
393 # setup the attributes (merge with defaultis)
394 $attr->{attributes} = $self->setup_attributes( $c, $attr->{attributes} );
395 Email::MIME->create( %$attr );
401 =head1 TROUBLESHOOTING
403 As with most things computer related, things break. Email even more so.
404 Typically any errors are going to come from using SMTP as your sending method,
405 which means that if you are having trouble the first place to look is at
406 L<Email::Sender::Transport::SMTP>. This module is just a wrapper for L<Email::Sender::Simple>,
407 so if you get an error on sending, it is likely from there anyway.
409 If you are using SMTP and have troubles sending, whether it is authentication
410 or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
411 if applicable, L<Net::SMTP::SSL> installed.
413 It is very simple to check that you can connect via L<Net::SMTP>, and if you
414 do have sending errors the first thing to do is to write a simple script
415 that attempts to connect. If it works, it is probably something in your
416 configuration so double check there. If it doesn't, well, keep modifying
417 the script and/or your mail server configuration until it does!
421 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
423 =head2 L<Catalyst::Manual> - The Catalyst Manual
425 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
429 J. Shirley <jshirley@gmail.com>
431 Alexander Hartmaier <abraxxa@cpan.org>
439 Daniel Westermann-Clark
441 Simon Elliott <cpan@browsing.co.uk>
445 Lance Brown <lance@bearcircle.net>
447 Devin Austin <dhoss@cpan.org>
449 Chris Nehren <apeiron@cpan.org>
453 Copyright (c) 2007 - 2009
454 the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
459 This library is free software, you can redistribute it and/or modify it under
460 the same terms as Perl itself.