Sending invoice mails with attachement
This commit is contained in:
		
							
								
								
									
										18
									
								
								cmd/micro/invoice/email-templates/invoice.html.gohtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								cmd/micro/invoice/email-templates/invoice.html.gohtml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
{{ define "body" }}
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
    <head>
 | 
			
		||||
        <meta name="viewport" content="width=device-width">
 | 
			
		||||
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 | 
			
		||||
    </head>
 | 
			
		||||
    <body>
 | 
			
		||||
        <p>Hello:</p>
 | 
			
		||||
        <p>Please find your invoice attached.</p>
 | 
			
		||||
        <p>
 | 
			
		||||
            --
 | 
			
		||||
            <br>
 | 
			
		||||
            Widget Co.
 | 
			
		||||
        </p>
 | 
			
		||||
    </body>
 | 
			
		||||
</html>
 | 
			
		||||
{{ end }}
 | 
			
		||||
							
								
								
									
										9
									
								
								cmd/micro/invoice/email-templates/invoice.plain.gohtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cmd/micro/invoice/email-templates/invoice.plain.gohtml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
{{ define "body" }}
 | 
			
		||||
Hello:
 | 
			
		||||
 | 
			
		||||
Please find your invoice attached.
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
Widget Co.
 | 
			
		||||
{{ end }}
 | 
			
		||||
 | 
			
		||||
@ -24,30 +24,30 @@ func (app *application) CreateAndSendInvoice(w http.ResponseWriter, r *http.Requ
 | 
			
		||||
	// receive json
 | 
			
		||||
	var order Order
 | 
			
		||||
 | 
			
		||||
	order.ID = 100
 | 
			
		||||
	order.Email = "me@here.com"
 | 
			
		||||
	order.FirstName = "John"
 | 
			
		||||
	order.LastName = "Smith"
 | 
			
		||||
	order.Quantity = 1
 | 
			
		||||
	order.Amount = 1000
 | 
			
		||||
	order.Product = "Widget"
 | 
			
		||||
	order.CreatedAt = time.Now()
 | 
			
		||||
	// err = app.readJSON(w, r, &order)
 | 
			
		||||
	// if err != nil {
 | 
			
		||||
	// 	app.badRequest(w, r, err)
 | 
			
		||||
	// 	return
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	// generate a pdf invoice
 | 
			
		||||
	err := app.createInvoicePDF(order)
 | 
			
		||||
	err := app.readJSON(w, r, &order)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.badRequest(w, r, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create mail
 | 
			
		||||
	// generate a pdf invoice
 | 
			
		||||
	err = app.createInvoicePDF(order)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.badRequest(w, r, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create mail attachment
 | 
			
		||||
	attachments := []string{
 | 
			
		||||
		fmt.Sprintf("./invoices/%d.pdf", order.ID),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// send mail with attachment
 | 
			
		||||
	err = app.SendMail("info@widgets.com", order.Email, "Your invoice", "invoice", attachments, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.badRequest(w, r, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// send response
 | 
			
		||||
	var resp JSONResponse
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,6 @@ func (app *application) routes() http.Handler {
 | 
			
		||||
		MaxAge:           300,
 | 
			
		||||
	}))
 | 
			
		||||
 | 
			
		||||
	mux.Get("/invoice/create-and-send", app.CreateAndSendInvoice)
 | 
			
		||||
	mux.Post("/invoice/create-and-send", app.CreateAndSendInvoice)
 | 
			
		||||
	return mux
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										88
									
								
								cmd/micro/invoice/mailer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								cmd/micro/invoice/mailer.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"embed"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"text/template"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	mail "github.com/xhit/go-simple-mail/v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:embed email-templates
 | 
			
		||||
var emailTemplateFS embed.FS
 | 
			
		||||
 | 
			
		||||
func (app *application) SendMail(
 | 
			
		||||
	from, to, subject, tmpl string,
 | 
			
		||||
	attachments []string,
 | 
			
		||||
	data interface{},
 | 
			
		||||
) error {
 | 
			
		||||
	templateToRender := fmt.Sprintf("email-templates/%s.html.gohtml", tmpl)
 | 
			
		||||
 | 
			
		||||
	t, err := template.New("email-html").ParseFS(emailTemplateFS, templateToRender)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var tpl bytes.Buffer
 | 
			
		||||
	if err = t.ExecuteTemplate(&tpl, "body", data); err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	formattedMessage := tpl.String()
 | 
			
		||||
 | 
			
		||||
	templateToRender = fmt.Sprintf("email-templates/%s.plain.gohtml", tmpl)
 | 
			
		||||
	t, err = template.New("email-plain").ParseFS(emailTemplateFS, templateToRender)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if err = t.ExecuteTemplate(&tpl, "body", data); err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	plainMessage := tpl.String()
 | 
			
		||||
 | 
			
		||||
	app.infoLog.Println(formattedMessage, plainMessage)
 | 
			
		||||
 | 
			
		||||
	// send the mail
 | 
			
		||||
	server := mail.NewSMTPClient()
 | 
			
		||||
	server.Host = app.config.smtp.host
 | 
			
		||||
	server.Port = app.config.smtp.port
 | 
			
		||||
	// NOTE: not needed for MailHog
 | 
			
		||||
	// server.Username = app.config.smtp.username
 | 
			
		||||
	// server.Password = app.config.smtp.password
 | 
			
		||||
	// server.Encryption = mail.EncryptionTLS
 | 
			
		||||
	server.KeepAlive = false
 | 
			
		||||
	server.ConnectTimeout = 10 * time.Second
 | 
			
		||||
	server.SendTimeout = 10 * time.Second
 | 
			
		||||
 | 
			
		||||
	smtpClient, err := server.Connect()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	email := mail.NewMSG()
 | 
			
		||||
	email.SetFrom(from).AddTo(to).SetSubject(subject)
 | 
			
		||||
	email.SetBody(mail.TextHTML, formattedMessage)
 | 
			
		||||
	email.AddAlternative(mail.TextPlain, plainMessage)
 | 
			
		||||
 | 
			
		||||
	if len(attachments) > 0 {
 | 
			
		||||
		for _, x := range attachments {
 | 
			
		||||
			email.AddAttachment(x)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = email.Send(smtpClient)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		app.errorLog.Println(err)
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	app.infoLog.Println("send mail")
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user