OSDN Git Service

Plugin::Sendmail: add _encode_header()
[newslash/newslash.git] / src / newslash_web / lib / Newslash / Plugin / Sendmail.pm
index 864b118..ccd2691 100644 (file)
@@ -1,6 +1,11 @@
 package Newslash::Plugin::Sendmail;
 use Mojo::Base 'Mojolicious::Plugin';
 use Email::Valid;
+use Email::Simple;
+use Email::Sender::Simple;
+use Email::Sender::Transport::SMTP;
+use Encode;
+use Data::Dumper;
 
 has 'last_error';
 has 'app';
@@ -8,10 +13,58 @@ has 'app';
 sub register {
     my ($self, $app, $conf) = @_;
     $self->app($app);
-    $app->helper(sendmail => sub { $self->sendmail(@_); });
+    $app->helper(sendmail => sub { shift; $self->sendmail(@_); });
 
     # default config values
-    #my $cnf = $app->config->{Sendmail} ||= {};
+    my $cnf = $app->config->{Sendmail} ||= {};
+
+    $cnf->{default_from} ||= 'admin@example.com';
+    $cnf->{smtp_host} ||= 'example.com';
+    $cnf->{smtp_port} ||= '25';
+}
+
+sub _encode_header {
+    my ($self, $text) = @_;
+    my $encoded = encode('MIME-Header-ISO_2022_JP', $text);
+    $encoded =~ s/\n//g;
+    return $encoded;
+}
+
+sub _send {
+    my ($self, $from, $to, $title, $body) = @_;
+
+    # create header and body
+    my $header = [
+                  From    => $self->_encode_header($from),
+                  To      => $self->_encode_header($to),
+                  Subject => $self->_encode_header($title),
+                  'Content-Type' => 'text/plain; charset=ISO-2022-JP',
+                  'Content-Transfer-Encoding' => '7bit',
+                 ];
+
+    my $encoded_body = encode('iso-2022-jp', $body);
+
+    # create message
+    my $email = Email::Simple->create(header => $header,
+                                      body => $encoded_body);
+
+    # create transport
+    my $smtp_host = $self->app->config->{Sendmail}->{smtp_host};
+    my $smtp_port = $self->app->config->{Sendmail}->{smtp_port};
+    my $smtp_timeout = $self->app->config->{Sendmail}->{smtp_timeout};
+    my $transport = Email::Sender::Transport::SMTP->new({ host => $smtp_host,
+                                                          port => $smtp_port,
+                                                          timeout => $smtp_timeout,
+                                                        });
+
+    # send message
+    my $rs = eval { Email::Sender::Simple->send($email, {transport => $transport}) };
+    if (!$rs) {
+        my ($msg, $code) = ($@->message, $@->code);
+        $self->app->log->error("Sendmail: sendmail error. $msg ($code)");
+        return;
+    }
+    return 1;
 }
 
 sub _render {
@@ -43,15 +96,18 @@ sub sendmail {
         $recipient_user = $args->{to};
     }
     elsif (ref($args->{to}) eq "ARRAY") {
-        # 複数ターゲットに送信
+        # TODO
     }
     elsif (ref($args->{to}) eq "") {
         if ($args->{to} =~ m/^\d+$/) {
             # uid is given
             $recipient_user = $self->app->model('users')->select(uid => $args->{to});
         }
-        elsif (Email::Valid->address($args->{to})) {
-            $to_address = $args->{to};
+        else {
+            my $encoded_to = encode('MIME-Header-ISO_2022_JP', $args->{to});
+            if (Email::Valid->address($encoded_to)) {
+                $to_address = $args->{to};
+            }
         }
     }
 
@@ -64,18 +120,49 @@ sub sendmail {
         return;
     }
 
+
+    # check from address
+    my $from_address = $args->{from} || $self->app->config->{Sendmail}->{default_from};
+
+    # create title and body
+    my $title = $args->{title};
+    my $body = $args->{body};
+
     if ($args->{template}) {
         # render template
-        my ($title, $body) = eval { $self->_render($args->{template},
+        ($title, $body) = eval { $self->_render($args->{template},
                                                    $args->{params}); };
         if (!$title) {
             $self->app->log->error("Sendmail: template error: $@");
             return;
         }
+    }
+
+    if (!$title) {
+        $self->app->log->error("Sendmail: no title given. to: $to_address");
+        return;
+    }
+
+    if (!$body) {
+        $self->app->log->error("Sendmail: no body given. title: $title, to: $to_address");
+        return;
+    }
 
+    # if render only mode, return items.
+    if ($args->{render_only}) {
+        return wantarray ? ($from_address, $to_address, $title, $body) : { from => $from_address,
+                                                                             to => $to_address,
+                                                                             title => $title,
+                                                                             body => $body };
     }
 
     # send
+    my $rs = $self->_send($from_address, $to_address, $title, $body);
+
+    if (!$rs) {
+        $self->app->log->error("Sendmail: fail to send mail. title: $title, to: $to_address");
+        return;
+    }
 
     return 1;
 }