github.com/astaxie/beego@v1.12.3/logs/smtp.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package logs
    16  
    17  import (
    18  	"crypto/tls"
    19  	"encoding/json"
    20  	"fmt"
    21  	"net"
    22  	"net/smtp"
    23  	"strings"
    24  	"time"
    25  )
    26  
    27  // SMTPWriter implements LoggerInterface and is used to send emails via given SMTP-server.
    28  type SMTPWriter struct {
    29  	Username           string   `json:"username"`
    30  	Password           string   `json:"password"`
    31  	Host               string   `json:"host"`
    32  	Subject            string   `json:"subject"`
    33  	FromAddress        string   `json:"fromAddress"`
    34  	RecipientAddresses []string `json:"sendTos"`
    35  	Level              int      `json:"level"`
    36  }
    37  
    38  // NewSMTPWriter create smtp writer.
    39  func newSMTPWriter() Logger {
    40  	return &SMTPWriter{Level: LevelTrace}
    41  }
    42  
    43  // Init smtp writer with json config.
    44  // config like:
    45  //	{
    46  //		"username":"example@gmail.com",
    47  //		"password:"password",
    48  //		"host":"smtp.gmail.com:465",
    49  //		"subject":"email title",
    50  //		"fromAddress":"from@example.com",
    51  //		"sendTos":["email1","email2"],
    52  //		"level":LevelError
    53  //	}
    54  func (s *SMTPWriter) Init(jsonconfig string) error {
    55  	return json.Unmarshal([]byte(jsonconfig), s)
    56  }
    57  
    58  func (s *SMTPWriter) getSMTPAuth(host string) smtp.Auth {
    59  	if len(strings.Trim(s.Username, " ")) == 0 && len(strings.Trim(s.Password, " ")) == 0 {
    60  		return nil
    61  	}
    62  	return smtp.PlainAuth(
    63  		"",
    64  		s.Username,
    65  		s.Password,
    66  		host,
    67  	)
    68  }
    69  
    70  func (s *SMTPWriter) sendMail(hostAddressWithPort string, auth smtp.Auth, fromAddress string, recipients []string, msgContent []byte) error {
    71  	client, err := smtp.Dial(hostAddressWithPort)
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	host, _, _ := net.SplitHostPort(hostAddressWithPort)
    77  	tlsConn := &tls.Config{
    78  		InsecureSkipVerify: true,
    79  		ServerName:         host,
    80  	}
    81  	if err = client.StartTLS(tlsConn); err != nil {
    82  		return err
    83  	}
    84  
    85  	if auth != nil {
    86  		if err = client.Auth(auth); err != nil {
    87  			return err
    88  		}
    89  	}
    90  
    91  	if err = client.Mail(fromAddress); err != nil {
    92  		return err
    93  	}
    94  
    95  	for _, rec := range recipients {
    96  		if err = client.Rcpt(rec); err != nil {
    97  			return err
    98  		}
    99  	}
   100  
   101  	w, err := client.Data()
   102  	if err != nil {
   103  		return err
   104  	}
   105  	_, err = w.Write(msgContent)
   106  	if err != nil {
   107  		return err
   108  	}
   109  
   110  	err = w.Close()
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	return client.Quit()
   116  }
   117  
   118  // WriteMsg write message in smtp writer.
   119  // it will send an email with subject and only this message.
   120  func (s *SMTPWriter) WriteMsg(when time.Time, msg string, level int) error {
   121  	if level > s.Level {
   122  		return nil
   123  	}
   124  
   125  	hp := strings.Split(s.Host, ":")
   126  
   127  	// Set up authentication information.
   128  	auth := s.getSMTPAuth(hp[0])
   129  
   130  	// Connect to the server, authenticate, set the sender and recipient,
   131  	// and send the email all in one step.
   132  	contentType := "Content-Type: text/plain" + "; charset=UTF-8"
   133  	mailmsg := []byte("To: " + strings.Join(s.RecipientAddresses, ";") + "\r\nFrom: " + s.FromAddress + "<" + s.FromAddress +
   134  		">\r\nSubject: " + s.Subject + "\r\n" + contentType + "\r\n\r\n" + fmt.Sprintf(".%s", when.Format("2006-01-02 15:04:05")) + msg)
   135  
   136  	return s.sendMail(s.Host, auth, s.FromAddress, s.RecipientAddresses, mailmsg)
   137  }
   138  
   139  // Flush implementing method. empty.
   140  func (s *SMTPWriter) Flush() {
   141  }
   142  
   143  // Destroy implementing method. empty.
   144  func (s *SMTPWriter) Destroy() {
   145  }
   146  
   147  func init() {
   148  	Register(AdapterMail, newSMTPWriter)
   149  }