2020. 1. 27. 19:17 ㆍ개발 이야기/Golang
안녕하세요.
실직으로 인해 정말 오랫만에 블로그에 글을 쓰는 것 같습니다..
심리적으로 정말 힘든 요즘이네요 ㅎㅎ
그래도! 멈출수는 없으니까~~ ㅎㅎ
오늘은 구현해 놓은지는 조금된 기능인데요
SMTP 연동입니다.
SMTP는
simple mail transfer protocol의 약어. 인터넷 상에서 전자 메일을 전송할 때 쓰이는 표준적인 프로토콜. SMTP 프로토콜에 의해 전자 메일을 발신하는 서버(server)를 SMTP 서버라고 한다. 메일 사이에서 발생하는 것을 전송해 주는 프로토콜로 인터넷에서 이메일을 교환할 때 그 과정을 정렬해준다.
[네이버 지식백과] SMTP [simple mail transfer protocol] (컴퓨터인터넷IT용어대사전, 2011. 1. 20., 전산용어사전편찬위원회)
메일 전송을 할 때 사용하는 프로토콜인데요
SMTP 서버를 구축하고 자체 SMTP를 사용할 수도 있고
naver나 google의 SMTP 서버를 사용할 수도 있도록
코드를 작성해보도록 하겠습니다.
모듈은 gomail을 사용해보겠습니다.
먼저 SMTP 정보를 저장할 수 있는 DB 스키마를 작성하고
사용자마다 사용하고 싶은 SMTP 서버 정보를 넣는 input form을 만들어서 구현을 했습니다.
이렇게 SMTP 서버 정보를 입력해 놓으면
정상적으로 연결이 되는지 연결 테스트를 하고 저장하도록 프로세스를 만들었는데요
자 그럼 연결테스트를 누르면 이 정보를 가지고 연결이 정상적으로 되는지 확인 하는 로직을 구현해보겠습니다.
먼저 gomail을 사용하려면!
go get gopkg.in/gomail.v2
SMTP 정보를 담을 수 있는 구조체를 만들어 줍니다.
type Smtpinfo struct {
SmtpNo int `json:"smtp_no"`
SmtpHost string `json:"smtp_host"`
SmtpPort string `json:"smtp_port"`
SmtpProtocol string `json:"smtp_protocol"`
SmtpTls string `json:"smtp_tls"`
SmtpTimeout string `json:"smtp_timeout"`
SmtpId string `json:"smtp_id"`
SmtpPw string `json:"smtp_pw"`
SmtpIdentity string `json:"smtp_identity"`
}
그리고 front-end 에서 보낸 정보를 BIND해주겠습니다.
func SmtpConnectionCheck(c *gin.Context) {
var si mail.Smtpinfo
err := c.BindJSON(&si)
err = si.IdPwCheck()
err = si.SmtpConnectionCheck(model.GetUserNo(c))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"status": http.StatusBadRequest,
"isOK": 0,
"error": err,
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"isOK": 1,
})
}
바인딩을 해준 후 SmtpConnectionCheck 메서드를 이용해 Smtp 정보가 연결 가능한 정보인지 확인을 하는데요!
gomail.NewDialer 메서드로 다이얼을 만들어주고
Dial 메서드를 실행해 err가 있으면 연결에 실패한 것으로
판단할 수있습니다. 디버깅을 해보겠습니다.
func (si *Smtpinfo) SmtpConnectionCheck(userNo int) error {
port, _ := strconv.Atoi(si.SmtpPort)
d := gomail.NewDialer(si.SmtpHost, port, si.SmtpId, si.SmtpPw)
// d.Dial()
_, err := d.Dial()
if err != nil {
return err
}
return nil
}
잘못된 정보를 입력했을 때
not accepted 에러가 발생할 것을 확인할 수 있죠?
정상적인 정보를 입력하면?
에러가 nil인 것을 확인할 수있습니다.
자 이렇게 연결 테스트 로직을 구현했으면
메일을 보내봐야겠죠?
테스트로 메일을 보낼 수 있는 api를 만들었습니다.
func SendMailTest(c *gin.Context) {
var si mail.Smtpinfo
err := c.BindJSON(&si)
err = si.SendMail()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"status": http.StatusBadRequest,
"isOK": 0,
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"status": http.StatusOK,
"isOK": 1,
})
}
smtp 연결 테스트와 유사하게 로직을 구현했구요
간단히 bind 후 sendMail 메서드 실행 입니다.
gomail을 이용한 메일 전송 로직은 그냥 smtp 모듈을 사용하는 것과 거의 같다고 생각이 들었는데요
func (si *Smtpinfo) SendMail() error {
// var list []struct {
// Name string
// Address string
// }
port, _ := strconv.Atoi(si.SmtpPort)
d := gomail.NewDialer(si.SmtpHost, port, si.SmtpId, si.SmtpPw)
s, err := d.Dial()
if err != nil {
return err
}
m := gomail.NewMessage()
// for _, r := range list {
m.SetHeader("From", "보내는계정@naver.com")
m.SetAddressHeader("To", "받는계정@gmail.com", "Minseok")
m.SetHeader("Subject", "Newsletter #1")
m.SetBody("text/html", fmt.Sprintf("Hello %s!", "Minseok"))
if err := gomail.Send(s, m); err != nil {
return fmt.Errorf(
"Could not send email to %q: %v", "보내는계정@naver.com", err)
}
m.Reset()
// }
return nil
}
간단히 전송만 하도록 구현했는데요
smtp check 로직과 동일하게 먼저 dial을 확인해 연결이 가능한지 확인을 한 후
NewMessage 작성해줍니다.
여기서 혼돈할 수 있는 부분은
보내는 계정이 smtp에 연동된 계정과 다르다면 아래와 같은 에러가 발생하게됩니다.
정상적으로 계정을 입력해서 보내게되면
정상적으로 메일이 보내진 것을 확인할 수있습니다.
이렇게 SMTP 를 golang에서도 사용할 수있는데요!
메일을 이용해 개인정보 처리방침 등의 변경이 있는 경우
공지를 해주면 아주 좋겠죠?
이상입니다
'개발 이야기 > Golang' 카테고리의 다른 글
# Opentracing Jaeger-client golang/JAVA applicaion에 적용하기[JAVA 편] (0) | 2020.08.23 |
---|---|
# Kubernetes(쿠버네티스) 환경에서 GO 어플리케이션 디버깅 환경 구성 (0) | 2020.08.05 |
#5 Golang bcrypt로 비밀번호 해싱 및 검증하기 (0) | 2019.12.30 |
#4 Golang 인증 middleware 구현하기(gin framework) (0) | 2019.12.20 |
#3 Golang JWT 토큰으로 인증 구현하기 (0) | 2019.12.16 |