1 package Catalyst::View::Email;
10 use Email::MIME::Creator;
12 use base qw/ Catalyst::View /;
14 our $VERSION = '0.11';
16 __PACKAGE__->mk_accessors(qw/ mailer /);
20 Catalyst::View::Email - Send Email from Catalyst
24 This module sends out emails from a stash key specified in the
25 configuration settings.
29 WARNING: since version 0.10 the configuration options slightly changed!
31 Use the helper to create your View:
33 $ script/myapp_create.pl view Email Email
35 In your app configuration (example in L<YAML>):
38 # Where to look in the stash for the email information.
39 # 'email' is the default, so you don't have to specify it.
41 # Define the defaults for the mail
43 # Defines the default content type (mime type).
45 content_type: text/plain
46 # Defines the default charset for every MIME part with the content
48 # According to RFC2049 a MIME part without a charset should
49 # be treated as US-ASCII by the mail client.
50 # If the charset is not set it won't be set for all MIME parts
51 # without an overridden one.
54 # Setup how to send the email
55 # all those options are passed directly to Email::Send
58 # mailer_args is passed directly into Email::Send
60 Host: smtp.example.com # defaults to localhost
66 If you use SMTP and don't specify Host, it will default to localhost and
67 attempt delivery. This often means an email will sit in a queue and
75 content_type => 'text/plain',
81 Sending email is just filling the stash and forwarding to the view:
83 sub controller : Private {
84 my ( $self, $c ) = @_;
86 $c->stash->{email} = {
87 to => 'jshirley@gmail.com',
88 cc => 'abraxxa@cpan.org',
89 bcc => [ qw/hidden@secret.com hidden2@foobar.com/ ],
90 from => 'no-reply@foobar.com',
91 subject => 'I am a Catalyst generated email',
92 body => 'Body Body Body',
95 $c->forward( $c->view('Email') );
98 Alternatively you can use a more raw interface and specify the headers as
99 an array reference like it is passed to L<Email::MIME::Creator>.
100 Note that you may also mix both syntaxes if you like ours better but need to
101 specify additional header attributes.
102 The attributes are appended to the header array reference without overwriting
105 $c->stash->{email} = {
107 To => 'jshirley@gmail.com',
108 Cc => 'abraxxa@cpan.org',
109 Bcc => [ qw/hidden@secret.com hidden2@foobar.com/ ],
110 From => 'no-reply@foobar.com',
111 Subject => 'Note the capitalization differences',
113 body => qq{Ain't got no body, and nobody cares.},
118 content_type => 'text/plain',
119 disposition => 'attachment',
120 charset => 'US-ASCII',
122 body => qq{Got a body, but didn't get ahead.},
127 =head1 HANDLING ERRORS
129 If the email fails to send, the view will die (throw an exception).
130 After your forward to the view, it is a good idea to check for errors:
132 $c->forward( $c->view('Email') );
134 if ( scalar( @{ $c->error } ) ) {
135 $c->error(0); # Reset the error condition if you need to
136 $c->response->body('Oh noes!');
138 $c->response->body('Email sent A-OK! (At least as far as we can tell)');
141 =head1 USING TEMPLATES FOR EMAIL
143 Now, it's no fun to just send out email using plain strings.
144 Take a look at L<Catalyst::View::Email::Template> to see how you can use your
145 favourite template engine to render the mail body.
153 Validates the base config and creates the L<Email::Send> object for later use
159 my $self = shift->next::method(@_);
161 my $stash_key = $self->{stash_key};
162 croak "$self stash_key isn't defined!"
163 if ($stash_key eq '');
165 my $sender = Email::Send->new;
167 if ( my $mailer = $self->{sender}->{mailer} ) {
168 croak "$mailer is not supported, see Email::Send"
169 unless $sender->mailer_available($mailer);
170 $sender->mailer($mailer);
173 # Default case, run through the most likely options first.
174 for ( qw/SMTP Sendmail Qmail/ ) {
175 $sender->mailer($_) and last if $sender->mailer_available($_);
179 if ( my $args = $self->{sender}->{mailer_args} ) {
180 if ( ref $args eq 'HASH' ) {
181 $sender->mailer_args([ %$args ]);
183 elsif ( ref $args eq 'ARRAY' ) {
184 $sender->mailer_args($args);
186 croak "Invalid mailer_args specified, check pod for Email::Send!";
190 $self->mailer($sender);
197 The process method does the actual processing when the view is dispatched to.
199 This method sets up the email parts and hands off to L<Email::Send> to handle
200 the actual email delivery.
205 my ( $self, $c ) = @_;
207 croak "Unable to send mail, bad mail configuration"
208 unless $self->mailer;
210 my $email = $c->stash->{$self->{stash_key}};
211 croak "Can't send email without a valid email structure"
214 # Default content type
215 if ( exists $self->{content_type} and not $email->{content_type} ) {
216 $email->{content_type} = $self->{content_type};
219 my $header = $email->{header} || [];
220 push @$header, ('To' => delete $email->{to})
222 push @$header, ('Cc' => delete $email->{cc})
224 push @$header, ('Bcc' => delete $email->{bcc})
226 push @$header, ('From' => delete $email->{from})
228 push @$header, ('Subject' => delete $email->{subject})
229 if $email->{subject};
230 push @$header, ('Content-type' => $email->{content_type})
231 if $email->{content_type};
233 my $parts = $email->{parts};
234 my $body = $email->{body};
236 unless ( $parts or $body ) {
237 croak "Can't send email without parts or body, check stash";
240 my %mime = ( header => $header, attributes => {} );
242 if ( $parts and ref $parts eq 'ARRAY' ) {
243 $mime{parts} = $parts;
248 $mime{attributes}->{content_type} = $email->{content_type}
249 if $email->{content_type};
250 if ( $mime{attributes} and not $mime{attributes}->{charset} and
251 $self->{default}->{charset} )
253 $mime{attributes}->{charset} = $self->{default}->{charset};
256 my $message = $self->generate_message( $c, \%mime );
259 my $return = $self->mailer->send($message);
260 # return is a Return::Value object, so this will stringify as the error
261 # in the case of a failure.
262 croak "$return" if !$return;
264 croak "Unable to create message";
268 =item setup_attributes($c, $attr)
270 Merge attributes with the configured defaults. You can override this method to
271 return a structure to pass into L<generate_message> which subsequently
272 passes the return value of this method to Email::MIME->create under the
277 sub setup_attributes {
278 my ( $self, $c, $attrs ) = @_;
280 my $default_content_type = $self->{default}->{content_type};
281 my $default_charset = $self->{default}->{charset};
285 if (exists $attrs->{content_type} && defined $attrs->{content_type} && $attrs->{content_type} ne '') {
286 $c->log->debug('C::V::Email uses specified content_type ' . $attrs->{content_type} . '.') if $c->debug;
287 $e_m_attrs->{content_type} = $attrs->{content_type};
289 elsif (defined $default_content_type && $default_content_type ne '') {
290 $c->log->debug("C::V::Email uses default content_type $default_content_type.") if $c->debug;
291 $e_m_attrs->{content_type} = $default_content_type;
294 if (exists $attrs->{charset} && defined $attrs->{charset} && $attrs->{charset} ne '') {
295 $e_m_attrs->{charset} = $attrs->{charset};
297 elsif (defined $default_charset && $default_charset ne '') {
298 $e_m_attrs->{charset} = $default_charset;
304 =item generate_message($c, $attr)
306 Generate a message part, which should be an L<Email::MIME> object and return it.
308 Takes the attributes, merges with the defaults as necessary and returns a
313 sub generate_message {
314 my ( $self, $c, $attr ) = @_;
316 # setup the attributes (merge with defaults)
317 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
318 return Email::MIME->create(%$attr);
325 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
327 =head2 L<Catalyst::Manual> - The Catalyst Manual
329 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
333 J. Shirley <jshirley@gmail.com>
335 Alexander Hartmaier <abraxxa@cpan.org>
343 Daniel Westermann-Clark
345 Simon Elliott <cpan@browsing.co.uk>
351 This library is free software, you can redistribute it and/or modify it under
352 the same terms as Perl itself.