ตัวอย่างการการทำ Service ส่ง EMAIL


require

- github.com/labstack/echo # framework api golang
- github.com/joho/godotenv # env

import library

import (
	"log"
	"net/http"
	"net/smtp"
	"os"

	"github.com/go-playground/validator"
	"github.com/joho/godotenv"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
)
...

struct and validate

...
type (
	SendMail struct {
		To      string `json:"to" validate:"required,email" `
		Body    string `json:"body"`
		Subject string `json:"subject"`
	}
	CustomValidator struct {
		validator *validator.Validate
	}
)

func (cv *CustomValidator) Validate(i interface{}) error {
	return cv.validator.Struct(i)
}
...

คล้ายๆ เป็นการกำหนด Model | Dto สำหรับ รับ Request และ validate

Sendmail Function

ส่วนที่ 1

func send(c echo.Context) (err error) {
	from := os.Getenv("EMAIL")
	pass := os.Getenv("PASSWORD")
  // from , pass เป็นการ เอาค่า EMAIL PASSWORD ที่จะทำการ ส่ง มาจาก ENV
  ...

ส่วนที่ 2

    ...
    ...
	sendmail := new(SendMail)
	if err = c.Bind(sendmail); err != nil {
		return
	}
	if err = c.Validate(sendmail); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
  

เป็นการ เอา Request ที่ได้มาเช็ค กับ Model หรือ Dto ที่เรา ประกาศ ไว้

ส่วนที่ 3

    ...
    ...
	msg := "From: " + from + "\n" +
		"To: " + sendmail.To + "\n" +
		"Subject: " + sendmail.Subject + "\n" +
		sendmail.Body

	err = smtp.SendMail("smtp.gmail.com:587",
		smtp.PlainAuth("", from, pass, "smtp.gmail.com"),
		from, []string{sendmail.To}, []byte(msg))

	if err != nil {
		log.Printf("smtp error: %s", err)

		return echo.NewHTTPError(http.StatusInternalServerError, "smtp error : "+err.Error())
	}
	log.Print("sent")
	return c.JSON(http.StatusOK, map[string]string{"message": "Email sent : " + sendmail.To})
}

เป็นส่วนในการ จัดเตรียมข้อมูลที่ต้องการจะส่ง และทำการส่ง email แบบ smtp

Main Function

func main() {
	e := echo.New()
	e.Validator = &CustomValidator{validator: validator.New()}
	e.POST("/sendmail", send)
	e.Logger.Fatal(e.Start(":1323"))
}

ทั้งหมด

package main

import (
	"log"
	"net/http"
	"net/smtp"
	"os"

	"github.com/go-playground/validator"
	"github.com/joho/godotenv"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
)

type (
	SendMail struct {
		To      string `json:"to" validate:"required,email" `
		Body    string `json:"body"`
		Subject string `json:"subject"`
	}
	CustomValidator struct {
		validator *validator.Validate
	}
)

func (cv *CustomValidator) Validate(i interface{}) error {
	return cv.validator.Struct(i)
}

func getEnv(key string) string {
	err := godotenv.Load(".env")

	if err != nil {
		log.Fatalf("Error loading .env file")
		echo.NewHTTPError(http.StatusBadGateway, "Error loading .env file")
	}

	return os.Getenv(key)
}

func main() {
	e := echo.New()
	e.Validator = &CustomValidator{validator: validator.New()}
	e.POST("/sendmail", send)
	e.Logger.Fatal(e.Start(":1323"))
}

func send(c echo.Context) (err error) {
	from := os.Getenv("EMAIL")
	pass := os.Getenv("PASSWORD")
	sendmail := new(SendMail)
	if err = c.Bind(sendmail); err != nil {
		return
	}

	if err = c.Validate(sendmail); err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}

	msg := "From: " + from + "\n" +
		"To: " + sendmail.To + "\n" +
		"Subject: " + sendmail.Subject + "\n" +
		sendmail.Body

	err = smtp.SendMail("smtp.gmail.com:587",
		smtp.PlainAuth("", from, pass, "smtp.gmail.com"),
		from, []string{sendmail.To}, []byte(msg))

	if err != nil {
		log.Printf("smtp error: %s", err)

		return echo.NewHTTPError(http.StatusInternalServerError, "smtp error : "+err.Error())
	}
	log.Print("sent")
	return c.JSON(http.StatusOK, map[string]string{"message": "Email sent : " + sendmail.To})
}

จากนั้น Run

$ go run .

try curl

$ curl \
  -X POST \
  http://localhost:1323/sendmail \
  -H 'Content-Type: application/json' \
  -d '{"to": "<mail>" ,"body":"test-sendmail" , "subject" : "Subject"}' -i

....

HTTP/1.1 200 OK
Access-Control-Allow-Origin: 
Content-Type: application/json; charset=UTF-8
Vary: Origin
Date: Thu, 30 Jul 2020 15:31:56 GMT
Content-Length: 39

{"message": "Email sent : <mail>"}