GO에서 SMTP로 이메일 발송하기 (Daum 계정으로)


Go언어로 SMTP로 이메일을 보내는 예제를 구해서 해보는데 안되길래 좀 더 검색해서 정리해서 올려 봅니다.

일단 필요한 정보는 다음메일에 환경설정에 IMAP/POP3 부분에 IMAP/SMTP 사용함에 체크를 하고 밑에 나온 SMTP 서버명, SMTP포트번호, 아이디, 비밀번호를 아래 변수에 저장합니다.

smtpID := "다음아이디"
smtpPassword := "다음비밀번호"
smtpServerURL := "smtp.daum.net"
smtpServerPort := "465"
fromEmail := "본인 다음이메일 주소"

IMAP은 메일을 수신할때 쓰는건데 여기서 구현하지 않습니다. (여긴 발송만…)

//메일 받을 사람.
listTo := []string{"받을사람 이메일 주소"}
//참조
listCc := []string{"참조로 들어갈 이메일 주소"}
//숨은 참조
listBcc := []string{"숨은참조로 들어갈 이메일 주소"}

subj := "[테스트] 이메일 발송 SMTP"
body := "이것은 테스트 본문입니다.(this is the test body.)\n두줄로. With two lines."

받을 이메일 주소나 CC, BCC 목록을 만들어줍니다. 그리고 메일 제목과 메일 본문내용을 작성합니다.

//헤더 생성
headers := make(map[string]string)
headers["From"] = fromEmail
headers["To"] = ""
for _, v := range listTo {
    headers["To"] += fmt.Sprintf("%s,", v)
}
headers["CC"] = ""
for _, v := range listCc {
    headers["CC"] += fmt.Sprintf("%s,", v)
}
headers["BCC"] = ""
for _, v := range listBcc {
    headers["BCC"] += fmt.Sprintf("%s,", v)
}
headers["Date"] = time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700")
headers["Subject"] = "=?UTF-8?B?" + base64.StdEncoding.EncodeToString([]byte(subj)) + "?="

// Setup message
message := ""
for key, value := range headers {
    message += fmt.Sprintf("%s: %s\r\n", key, value)
}
message += "\r\n" + body

위에서 작성한 데이터를 토대로 이메일 헤더를 만듭니다.
근데 메일 제목에 =?UTF-8?B?를 넣고 base64로 인코딩한 이유는… 안하면 한글이 깨지더군요.

이렇게 나오길래 검색해서 해결했습니다.

tlsconfig := &tls.Config{
    InsecureSkipVerify: false,
    ServerName:         smtpServerURL,
}

conn, err := tls.Dial("tcp", smtpServerURL+":"+smtpServerPort, tlsconfig)
if err != nil {
    log.Panic(err)
}

다음 이메일 SSL 문제 때문에 메일이 발송되지 않았는데 smtp.dial 대신 tls.dial로 바꾸면 해결됩니다.

client, err := smtp.NewClient(conn, smtpServerURL)
if err != nil {
    log.Panic(err)
}

// Auth
auth := smtp.PlainAuth("", smtpID, smtpPassword, smtpServerURL)
if err = client.Auth(auth); err != nil {
    log.Panic(err)
}

//보내는 사람 이메일 입력하고
if err = client.Mail(fromEmail); err != nil {
    log.Panic(err)
}

//to rcpt
for _, v := range listTo {
    if err = client.Rcpt(v); err != nil {
        log.Panic(err)
    }
}
//cc rcpt
for _, v := range listCc {
    if err = client.Rcpt(v); err != nil {
        log.Panic(err)
    }
}
//bcc rcpt
for _, v := range listBcc {
    if err = client.Rcpt(v); err != nil {
        log.Panic(err)
    }
}

//메일 발송
w, err := client.Data()
if err != nil {
    log.Panic(err)
}
_, err = w.Write([]byte(message))
if err != nil {
    log.Panic(err)
}

//리소스 정리
err = w.Close()
if err != nil {
    log.Panic(err)
}
client.Quit()

나머지 인데 뭐 딱히 큰 설명 없이 그냥 인증 한담에 각 메일 주소마다 알림 보내고 데이터를 밀어 보낸뒤 리소스 정리? 이렇게 정리합니다.

참고로 네이버는 위 소스로 안됩니다. 소스를 좀 고쳐야 하는데 그건 나중에 올리기로 하고 일단 다음메일만 해서 정리합니다.

참고 : https://gist.github.com/chrisgillis/10888032,
http://golang.site/go/article/113-SMTP-%EC%9D%B4%EB%A9%94%EC%9D%BC-%EB%B3%B4%EB%82%B4%EA%B8%B0

댓글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다