1 package Catalyst::View::Email;
6 use Encode qw(encode decode);
7 use Email::Sender::Simpleer::Simple qw/ sendmail /;
8 use Email::MIME::Creator;
9 extends 'Catalyst::View';
11 our $VERSION = '0.21';
17 default => sub { "sendmail" }
20 has '_mailer_obj' => (
22 isa => 'Email::Sender::Simpleer::Transport',
24 builder => '_build_mailer_obj',
31 default => sub { "email" }
37 default => sub { { content_type => 'text/plain' } },
45 default => sub { { mailer => shift->mailer } }
48 has 'content_type' => (
51 default => sub { shift->default->{content_type} },
57 Catalyst::View::Email - Send Email from Catalyst
65 This module sends out emails from a stash key specified in the
66 configuration settings.
70 WARNING: since version 0.10 the configuration options slightly changed!
72 Use the helper to create your View:
74 $ script/myapp_create.pl view Email Email
76 In your app configuration:
80 # Where to look in the stash for the email information.
81 # 'email' is the default, so you don't have to specify it.
83 # Define the defaults for the mail
85 # Defines the default content type (mime type). Mandatory
86 content_type => 'text/plain',
87 # Defines the default charset for every MIME part with the
89 # According to RFC2049 a MIME part without a charset should
90 # be treated as US-ASCII by the mail client.
91 # If the charset is not set it won't be set for all MIME parts
92 # without an overridden one.
96 # Setup how to send the email
97 # all those options are passed directly to Email::Sender::Simple
99 # if mailer doesn't start with Email::Sender::Simpleer::Transport::,
100 # then this is prepended.
102 # mailer_args is passed directly into Email::Sender::Simple
104 host => 'smtp.example.com', # defaults to localhost
105 username => 'username',
106 password => 'password',
114 If you use SMTP and don't specify host, it will default to localhost and
115 attempt delivery. This often means an email will sit in a queue and
122 Sending email is just filling the stash and forwarding to the view:
124 sub controller : Private {
125 my ( $self, $c ) = @_;
127 $c->stash->{email} = {
128 to => 'jshirley@gmail.com',
129 cc => 'abraxxa@cpan.org',
130 bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
131 from => 'no-reply@foobar.com',
132 subject => 'I am a Catalyst generated email',
133 body => 'Body Body Body',
136 $c->forward( $c->view('Email') );
139 Alternatively you can use a more raw interface and specify the headers as
140 an array reference like it is passed to L<Email::MIME::Creator>.
141 Note that you may also mix both syntaxes if you like ours better but need to
142 specify additional header attributes.
143 The attributes are appended to the header array reference without overwriting
146 $c->stash->{email} = {
148 To => 'jshirley@gmail.com',
149 Cc => 'abraxxa@cpan.org',
150 Bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
151 From => 'no-reply@foobar.com',
152 Subject => 'Note the capitalization differences',
154 body => qq{Ain't got no body, and nobody cares.},
159 content_type => 'text/plain',
160 disposition => 'attachment',
161 charset => 'US-ASCII',
163 body => qq{Got a body, but didn't get ahead.},
168 =head1 HANDLING ERRORS
170 If the email fails to send, the view will die (throw an exception).
171 After your forward to the view, it is a good idea to check for errors:
173 $c->forward( $c->view('Email') );
175 if ( scalar( @{ $c->error } ) ) {
176 $c->error(0); # Reset the error condition if you need to
177 $c->response->body('Oh noes!');
179 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
182 =head1 USING TEMPLATES FOR EMAIL
184 Now, it's no fun to just send out email using plain strings.
185 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
186 favourite template engine to render the mail body.
194 Validates the base config and creates the L<Email::Sender::Simple> object for later use
202 my $stash_key = $self->stash_key;
203 croak "$self stash_key isn't defined!"
204 if ( $stash_key eq '' );
208 sub _build_mailer_obj {
210 my $transport_class = ucfirst $self->sender->{mailer};
212 # borrowed from Email::Sender::Simpleer::Simple -- apeiron, 2010-01-26
213 if ($transport_class !~ /^Email::Sender::Simpleer::Transport::/) {
214 $transport_class = "Email::Sender::Simpleer::Transport::$transport_class";
217 Class::MOP::load_class($transport_class);
219 return $transport_class->new($self->sender->{mailer_args} || {});
224 The process method does the actual processing when the view is dispatched to.
226 This method sets up the email parts and hands off to L<Email::Sender::Simple> to handle
227 the actual email delivery.
232 my ( $self, $c ) = @_;
234 croak "Unable to send mail, bad mail configuration"
235 unless $self->sender->{mailer};
237 my $email = $c->stash->{ $self->stash_key };
238 croak "Can't send email without a valid email structure"
241 # Default content type
242 if ( $self->content_type and not $email->{content_type} ) {
243 $email->{content_type} = $self->content_type;
246 my $header = $email->{header} || [];
247 push @$header, ( 'To' => delete $email->{to} )
249 push @$header, ( 'Cc' => delete $email->{cc} )
251 push @$header, ( 'Bcc' => delete $email->{bcc} )
253 push @$header, ( 'From' => delete $email->{from} )
256 ( 'Subject' => Encode::encode( 'MIME-Header', delete $email->{subject} ) )
257 if $email->{subject};
258 push @$header, ( 'Content-type' => $email->{content_type} )
259 if $email->{content_type};
261 my $parts = $email->{parts};
262 my $body = $email->{body};
264 unless ( $parts or $body ) {
265 croak "Can't send email without parts or body, check stash";
268 my %mime = ( header => $header, attributes => {} );
270 if ( $parts and ref $parts eq 'ARRAY' ) {
271 $mime{parts} = $parts;
277 $mime{attributes}->{content_type} = $email->{content_type}
278 if $email->{content_type};
279 if ( $mime{attributes}
280 and not $mime{attributes}->{charset}
281 and $self->{default}->{charset} )
283 $mime{attributes}->{charset} = $self->{default}->{charset};
286 my $message = $self->generate_message( $c, \%mime );
289 my $return = sendmail( $message, { transport => $self->_mailer_obj } );
291 # return is a Return::Value object, so this will stringify as the error
292 # in the case of a failure.
293 croak "$return" if !$return;
296 croak "Unable to create message";
300 =item setup_attributes($c, $attr)
302 Merge attributes with the configured defaults. You can override this method to
303 return a structure to pass into L<generate_message> which subsequently
304 passes the return value of this method to Email::MIME->create under the
309 sub setup_attributes {
310 my ( $self, $c, $attrs ) = @_;
312 my $default_content_type = $self->default->{content_type};
313 my $default_charset = $self->default->{charset};
317 if ( exists $attrs->{content_type}
318 && defined $attrs->{content_type}
319 && $attrs->{content_type} ne '' )
321 $c->log->debug( 'C::V::Email uses specified content_type '
322 . $attrs->{content_type}
325 $e_m_attrs->{content_type} = $attrs->{content_type};
327 elsif ( defined $default_content_type && $default_content_type ne '' ) {
329 "C::V::Email uses default content_type $default_content_type.")
331 $e_m_attrs->{content_type} = $default_content_type;
334 if ( exists $attrs->{charset}
335 && defined $attrs->{charset}
336 && $attrs->{charset} ne '' )
338 $e_m_attrs->{charset} = $attrs->{charset};
340 elsif ( defined $default_charset && $default_charset ne '' ) {
341 $e_m_attrs->{charset} = $default_charset;
347 =item generate_message($c, $attr)
349 Generate a message part, which should be an L<Email::MIME> object and return it.
351 Takes the attributes, merges with the defaults as necessary and returns a
356 sub generate_message {
357 my ( $self, $c, $attr ) = @_;
359 # setup the attributes (merge with defaultis)
360 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
369 =head1 TROUBLESHOOTING
371 As with most things computer related, things break. Email even more so.
372 Typically any errors are going to come from using SMTP as your sending method,
373 which means that if you are having trouble the first place to look is at
374 L<Email::Sender::Simple::SMTP>. This module is just a wrapper for L<Email::Sender::Simple>,
375 so if you get an error on sending, it is likely from there anyway.
377 If you are using SMTP and have troubles sending, whether it is authentication
378 or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
379 if applicable, L<Net::SMTP::SSL> installed.
381 It is very simple to check that you can connect via L<Net::SMTP>, and if you
382 do have sending errors the first thing to do is to write a simple script
383 that attempts to connect. If it works, it is probably something in your
384 configuration so double check there. If it doesn't, well, keep modifying
385 the script and/or your mail server configuration until it does!
389 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
391 =head2 L<Catalyst::Manual> - The Catalyst Manual
393 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
397 J. Shirley <jshirley@gmail.com>
399 Alexander Hartmaier <abraxxa@cpan.org>
407 Daniel Westermann-Clark
409 Simon Elliott <cpan@browsing.co.uk>
413 Lance Brown <lance@bearcircle.net>
415 Devin Austin <dhoss@cpan.org>
417 Chris Nehren <apeiron@cpan.org>
421 Copyright (c) 2007 - 2009
422 the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
427 This library is free software, you can redistribute it and/or modify it under
428 the same terms as Perl itself.