1 package Catalyst::View::Email;
10 use Email::MIME::Creator;
12 use base qw/ Catalyst::View /;
14 our $VERSION = '0.10';
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 if ( exists $self->{content_type} ) {
215 $email->{content_type} ||= $self->{content_type};
218 my $header = $email->{header} || [];
219 push @$header, ('To' => delete $email->{to})
221 push @$header, ('Cc' => delete $email->{cc})
223 push @$header, ('Bcc' => delete $email->{bcc})
225 push @$header, ('From' => delete $email->{from})
227 push @$header, ('Subject' => delete $email->{subject})
228 if $email->{subject};
229 push @$header, ('Content-type' => delete $email->{content_type})
230 if $email->{content_type};
232 my $parts = $email->{parts};
233 my $body = $email->{body};
235 unless ( $parts or $body ) {
236 croak "Can't send email without parts or body, check stash";
239 my %mime = ( header => $header );
241 if ( $parts and ref $parts eq 'ARRAY' ) {
242 $mime{parts} = $parts;
247 if ( $mime{attributes} and not $mime{attributes}->{charset} and
248 $self->{default}->{charset} )
250 $mime{attributes}->{charset} = $self->{default}->{charset};
253 my $message = $self->generate_message( $c, \%mime );
256 my $return = $self->mailer->send($message);
257 # return is a Return::Value object, so this will stringify as the error
258 # in the case of a failure.
259 croak "$return" if !$return;
261 croak "Unable to create message";
265 =item setup_attributes($c, $attr)
267 Merge attributes with the configured defaults. You can override this method to
268 return a structure to pass into L<generate_message> which subsequently
269 passes the return value of this method to Email::MIME->create under the
274 sub setup_attributes {
275 my ( $self, $c, $attrs ) = @_;
277 my $default_content_type = $self->{default}->{content_type};
278 my $default_charset = $self->{default}->{charset};
282 if (exists $attrs->{content_type} && defined $attrs->{content_type} && $attrs->{content_type} ne '') {
283 $c->log->debug('C::V::Email uses specified content_type ' . $attrs->{content_type} . '.') if $c->debug;
284 $e_m_attrs->{content_type} = $attrs->{content_type};
286 elsif (defined $default_content_type && $default_content_type ne '') {
287 $c->log->debug("C::V::Email uses default content_type $default_content_type.") if $c->debug;
288 $e_m_attrs->{content_type} = $default_content_type;
291 if (exists $attrs->{charset} && defined $attrs->{charset} && $attrs->{charset} ne '') {
292 $e_m_attrs->{charset} = $attrs->{charset};
294 elsif (defined $default_charset && $default_charset ne '') {
295 $e_m_attrs->{charset} = $default_charset;
301 =item generate_message($c, $attr)
303 Generate a message part, which should be an L<Email::MIME> object and return it.
305 Takes the attributes, merges with the defaults as necessary and returns a
310 sub generate_message {
311 my ( $self, $c, $attr ) = @_;
313 # setup the attributes (merge with defaults)
314 $attr->{attributes} = $self->setup_attributes($c, $attr->{attributes});
315 return Email::MIME->create(%$attr);
322 =head2 L<Catalyst::View::Email::Template> - Send fancy template emails with Cat
324 =head2 L<Catalyst::Manual> - The Catalyst Manual
326 =head2 L<Catalyst::Manual::Cookbook> - The Catalyst Cookbook
330 J. Shirley <jshirley@gmail.com>
332 Alexander Hartmaier <abraxxa@cpan.org>
340 Daniel Westermann-Clark
342 Simon Elliott <cpan@browsing.co.uk>
348 This library is free software, you can redistribute it and/or modify it under
349 the same terms as Perl itself.