ตัวอย่างการการทำ 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>"}
July 30, 2020