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.12';
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',
70 If you use SMTP and don't specify Host, it will default to localhost and
71 attempt delivery. This often means an email will sit in a queue and
79 content_type => 'text/plain',
85 Sending email is just filling the stash and forwarding to the view:
87 sub controller : Private {
88 my ( $self, $c ) = @_;
90 $c->stash->{email} = {
91 to => 'jshirley@gmail.com',
92 cc => 'abraxxa@cpan.org',
93 bcc => [ qw/hidden@secret.com hidden2@foobar.com/ ],
94 from => 'no-reply@foobar.com',
95 subject => 'I am a Catalyst generated email',
96 body => 'Body Body Body',
99 $c->forward( $c->view('Email') );
102 Alternatively you can use a more raw interface and specify the headers as
103 an array reference like it is passed to L<Email::MIME::Creator>.
104 Note that you may also mix both syntaxes if you like ours better but need to
105 specify additional header attributes.
106 The attributes are appended to the header array reference without overwriting
109 $c->stash->{email} = {
111 To => 'jshirley@gmail.com',
112 Cc => 'abraxxa@cpan.org',
113 Bcc => [ qw/hidden@secret.com hidden2@foobar.com/ ],
114 From => 'no-reply@foobar.com',
115 Subject => 'Note the capitalization differences',
117 body => qq{Ain't got no body, and nobody cares.},
122 content_type => 'text/plain',
123 disposition => 'attachment',
124 charset => 'US-ASCII',
126 body => qq{Got a body, but didn't get ahead.},
131 =head1 HANDLING ERRORS
133 If the email fails to send, the view will die (throw an exception).
134 After your forward to the view, it is a good idea to check for errors:
136 $c->forward( $c->view('Email') );
138 if ( scalar( @{ $c->error } ) ) {
139 $c->error(0); # Reset the error condition if you need to
140 $c->response->body('Oh noes!');
142 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
145 =head1 USING TEMPLATES FOR EMAIL
147 Now, it's no fun to just send out email using plain strings.
148 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
149 favourite template engine to render the mail body.
157 Validates the base config and creates the L<Email::Send> object for later use
163 my $self = shift->next::method(@_);
165 my $stash_key = $self->{stash_key};
166 croak "$self stash_key isn't defined!"
167 if ($stash_key eq '');
169 my $sender = Email::Send->new;
171 if ( my $mailer = $self->{sender}->{mailer} ) {
172 croak "$mailer is not supported, see Email::Send"
173 unless $sender->mailer_available($mailer);
174 $sender->mailer($mailer);
177 # Default case, run through the most likely options first.
178 for ( qw/SMTP Sendmail Qmail/ ) {
179 $sender->mailer($_) and last if $sender->mailer_available($_);
183 if ( my $args = $self->{sender}->{mailer_args} ) {
184 if ( ref $args eq 'HASH' ) {
185 $sender->mailer_args([ %$args ]);
187 elsif ( ref $args eq 'ARRAY' ) {
188 $sender->mailer_args($args);
190 croak "Invalid mailer_args specified, check pod for Email::Send!";
194 $self->mailer($sender);
201 The process method does the actual processing when the view is dispatched to.
203 This method sets up the email parts and hands off to L<Email::Send> to handle
204 the actual email delivery.
209 my ( $self, $c ) = @_;
211 croak "Unable to send mail, bad mail configuration"
212 unless $self->mailer;
214 my $email = $c->stash->{$self->{stash_key}};
215 croak "Can't send email without a valid email structure"
218 # Default content type
219 if ( exists $self->{content_type} and not $email->{content_type} ) {
220 $email->{content_type} = $self->{content_type};
223 my $header = $email->{header} || [];
224 push @$header, ('To' => delete $email->{to})
226 push @$header, ('Cc' => delete $email->{cc})
228 push @$header, ('Bcc' => delete $email->{bcc})
230 push @$header, ('From' => delete $email->{from})
232 push @$header, ('Subject' => Encode::encode('MIME-Header', delete $email->{subject}))
233 if $email->{subject};
234 push @$header, ('Content-type' => $email->{content_type})
235 if $email->{content_type};
237 my $parts = $email->{parts};
238 my $body = $email->{body};
240 unless ( $parts or $body ) {
241 croak "Can't send email without parts or body, check stash";
244 my %mime = ( header => $header, attributes => {} );
246 if ( $parts and ref $parts eq 'ARRAY' ) {
247 $mime{parts} = $parts;
252 $mime{attributes}->{content_type} = $email->{content_type}
253 if $email->{content_type};
254 if ( $mime{attributes} and not $mime{attributes}->{charset} and
255 $self->{default}->{charset} )
257 $mime{attributes}->{charset} = $self->{default}->{charset};
260 my $message = $self->generate_message( $c, \%mime );
263 my $return = $self->mailer->send($message);
264 # return is a Return::Value object, so this will stringify as the error
265 # in the case of a failure.
266 croak "$return" if !$return;
268 croak "Unable to create message";
272 =item setup_attributes($c, $attr)
274 Merge attributes with the configured defaults. You can override this method to
275 return a structure to pass into L<generate_message> which subsequently
276 passes the return value of this method to Email::MIME->create under the
281 sub setup_attributes {
282 my ( $self, $c, $attrs ) = @_;
284 my $default_content_type = $self->{default}->{content_type};
285 my $default_charset = $self->{default}->{charset};
289 if (exists $attrs->{content_type} && defined $attrs->{content_type} && $attrs->{content_type} ne '') {
290 $c->log->debug('C::V::Email uses specified content_type ' . $attrs->{content_type} . '.') if $c->debug;
291 $e_m_attrs->{content_type} = $attrs->{content_type};
293 elsif (defined $default_content_type && $default_content_type ne '') {
294 $c->log->debug("C::V::Email uses default content_type $default_content_type.") if $c->debug;
295 $e_m_attrs->{content_type} = $default_content_type;
298 if (exists $attrs->{charset} && defined $attrs->{charset} && $attrs->{charset} ne '') {
299 $e_m_attrs->{charset} = $attrs->{charset};
301 elsif (defined $default_charset && $default_charset ne '') {
302 $e_m_attrs->{charset} = $default_charset;
308 =item generate_message($c, $attr)
310 Generate a message part, which should be an L<Email::MIME> object and return it.
312 Takes the attributes, merges with the defaults as necessary and returns a
317 sub generate_message {
318 my ( $self, $c, $attr ) = @_;
320 # setup the attributes (merge with defaults)
321 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
322 return Email::MIME->create(%$attr);
327 =head1 TROUBLESHOOTING
329 As with most things computer related, things break. Email even more so.
330 Typically any errors are going to come from using SMTP as your sending method,
331 which means that if you are having trouble the first place to look is at
332 L<Email::Send::SMTP>. This module is just a wrapper for L<Email::Send>,
333 so if you get an error on sending, it is likely from there anyway.
335 If you are using SMTP and have troubles sending, whether it is authentication
336 or a very bland "Can't send" message, make sure that you have L<Net::SMTP> and,
337 if applicable, L<Net::SMTP::SSL> installed.
339 It is very simple to check that you can connect via L<Net::SMTP>, and if you
340 do have sending errors the first thing to do is to write a simple script
341 that attempts to connect. If it works, it is probably something in your
342 configuration so double check there. If it doesn't, well, keep modifying
343 the script and/or your mail server configuration until it does!
347 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
349 =head2 L<Catalyst::Manual> - The Catalyst Manual
351 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
355 J. Shirley <jshirley@gmail.com>
357 Alexander Hartmaier <abraxxa@cpan.org>
365 Daniel Westermann-Clark
367 Simon Elliott <cpan@browsing.co.uk>
373 This library is free software, you can redistribute it and/or modify it under
374 the same terms as Perl itself.