1 package Catalyst::View::Email;
9 use Encode qw(encode decode);
11 use Email::MIME::Creator;
13 use parent 'Catalyst::View';
15 our $VERSION = '0.13';
17 __PACKAGE__->mk_accessors(qw/ mailer /);
21 Catalyst::View::Email - Send Email from Catalyst
25 This module sends out emails from a stash key specified in the
26 configuration settings.
30 WARNING: since version 0.10 the configuration options slightly changed!
32 Use the helper to create your View:
34 $ script/myapp_create.pl view Email Email
36 In your app configuration:
40 # Where to look in the stash for the email information.
41 # 'email' is the default, so you don't have to specify it.
43 # Define the defaults for the mail
45 # Defines the default content type (mime type). Mandatory
46 content_type => 'text/plain',
47 # Defines the default charset for every MIME part with the
49 # According to RFC2049 a MIME part without a charset should
50 # be treated as US-ASCII by the mail client.
51 # If the charset is not set it won't be set for all MIME parts
52 # without an overridden one.
56 # Setup how to send the email
57 # all those options are passed directly to Email::Send
60 # mailer_args is passed directly into Email::Send
62 Host => 'smtp.example.com', # defaults to localhost
63 username => 'username',
64 password => 'password',
72 If you use SMTP and don't specify Host, it will default to localhost and
73 attempt delivery. This often means an email will sit in a queue and
81 content_type => 'text/plain',
87 Sending email is just filling the stash and forwarding to the view:
89 sub controller : Private {
90 my ( $self, $c ) = @_;
92 $c->stash->{email} = {
93 to => 'jshirley@gmail.com',
94 cc => 'abraxxa@cpan.org',
95 bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
96 from => 'no-reply@foobar.com',
97 subject => 'I am a Catalyst generated email',
98 body => 'Body Body Body',
101 $c->forward( $c->view('Email') );
104 Alternatively you can use a more raw interface and specify the headers as
105 an array reference like it is passed to L<Email::MIME::Creator>.
106 Note that you may also mix both syntaxes if you like ours better but need to
107 specify additional header attributes.
108 The attributes are appended to the header array reference without overwriting
111 $c->stash->{email} = {
113 To => 'jshirley@gmail.com',
114 Cc => 'abraxxa@cpan.org',
115 Bcc => join ',', qw/hidden@secret.com hidden2@foobar.com/,
116 From => 'no-reply@foobar.com',
117 Subject => 'Note the capitalization differences',
119 body => qq{Ain't got no body, and nobody cares.},
124 content_type => 'text/plain',
125 disposition => 'attachment',
126 charset => 'US-ASCII',
128 body => qq{Got a body, but didn't get ahead.},
133 =head1 HANDLING ERRORS
135 If the email fails to send, the view will die (throw an exception).
136 After your forward to the view, it is a good idea to check for errors:
138 $c->forward( $c->view('Email') );
140 if ( scalar( @{ $c->error } ) ) {
141 $c->error(0); # Reset the error condition if you need to
142 $c->response->body('Oh noes!');
144 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
147 =head1 USING TEMPLATES FOR EMAIL
149 Now, it's no fun to just send out email using plain strings.
150 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
151 favourite template engine to render the mail body.
159 Validates the base config and creates the L<Email::Send> object for later use
165 my $self = shift->next::method(@_);
167 my $stash_key = $self->{stash_key};
168 croak "$self stash_key isn't defined!"
169 if ($stash_key eq '');
171 my $sender = Email::Send->new;
173 if ( my $mailer = $self->{sender}->{mailer} ) {
174 croak "$mailer is not supported, see Email::Send"
175 unless $sender->mailer_available($mailer);
176 $sender->mailer($mailer);
179 # Default case, run through the most likely options first.
180 for ( qw/SMTP Sendmail Qmail/ ) {
181 $sender->mailer($_) and last if $sender->mailer_available($_);
185 if ( my $args = $self->{sender}->{mailer_args} ) {
186 if ( ref $args eq 'HASH' ) {
187 $sender->mailer_args([ %$args ]);
189 elsif ( ref $args eq 'ARRAY' ) {
190 $sender->mailer_args($args);
192 croak "Invalid mailer_args specified, check pod for Email::Send!";
196 $self->mailer($sender);
203 The process method does the actual processing when the view is dispatched to.
205 This method sets up the email parts and hands off to L<Email::Send> to handle
206 the actual email delivery.
211 my ( $self, $c ) = @_;
213 croak "Unable to send mail, bad mail configuration"
214 unless $self->mailer;
216 my $email = $c->stash->{$self->{stash_key}};
217 croak "Can't send email without a valid email structure"
220 # Default content type
221 if ( exists $self->{content_type} and not $email->{content_type} ) {
222 $email->{content_type} = $self->{content_type};
225 my $header = $email->{header} || [];
226 push @$header, ('To' => delete $email->{to})
228 push @$header, ('Cc' => delete $email->{cc})
230 push @$header, ('Bcc' => delete $email->{bcc})
232 push @$header, ('From' => delete $email->{from})
234 push @$header, ('Subject' => Encode::encode('MIME-Header', delete $email->{subject}))
235 if $email->{subject};
236 push @$header, ('Content-type' => $email->{content_type})
237 if $email->{content_type};
239 my $parts = $email->{parts};
240 my $body = $email->{body};
242 unless ( $parts or $body ) {
243 croak "Can't send email without parts or body, check stash";
246 my %mime = ( header => $header, attributes => {} );
248 if ( $parts and ref $parts eq 'ARRAY' ) {
249 $mime{parts} = $parts;
254 $mime{attributes}->{content_type} = $email->{content_type}
255 if $email->{content_type};
256 if ( $mime{attributes} and not $mime{attributes}->{charset} and
257 $self->{default}->{charset} )
259 $mime{attributes}->{charset} = $self->{default}->{charset};
262 my $message = $self->generate_message( $c, \%mime );
265 my $return = $self->mailer->send($message);
266 # return is a Return::Value object, so this will stringify as the error
267 # in the case of a failure.
268 croak "$return" if !$return;
270 croak "Unable to create message";
274 =item setup_attributes($c, $attr)
276 Merge attributes with the configured defaults. You can override this method to
277 return a structure to pass into L<generate_message> which subsequently
278 passes the return value of this method to Email::MIME->create under the
283 sub setup_attributes {
284 my ( $self, $c, $attrs ) = @_;
286 my $default_content_type = $self->{default}->{content_type};
287 my $default_charset = $self->{default}->{charset};
291 if (exists $attrs->{content_type} && defined $attrs->{content_type} && $attrs->{content_type} ne '') {
292 $c->log->debug('C::V::Email uses specified content_type ' . $attrs->{content_type} . '.') if $c->debug;
293 $e_m_attrs->{content_type} = $attrs->{content_type};
295 elsif (defined $default_content_type && $default_content_type ne '') {
296 $c->log->debug("C::V::Email uses default content_type $default_content_type.") if $c->debug;
297 $e_m_attrs->{content_type} = $default_content_type;
300 if (exists $attrs->{charset} && defined $attrs->{charset} && $attrs->{charset} ne '') {
301 $e_m_attrs->{charset} = $attrs->{charset};
303 elsif (defined $default_charset && $default_charset ne '') {
304 $e_m_attrs->{charset} = $default_charset;
310 =item generate_message($c, $attr)
312 Generate a message part, which should be an L<Email::MIME> object and return it.
314 Takes the attributes, merges with the defaults as necessary and returns a
319 sub generate_message {
320 my ( $self, $c, $attr ) = @_;
322 # setup the attributes (merge with defaults)
323 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
324 return Email::MIME->create(%$attr);
329 =head1 TROUBLESHOOTING
331 As with most things computer related, things break. Email even more so.
332 Typically any errors are going to come from using SMTP as your sending method,
333 which means that if you are having trouble the first place to look is at
334 L<Email::Send::SMTP>. This module is just a wrapper for L<Email::Send>,
335 so if you get an error on sending, it is likely from there anyway.
337 If you are using SMTP and have troubles sending, whether it is authentication
338 or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
339 if applicable, L<Net::SMTP::SSL> installed.
341 It is very simple to check that you can connect via L<Net::SMTP>, and if you
342 do have sending errors the first thing to do is to write a simple script
343 that attempts to connect. If it works, it is probably something in your
344 configuration so double check there. If it doesn't, well, keep modifying
345 the script and/or your mail server configuration until it does!
349 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
351 =head2 L<Catalyst::Manual> - The Catalyst Manual
353 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
357 J. Shirley <jshirley@gmail.com>
359 Alexander Hartmaier <abraxxa@cpan.org>
367 Daniel Westermann-Clark
369 Simon Elliott <cpan@browsing.co.uk>
373 Lance Brown <lance@bearcircle.net>
377 Copyright (c) 2007 - 2009
378 the Catalyst::View::Email L</AUTHORS> and L</CONTRIBUTORS>
383 This library is free software, you can redistribute it and/or modify it under
384 the same terms as Perl itself.