github.com/goravel/framework@v1.13.9/mail/application.go (about) 1 package mail 2 3 import ( 4 "crypto/tls" 5 "fmt" 6 "net/smtp" 7 8 "github.com/jordan-wright/email" 9 10 "github.com/goravel/framework/contracts/config" 11 "github.com/goravel/framework/contracts/mail" 12 queuecontract "github.com/goravel/framework/contracts/queue" 13 ) 14 15 type Application struct { 16 clone int 17 config config.Config 18 content mail.Content 19 from mail.From 20 queue queuecontract.Queue 21 attaches []string 22 bcc []string 23 cc []string 24 to []string 25 } 26 27 func NewApplication(config config.Config, queue queuecontract.Queue) *Application { 28 return &Application{ 29 config: config, 30 queue: queue, 31 } 32 } 33 34 func (r *Application) Content(content mail.Content) mail.Mail { 35 instance := r.instance() 36 instance.content = content 37 38 return instance 39 } 40 41 func (r *Application) From(from mail.From) mail.Mail { 42 instance := r.instance() 43 instance.from = from 44 45 return instance 46 } 47 48 func (r *Application) To(to []string) mail.Mail { 49 instance := r.instance() 50 instance.to = to 51 52 return instance 53 } 54 55 func (r *Application) Cc(cc []string) mail.Mail { 56 instance := r.instance() 57 instance.cc = cc 58 59 return instance 60 } 61 62 func (r *Application) Bcc(bcc []string) mail.Mail { 63 instance := r.instance() 64 instance.bcc = bcc 65 66 return instance 67 } 68 69 func (r *Application) Attach(files []string) mail.Mail { 70 instance := r.instance() 71 instance.attaches = files 72 73 return instance 74 } 75 76 func (r *Application) Send() error { 77 return SendMail(r.config, r.content.Subject, r.content.Html, r.from.Address, r.from.Name, r.to, r.cc, r.bcc, r.attaches) 78 } 79 80 func (r *Application) Queue(queue *mail.Queue) error { 81 job := r.queue.Job(NewSendMailJob(r.config), []queuecontract.Arg{ 82 {Value: r.content.Subject, Type: "string"}, 83 {Value: r.content.Html, Type: "string"}, 84 {Value: r.from.Address, Type: "string"}, 85 {Value: r.from.Name, Type: "string"}, 86 {Value: r.to, Type: "[]string"}, 87 {Value: r.cc, Type: "[]string"}, 88 {Value: r.bcc, Type: "[]string"}, 89 {Value: r.attaches, Type: "[]string"}, 90 }) 91 if queue != nil { 92 if queue.Connection != "" { 93 job.OnConnection(queue.Connection) 94 } 95 if queue.Queue != "" { 96 job.OnQueue(queue.Queue) 97 } 98 } 99 100 return job.Dispatch() 101 } 102 103 func (r *Application) instance() *Application { 104 if r.clone == 0 { 105 return &Application{ 106 clone: 1, 107 config: r.config, 108 queue: r.queue, 109 } 110 } 111 112 return r 113 } 114 115 func SendMail(config config.Config, subject, html string, fromAddress, fromName string, to, cc, bcc, attaches []string) error { 116 e := email.NewEmail() 117 if fromAddress == "" { 118 e.From = fmt.Sprintf("%s <%s>", config.GetString("mail.from.name"), config.GetString("mail.from.address")) 119 } else { 120 e.From = fmt.Sprintf("%s <%s>", fromName, fromAddress) 121 } 122 123 e.To = to 124 if len(e.Bcc) > 0 { 125 e.Bcc = bcc 126 } 127 if len(e.Cc) > 0 { 128 e.Cc = cc 129 } 130 e.Subject = subject 131 e.HTML = []byte(html) 132 133 for _, attach := range attaches { 134 if _, err := e.AttachFile(attach); err != nil { 135 return err 136 } 137 } 138 139 port := config.GetInt("mail.port") 140 switch port { 141 case 465: 142 return e.SendWithTLS(fmt.Sprintf("%s:%d", config.GetString("mail.host"), config.GetInt("mail.port")), 143 LoginAuth(config.GetString("mail.username"), config.GetString("mail.password")), 144 &tls.Config{ServerName: config.GetString("mail.host")}) 145 case 587: 146 return e.SendWithStartTLS(fmt.Sprintf("%s:%d", config.GetString("mail.host"), config.GetInt("mail.port")), 147 LoginAuth(config.GetString("mail.username"), config.GetString("mail.password")), 148 &tls.Config{ServerName: config.GetString("mail.host")}) 149 default: 150 return e.Send(fmt.Sprintf("%s:%d", config.GetString("mail.host"), port), 151 LoginAuth(config.GetString("mail.username"), config.GetString("mail.password"))) 152 } 153 } 154 155 type loginAuth struct { 156 username, password string 157 } 158 159 func LoginAuth(username, password string) smtp.Auth { 160 return &loginAuth{username, password} 161 } 162 163 func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { 164 return "LOGIN", []byte(a.username), nil 165 } 166 167 func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { 168 if more { 169 switch string(fromServer) { 170 case "Username:": 171 return []byte(a.username), nil 172 case "Password:": 173 return []byte(a.password), nil 174 } 175 } 176 return nil, nil 177 }