이메일 전송하는 상황이 많을거 같아서 미리 만들어 두기로 했다.
SMTP를 사용하여 구글 이메일을 보내는 API를 만들어 보았다.
Github
https://github.com/kimguny/send-email
웹 프레임워크
go fiber
go packages
net/smtp
보안 정책이 바뀌면서 app 계정을 생성해줘야 한다.
구글 설정 -> 보안 -> 2단계 인증 -> 앱 비밀번호
앱 비밀번호를 생성한 뒤 나오는 비밀번호를 따로 저장해 둔다.
go 프로젝트를 생성한 뒤 .env 파일을 생성해준다.
.env.example
SMTP_USERNAME=""
SMTP_PASSWORD=""
SMTP_FROM=""
깃허브에 올릴때는 보안 때문에 .env 파일은 gitignore로 커밋하지 않고 .env.example을 커밋한다.
패스워드에 아까 저장해둔 앱 비밀번호를 넣으면 된다.
3. API 요청
Key | Value |
Method | POST |
URL | /send_email |
Request Body
Key | Value |
to | [string] |
CURL
curl --location 'http://127.0.0.1:8080/send_email' \
--header 'Content-Type: application/json' \
--data-raw '{
"to": "{전송 할 이메일}"
}'
main.go 생성 후 아래와 같이 코드를 작성했다.
package main
import (
"bytes"
"fmt"
"log"
"mime/multipart"
"net/smtp"
"os"
"github.com/gofiber/fiber/v2"
"github.com/joho/godotenv"
)
type ResponseData struct {
To string `json:"to"`
}
func main() {
// .env 읽기
err := godotenv.Load()
if err != nil {
fmt.Println(err)
return
}
app := fiber.New()
app.Post("/send_email", send_email)
log.Fatal(app.Listen(":8080"))
}
func send_email(c *fiber.Ctx) (err error) {
// 환경변수
smtpUsername := os.Getenv("SMTP_USERNAME")
smtpPassword := os.Getenv("SMTP_PASSWORD")
smtpFROM := os.Getenv("SMTP_FROM")
// POST 요청 body 파싱
var responseData ResponseData
err = c.BodyParser(&responseData)
if err != nil {
fmt.Println(err)
return err
}
// SMTP 인증 정보 설정
smtpHost := "smtp.gmail.com"
smtpPort := 587
auth := smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)
// 메시지 작성
headerSubject := "메일 테스트\r\n"
headerBlank := "\r\n"
body := "메일 테스트 입니다.\r\n"
msg := []byte(headerSubject + headerBlank + body)
// MIME 멀티파트 바디 생성
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
// 텍스트 파트 추가
textPart, err := writer.CreatePart(map[string][]string{
"Content-Type": {"text/plain; charset=UTF-8"},
})
if err != nil {
fmt.Println(err)
return err
}
textPart.Write(msg)
// 메일 헤더 설정
header := make(map[string]string)
header["From"] = smtpFROM
header["To"] = responseData.To
header["Subject"] = "메일 테스트"
header["MIME-Version"] = "1.0"
header["Content-Type"] = writer.FormDataContentType()
// 메일 보내기
err = smtp.SendMail(fmt.Sprintf("%s:%d", smtpHost, smtpPort), auth, smtpFROM, []string{responseData.To}, composeEmail(header, buf.Bytes()))
if err != nil {
fmt.Println(err)
return err
}
return c.SendStatus(200)
}
func composeEmail(header map[string]string, body []byte) []byte {
var email bytes.Buffer
for key, value := range header {
email.WriteString(fmt.Sprintf("%s: %s\r\n", key, value))
}
email.WriteString("\r\n")
email.Write(body)
return email.Bytes()
}
요청을 보내면 이메일이 전송된다.
[Go] 4. Golang 데이터 타입 & 연산자 이해하기 (4) | 2024.01.04 |
---|---|
[Go] 3. Golang 변수와 상수 활용하기 (2) | 2024.01.03 |
[Go] 2. go mod init 패키지 관리 및 활용하기 (2) | 2024.01.02 |
[Go] 1. Golang Mac VSCode 개발환경 세팅하기 (4) | 2023.12.31 |