eliminate some false laziness in FS::Misc::send_email vs. msg_template/email.pm send_...
[freeside.git] / FS / FS / msg_template / email.pm
index cc5428b..8fb81f6 100644 (file)
@@ -16,7 +16,7 @@ use HTML::TreeBuilder;
 use Encode;
 
 # needed to send email
-use FS::Misc qw( generate_email );
+use FS::Misc qw( generate_email _sendmail );
 use FS::Conf;
 use Email::Sender::Simple qw( sendmail );
 
@@ -210,6 +210,22 @@ go away in the future.
 
 A L<MIME::Entity> (or arrayref of them) to attach to the message.
 
+=item to_contact_classnum
+
+Set a string containing a comma-separated list.  This list may contain:
+
+- the text "invoice" indicating contacts with invoice_dest flag should
+  be included
+- the text "message" indicating contacts with message_dest flag should
+  be included
+- numbers representing classnum id values for email contact classes.
+  If any classnum are present, emails should only be sent to contact_email
+  addresses where contact_email.classnum contains one of these classes.
+  The classnum 0 also includes where contact_email.classnum IS NULL
+
+If neither 'invoice' nor 'message' has been specified, this method will
+behave as if 'invoice' had been selected
+
 =cut
 
 =back
@@ -290,14 +306,22 @@ sub prepare {
   my @to;
   if ( exists($opt{'to'}) ) {
 
-    @to = split(/\s*,\s*/, $opt{'to'});
+    @to = map { $_->format } Email::Address->parse($opt{'to'});
 
   } elsif ( $cust_main ) {
 
     my $classnum = $opt{'to_contact_classnum'} || '';
     my @classes = ref($classnum) ? @$classnum : split(',', $classnum);
-    # traditional behavior: send to all invoice recipients
-    @classes = ('invoice') unless @classes;
+
+    # There are two e-mail opt-in flags per contact_email address.
+    # If neither 'invoice' nor 'message' has been specified, default
+    # to 'invoice'.
+    #
+    # This default supports the legacy behavior of
+    #    send to all invoice recipients
+    push @classes,'invoice'
+      unless grep {$_ eq 'invoice' || $_ eq 'message'} @classes;
+
     @to = $cust_main->contact_list_email(@classes);
     # not guaranteed to produce contacts, but then customers aren't
     # guaranteed to have email addresses on file. in that case, env_to
@@ -393,14 +417,17 @@ sub prepare {
 
   # effective To: address (not in headers)
   push @to, $self->bcc_addr if $self->bcc_addr;
-  my $env_to = join(', ', @to);
+  my @env_to;
+  foreach my $dest (@to) {
+    push @env_to, map { $_->address } Email::Address->parse($dest);
+  }
 
   my $cust_msg = FS::cust_msg->new({
       'custnum'   => $cust_main ? $cust_main->custnum : '',
       'msgnum'    => $self->msgnum,
       '_date'     => $time,
       'env_from'  => $env_from,
-      'env_to'    => $env_to,
+      'env_to'    => join(',', @env_to),
       'header'    => $message->header_as_string,
       'body'      => $message->body_as_string,
       'error'     => '',
@@ -502,47 +529,27 @@ sub send_prepared {
   my $self = shift;
   my $cust_msg = shift or die "cust_msg required";
 
+  if ( $FS::Misc::DISABLE_ALL_NOTICES ) {
+    warn 'send_prepared() disabled by $FS::Misc::DISABLE_ALL_NOTICES' if $DEBUG;
+    return;
+  }
+
   my $domain = 'example.com';
   if ( $cust_msg->env_from =~ /\@([\w\.\-]+)/ ) {
     $domain = $1;
   }
 
-  my @to = split(/\s*,\s*/, $cust_msg->env_to);
-
-  my %smtp_opt = ( 'host' => $conf->config('smtpmachine'),
-                   'helo' => $domain );
+  # in principle should already be a list of bare addresses, but run it
+  # through Email::Address to make sure
+  my @env_to = map { $_->address } Email::Address->parse($cust_msg->env_to);
 
-  my($port, $enc) = split('-', ($conf->config('smtp-encryption') || '25') );
-  $smtp_opt{'port'} = $port;
-  
-  my $transport;
-  if ( defined($enc) && $enc eq 'starttls' ) {
-    $smtp_opt{$_} = $conf->config("smtp-$_") for qw(username password);
-    $transport = Email::Sender::Transport::SMTP::TLS->new( %smtp_opt );
-  } else {
-    if ( $conf->exists('smtp-username') && $conf->exists('smtp-password') ) {
-      $smtp_opt{"sasl_$_"} = $conf->config("smtp-$_") for qw(username password);     
-    } 
-    $smtp_opt{'ssl'} = 1 if defined($enc) && $enc eq 'tls';
-    $transport = Email::Sender::Transport::SMTP->new( %smtp_opt );
-  }
-
-  warn "$me sending message\n" if $DEBUG;
   my $message = join("\n", $cust_msg->header, $cust_msg->body);
-  local $@;
-  eval {
-    sendmail( $message, { transport => $transport,
-                          from      => $cust_msg->env_from,
-                          to        => \@to })
-  };
-  my $error = '';
-  if(ref($@) and $@->isa('Email::Sender::Failure')) {
-    $error = $@->code.' ' if $@->code;
-    $error .= $@->message;
-  }
-  else {
-    $error = $@;
-  }
+
+  my $error = _sendmail( $message, { 'from'    => $cust_msg->env_from,
+                                     'to'      => \@env_to,
+                                     'domain'  => $domain,
+                                   }
+                       );
 
   $cust_msg->set('error', $error);
   $cust_msg->set('status', $error ? 'failed' : 'sent');
@@ -620,4 +627,3 @@ L<FS::Record>, schema.html from the base documentation.
 =cut
 
 1;
-