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.26_01';
12 $VERSION = eval $VERSION;
18 default => sub { "sendmail" }
21 has '_mailer_obj' => (
23 isa => '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 username => 'username',
103 password => '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 bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
128 from => 'no-reply@foobar.com',
129 subject => 'I am a Catalyst generated email',
130 body => 'Body Body Body',
133 $c->forward( $c->view('Email') );
136 Alternatively you can use a more raw interface and specify the headers as
137 an array reference like it is passed to L<Email::MIME::Creator>.
138 Note that you may also mix both syntaxes if you like ours better but need to
139 specify additional header attributes.
140 The attributes are appended to the header array reference without overwriting
143 $c->stash->{email} = {
145 To => 'jshirley@gmail.com',
146 Cc => 'abraxxa@cpan.org',
147 Bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
148 From => 'no-reply@foobar.com',
149 Subject => 'Note the capitalization differences',
151 body => qq{Ain't got no body, and nobody cares.},
156 content_type => 'text/plain',
157 disposition => 'attachment',
158 charset => 'US-ASCII',
160 body => qq{Got a body, but didn't get ahead.},
165 =head1 HANDLING ERRORS
167 If the email fails to send, the view will die (throw an exception).
168 After your forward to the view, it is a good idea to check for errors:
170 $c->forward( $c->view('Email') );
172 if ( scalar( @{ $c->error } ) ) {
173 $c->error(0); # Reset the error condition if you need to
174 $c->response->body('Oh noes!');
176 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
179 =head1 USING TEMPLATES FOR EMAIL
181 Now, it's no fun to just send out email using plain strings.
182 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
183 favourite template engine to render the mail body.
191 Validates the base config and creates the L<Email::Sender::Simple> object for later use
199 my $stash_key = $self->stash_key;
200 croak "$self stash_key isn't defined!"
201 if ( $stash_key eq '' );
205 sub _build_mailer_obj {
207 my $transport_class = ucfirst $self->sender->{mailer};
209 # borrowed from Email::Sender::Simple -- apeiron, 2010-01-26
210 if ( $transport_class !~ /^Email::Sender::Transport::/ ) {
211 $transport_class = "Email::Sender::Transport::$transport_class";
214 Class::MOP::load_class($transport_class);
216 return $transport_class->new( $self->sender->{mailer_args} || {} );
221 The process method does the actual processing when the view is dispatched to.
223 This method sets up the email parts and hands off to L<Email::Sender::Simple> to handle
224 the actual email delivery.
229 my ( $self, $c ) = @_;
231 croak "Unable to send mail, bad mail configuration"
232 unless $self->sender->{mailer};
234 my $email = $c->stash->{ $self->stash_key };
235 croak "Can't send email without a valid email structure"
238 # Default content type
239 if ( $self->content_type and not $email->{content_type} ) {
240 $email->{content_type} = $self->content_type;
243 my $header = $email->{header} || [];
244 push @$header, ( 'To' => delete $email->{to} )
246 push @$header, ( 'Cc' => delete $email->{cc} )
248 push @$header, ( 'Bcc' => delete $email->{bcc} )
250 push @$header, ( 'From' => delete $email->{from} )
253 ( 'Subject' => Encode::encode( 'MIME-Header', delete $email->{subject} ) )
254 if $email->{subject};
255 push @$header, ( 'Content-type' => $email->{content_type} )
256 if $email->{content_type};
258 my $parts = $email->{parts};
259 my $body = $email->{body};
261 unless ( $parts or $body ) {
262 croak "Can't send email without parts or body, check stash";
265 my %mime = ( header => $header, attributes => {} );
267 if ( $parts and ref $parts eq 'ARRAY' ) {
268 $mime{parts} = $parts;
274 $mime{attributes}->{content_type} = $email->{content_type}
275 if $email->{content_type};
276 if ( $mime{attributes}
277 and not $mime{attributes}->{charset}
278 and $self->{default}->{charset} )
280 $mime{attributes}->{charset} = $self->{default}->{charset};
283 my $message = $self->generate_message( $c, \%mime );
286 my $return = sendmail( $message, { transport => $self->_mailer_obj } );
288 # return is a Return::Value object, so this will stringify as the error
289 # in the case of a failure.
290 croak "$return" if !$return;
293 croak "Unable to create message";
297 =item setup_attributes($c, $attr)
299 Merge attributes with the configured defaults. You can override this method to
300 return a structure to pass into L<generate_message> which subsequently
301 passes the return value of this method to Email::MIME->create under the
306 sub setup_attributes {
307 my ( $self, $c, $attrs ) = @_;
309 my $default_content_type = $self->default->{content_type};
310 my $default_charset = $self->default->{charset};
314 if ( exists $attrs->{content_type}
315 && defined $attrs->{content_type}
316 && $attrs->{content_type} ne '' )
318 $c->log->debug( 'C::V::Email uses specified content_type '
319 . $attrs->{content_type}
322 $e_m_attrs->{content_type} = $attrs->{content_type};
324 elsif ( defined $default_content_type && $default_content_type ne '' ) {
326 "C::V::Email uses default content_type $default_content_type.")
328 $e_m_attrs->{content_type} = $default_content_type;
331 if ( exists $attrs->{charset}
332 && defined $attrs->{charset}
333 && $attrs->{charset} ne '' )
335 $e_m_attrs->{charset} = $attrs->{charset};
337 elsif ( defined $default_charset && $default_charset ne '' ) {
338 $e_m_attrs->{charset} = $default_charset;
344 =item generate_message($c, $attr)
346 Generate a message part, which should be an L<Email::MIME> object and return it.
348 Takes the attributes, merges with the defaults as necessary and returns a
353 sub generate_message {
354 my ( $self, $c, $attr ) = @_;
356 # setup the attributes (merge with defaultis)
357 $attr->{attributes} = $self->setup_attributes( $c, $attr->{attributes} );
358 Email::MIME->create( %$attr );
364 =head1 TROUBLESHOOTING
366 As with most things computer related, things break. Email even more so.
367 Typically any errors are going to come from using SMTP as your sending method,
368 which means that if you are having trouble the first place to look is at
369 L<Email::Sender::Transport::SMTP>. This module is just a wrapper for L<Email::Sender::Simple>,
370 so if you get an error on sending, it is likely from there anyway.
372 If you are using SMTP and have troubles sending, whether it is authentication
373 or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
374 if applicable, L<Net::SMTP::SSL> installed.
376 It is very simple to check that you can connect via L<Net::SMTP>, and if you
377 do have sending errors the first thing to do is to write a simple script
378 that attempts to connect. If it works, it is probably something in your
379 configuration so double check there. If it doesn't, well, keep modifying
380 the script and/or your mail server configuration until it does!
384 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
386 =head2 L<Catalyst::Manual> - The Catalyst Manual
388 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
392 J. Shirley <jshirley@gmail.com>
394 Alexander Hartmaier <abraxxa@cpan.org>
402 Daniel Westermann-Clark
404 Simon Elliott <cpan@browsing.co.uk>
408 Lance Brown <lance@bearcircle.net>
410 Devin Austin <dhoss@cpan.org>
412 Chris Nehren <apeiron@cpan.org>
416 Copyright (c) 2007 - 2009
417 the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
422 This library is free software, you can redistribute it and/or modify it under
423 the same terms as Perl itself.