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.21';
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
66 This module sends out emails from a stash key specified in the
67 configuration settings.
71 WARNING: since version 0.10 the configuration options slightly changed!
73 Use the helper to create your View:
75 $ script/myapp_create.pl view Email Email
77 In your app configuration:
81 # Where to look in the stash for the email information.
82 # 'email' is the default, so you don't have to specify it.
84 # Define the defaults for the mail
86 # Defines the default content type (mime type). Mandatory
87 content_type => 'text/plain',
88 # Defines the default charset for every MIME part with the
90 # According to RFC2049 a MIME part without a charset should
91 # be treated as US-ASCII by the mail client.
92 # If the charset is not set it won't be set for all MIME parts
93 # without an overridden one.
97 # Setup how to send the email
98 # all those options are passed directly to Email::Send
100 # if mailer doesn't start with Email::Sender::Transport::,
101 # then this is prepended.
103 # mailer_args is passed directly into Email::Send
105 host => 'smtp.example.com', # defaults to localhost
106 username => 'username',
107 password => 'password',
115 If you use SMTP and don't specify host, it will default to localhost and
116 attempt delivery. This often means an email will sit in a queue and
123 Sending email is just filling the stash and forwarding to the view:
125 sub controller : Private {
126 my ( $self, $c ) = @_;
128 $c->stash->{email} = {
129 to => 'jshirley@gmail.com',
130 cc => 'abraxxa@cpan.org',
131 bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
132 from => 'no-reply@foobar.com',
133 subject => 'I am a Catalyst generated email',
134 body => 'Body Body Body',
137 $c->forward( $c->view('Email') );
140 Alternatively you can use a more raw interface and specify the headers as
141 an array reference like it is passed to L<Email::MIME::Creator>.
142 Note that you may also mix both syntaxes if you like ours better but need to
143 specify additional header attributes.
144 The attributes are appended to the header array reference without overwriting
147 $c->stash->{email} = {
149 To => 'jshirley@gmail.com',
150 Cc => 'abraxxa@cpan.org',
151 Bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
152 From => 'no-reply@foobar.com',
153 Subject => 'Note the capitalization differences',
155 body => qq{Ain't got no body, and nobody cares.},
160 content_type => 'text/plain',
161 disposition => 'attachment',
162 charset => 'US-ASCII',
164 body => qq{Got a body, but didn't get ahead.},
169 =head1 HANDLING ERRORS
171 If the email fails to send, the view will die (throw an exception).
172 After your forward to the view, it is a good idea to check for errors:
174 $c->forward( $c->view('Email') );
176 if ( scalar( @{ $c->error } ) ) {
177 $c->error(0); # Reset the error condition if you need to
178 $c->response->body('Oh noes!');
180 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
183 =head1 USING TEMPLATES FOR EMAIL
185 Now, it's no fun to just send out email using plain strings.
186 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
187 favourite template engine to render the mail body.
195 Validates the base config and creates the L<Email::Send> object for later use
203 my $stash_key = $self->stash_key;
204 croak "$self stash_key isn't defined!"
205 if ( $stash_key eq '' );
209 sub _build_mailer_obj {
211 my $transport_class = ucfirst $self->sender->{mailer};
213 # borrowed from Email::Sender::Simple -- apeiron, 2010-01-26
214 if ($transport_class !~ /^Email::Sender::Transport::/) {
215 $transport_class = "Email::Sender::Transport::$transport_class";
218 Class::MOP::load_class($transport_class);
220 return $transport_class->new($self->sender->{mailer_args} || {});
225 The process method does the actual processing when the view is dispatched to.
227 This method sets up the email parts and hands off to L<Email::Send> to handle
228 the actual email delivery.
233 my ( $self, $c ) = @_;
235 croak "Unable to send mail, bad mail configuration"
236 unless $self->sender->{mailer};
238 my $email = $c->stash->{ $self->stash_key };
239 croak "Can't send email without a valid email structure"
242 # Default content type
243 if ( $self->content_type and not $email->{content_type} ) {
244 $email->{content_type} = $self->content_type;
247 my $header = $email->{header} || [];
248 push @$header, ( 'To' => delete $email->{to} )
250 push @$header, ( 'Cc' => delete $email->{cc} )
252 push @$header, ( 'Bcc' => delete $email->{bcc} )
254 push @$header, ( 'From' => delete $email->{from} )
257 ( 'Subject' => Encode::encode( 'MIME-Header', delete $email->{subject} ) )
258 if $email->{subject};
259 push @$header, ( 'Content-type' => $email->{content_type} )
260 if $email->{content_type};
262 my $parts = $email->{parts};
263 my $body = $email->{body};
265 unless ( $parts or $body ) {
266 croak "Can't send email without parts or body, check stash";
269 my %mime = ( header => $header, attributes => {} );
271 if ( $parts and ref $parts eq 'ARRAY' ) {
272 $mime{parts} = $parts;
278 $mime{attributes}->{content_type} = $email->{content_type}
279 if $email->{content_type};
280 if ( $mime{attributes}
281 and not $mime{attributes}->{charset}
282 and $self->{default}->{charset} )
284 $mime{attributes}->{charset} = $self->{default}->{charset};
287 my $message = $self->generate_message( $c, \%mime );
290 my $return = sendmail( $message, { transport => $self->_mailer_obj } );
292 # return is a Return::Value object, so this will stringify as the error
293 # in the case of a failure.
294 croak "$return" if !$return;
297 croak "Unable to create message";
301 =item setup_attributes($c, $attr)
303 Merge attributes with the configured defaults. You can override this method to
304 return a structure to pass into L<generate_message> which subsequently
305 passes the return value of this method to Email::MIME->create under the
310 sub setup_attributes {
311 my ( $self, $c, $attrs ) = @_;
313 my $default_content_type = $self->default->{content_type};
314 my $default_charset = $self->default->{charset};
318 if ( exists $attrs->{content_type}
319 && defined $attrs->{content_type}
320 && $attrs->{content_type} ne '' )
322 $c->log->debug( 'C::V::Email uses specified content_type '
323 . $attrs->{content_type}
326 $e_m_attrs->{content_type} = $attrs->{content_type};
328 elsif ( defined $default_content_type && $default_content_type ne '' ) {
330 "C::V::Email uses default content_type $default_content_type.")
332 $e_m_attrs->{content_type} = $default_content_type;
335 if ( exists $attrs->{charset}
336 && defined $attrs->{charset}
337 && $attrs->{charset} ne '' )
339 $e_m_attrs->{charset} = $attrs->{charset};
341 elsif ( defined $default_charset && $default_charset ne '' ) {
342 $e_m_attrs->{charset} = $default_charset;
348 =item generate_message($c, $attr)
350 Generate a message part, which should be an L<Email::MIME> object and return it.
352 Takes the attributes, merges with the defaults as necessary and returns a
357 sub generate_message {
358 my ( $self, $c, $attr ) = @_;
360 # setup the attributes (merge with defaultis)
361 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
370 =head1 TROUBLESHOOTING
372 As with most things computer related, things break. Email even more so.
373 Typically any errors are going to come from using SMTP as your sending method,
374 which means that if you are having trouble the first place to look is at
375 L<Email::Send::SMTP>. This module is just a wrapper for L<Email::Send>,
376 so if you get an error on sending, it is likely from there anyway.
378 If you are using SMTP and have troubles sending, whether it is authentication
379 or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
380 if applicable, L<Net::SMTP::SSL> installed.
382 It is very simple to check that you can connect via L<Net::SMTP>, and if you
383 do have sending errors the first thing to do is to write a simple script
384 that attempts to connect. If it works, it is probably something in your
385 configuration so double check there. If it doesn't, well, keep modifying
386 the script and/or your mail server configuration until it does!
390 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
392 =head2 L<Catalyst::Manual> - The Catalyst Manual
394 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
398 J. Shirley <jshirley@gmail.com>
400 Alexander Hartmaier <abraxxa@cpan.org>
408 Daniel Westermann-Clark
410 Simon Elliott <cpan@browsing.co.uk>
414 Lance Brown <lance@bearcircle.net>
416 Devin Austin <dhoss@cpan.org>
418 Chris Nehren <apeiron@cpan.org>
422 Copyright (c) 2007 - 2009
423 the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
428 This library is free software, you can redistribute it and/or modify it under
429 the same terms as Perl itself.