// Send send message through the client func Send(c *smtp.Client, message *Message) (err error) { data, err := message.RenderData() if err != nil { return } if err = c.Reset(); err != nil { return } if err = c.Mail(message.From); err != nil { return } if err = addRcpt(c, message.To); err != nil { return } if err = addRcpt(c, message.Cc); err != nil { return } if err = addRcpt(c, message.Bcc); err != nil { return } w, err := c.Data() if err != nil { return } defer w.Close() _, err = w.Write(data) return }
// Receive message and deliver them to their recipients. Due to the complicated // algorithm for message delivery, the body of the method is broken up into a // sequence of labeled sections. func (h *Host) run() { defer close(h.stop) var ( m *Message hostname string c *smtp.Client err error tries int duration = time.Minute ) receive: if m == nil { m = h.receiveMessage() if m == nil { goto shutdown } h.log.Info("message received in queue") } hostname, err = h.parseHostname(m.From) if err != nil { h.log.Error(err.Error()) goto cleanup } deliver: if c == nil { h.log.Debug("connecting to mail server") c, err = h.connectToMailServer(hostname) if c == nil { if err != nil { h.log.Error(err) goto wait } else { goto shutdown } } h.log.Debug("connection established") } err = h.deliverToMailServer(c, m) if err != nil { h.log.Error(err) if _, ok := err.(syscall.Errno); ok { c = nil goto deliver } if e, ok := err.(*textproto.Error); ok { if e.Code >= 400 && e.Code <= 499 { c.Close() c = nil goto wait } c.Reset() } h.log.Error(err.Error()) goto cleanup } h.log.Info("message delivered successfully") cleanup: h.log.Debug("deleting message from disk") err = h.storage.DeleteMessage(m) if err != nil { h.log.Error(err.Error()) } m = nil tries = 0 goto receive wait: // We differ a tiny bit from the RFC spec here but this should work well // enough - the goal is to retry lots of times early on and space out the // remaining attempts as time goes on. (Roughly 48 hours total.) switch { case tries < 8: duration *= 2 case tries < 18: default: h.log.Error("maximum retry count exceeded") goto cleanup } select { case <-h.stop: case <-time.After(duration): goto receive } tries++ shutdown: h.log.Debug("shutting down") if c != nil { c.Close() } }
func (mailer *RecMailer) processOneRecord(id string, email string, w io.Writer, smtpClient *smtp.Client, httpClient *http.Client) int { var ( recResponse RecResponse ) fullUrl := fmt.Sprintf(mailer.Config.RecUrl, id) resp, err := httpClient.Get(fullUrl) if err != nil { fmt.Fprintf(w, "Unable to get URL %s\n", fullUrl) fmt.Println(err) resp.Body.Close() return 1 } readBytes, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { fmt.Fprintf(w, "Unable to read from URL %s\n", fullUrl) return 1 } err = json.Unmarshal(readBytes, &recResponse) if err != nil { fmt.Fprintf(w, "Unable to parse JSON http resp for user %s\n", id) fmt.Println(err) return 1 } if len(recResponse.Suggestions) == 0 { fmt.Fprintf(w, "No recommendations for user %s\n", id) return 1 } // If there's no thumbnail, use a blank gif for recIndex := 0; recIndex < len(recResponse.Suggestions); recIndex++ { if len(recResponse.Suggestions[recIndex].Thumbnail.Url) == 0 { recResponse.Suggestions[recIndex].Thumbnail.Url = "http://graphics8.nytimes.com/images/misc/spacer.gif" } } //emails := make([]string, 1) //emails[0] = email localTime := time.Now() dateStr := localTime.Format(time.RFC1123Z) edata := new(EmailData) edata.FromAddress = mailer.Config.EnvelopeFrom edata.ToAddress = email edata.Subject = "Recommendations for you" edata.RecResponse = recResponse edata.Date = dateStr edata.HumanDate = fmt.Sprintf("%s %d, %d", localTime.Month(), localTime.Day(), localTime.Year()) buff := new(bytes.Buffer) mailer.Template.Execute(buff, edata) //err = smtp.SendMail(mailer.Config.SmtpServer, nil, mailer.Config.SmtpFrom, emails, buff.Bytes()) errReset := smtpClient.Reset() if errReset != nil { fmt.Printf("There was an error sending for user %s\n", id) fmt.Println(errReset) return 1 } errMail := smtpClient.Mail(mailer.Config.SmtpFrom) if errMail != nil { fmt.Printf("There was an error sending for user %s\n", id) fmt.Println(errMail) return 1 } errRcpt := smtpClient.Rcpt(email) if errRcpt != nil { fmt.Printf("There was an error sending for user %s\n", id) fmt.Println(errRcpt) return 1 } smtpWriter, errData := smtpClient.Data() if errData != nil { fmt.Printf("There was an error sending for user %s\n", id) fmt.Println(errData) return 1 } smtpWriter.Write(buff.Bytes()) smtpWriter.Close() /* if err != nil { fmt.Printf("There was an error sending for user %s\n", id) fmt.Println(err) return 1 } */ fmt.Fprintf(w, "Success for %s, %s\n", id, email) return 0 }