Difference between revisions of "Go email example"

From UVOO Tech Wiki
Jump to navigation Jump to search
(Created page with "https://zetcode.com/golang/email-smtp/ ``` package main import ( "fmt" "log" "net/smtp" ) func main() { from := "john.doe@example.com" user := "9c1d45...")
 
Line 38: Line 38:
  
 
     fmt.Println("Email sent successfully")
 
     fmt.Println("Email sent successfully")
 +
}
 +
```
 +
 +
 +
more complex
 +
```
 +
package main
 +
 +
import (
 +
  "fmt"
 +
  "log"
 +
  "net"
 +
  "net/mail"
 +
  "net/smtp"
 +
  "crypto/tls"
 +
)
 +
 +
func main() {
 +
 +
from := mail.Address{"", "username@example.tld"}
 +
to  := mail.Address{"", "username@anotherexample.tld"}
 +
subj := "This is the email subject"
 +
body := "This is an example body.\n With two lines."
 +
 +
headers := make(map[string]string)
 +
headers["From"] = from.String()
 +
headers["To"] = to.String()
 +
headers["Subject"] = subj
 +
 +
message := ""
 +
for k,v := range headers {
 +
    message += fmt.Sprintf("%s: %s\r\n", k, v)
 +
}
 +
message += "\r\n" + body
 +
 +
servername := "smtp.example.tld:465"
 +
 +
host, _, _ := net.SplitHostPort(servername)
 +
 +
auth := smtp.PlainAuth("","username@example.tld", "password", host)
 +
 +
tlsconfig := &tls.Config {
 +
    InsecureSkipVerify: true,
 +
    ServerName: host,
 +
}
 +
 +
conn, err := tls.Dial("tcp", servername, tlsconfig)
 +
if err != nil {
 +
    log.Panic(err)
 +
}
 +
c, err := smtp.NewClient(conn, host)
 +
if err != nil {
 +
    log.Panic(err)
 +
}
 +
if err = c.Auth(auth); err != nil {
 +
    log.Panic(err)
 +
}
 +
if err = c.Mail(from.Address); err != nil {
 +
    log.Panic(err)
 +
}
 +
if err = c.Rcpt(to.Address); err != nil {
 +
    log.Panic(err)
 +
}
 +
w, err := c.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)
 +
}
 +
c.Quit()
 +
}
 +
```
 +
 +
 +
template.go
 +
```
 +
package main
 +
 +
import (
 +
    "bytes"
 +
    "fmt"
 +
    "log"
 +
    "net/smtp"
 +
    "text/template"
 +
 +
    "github.com/shopspring/decimal"
 +
)
 +
 +
type Mail struct {
 +
    Sender  string
 +
    To      string
 +
    Subject string
 +
    Body    bytes.Buffer
 +
}
 +
 +
type User struct {
 +
    Name  string
 +
    Email string
 +
    Debt  decimal.Decimal
 +
}
 +
 +
func main() {
 +
 +
    sender := "john.doe@example.com"
 +
 +
    var users = []User{
 +
        {"Roger Roe", "roger.roe@example.com", decimal.NewFromFloat(890.50)},
 +
        {"Peter Smith", "peter.smith@example.com", decimal.NewFromFloat(350)},
 +
        {"Lucia Green", "lucia.green@example.com", decimal.NewFromFloat(120.80)},
 +
    }
 +
 +
    my_user := "9c1d45eaf7af5b"
 +
    my_password := "ad62926fa75d0f"
 +
    addr := "smtp.mailtrap.io:2525"
 +
    host := "smtp.mailtrap.io"
 +
 +
    subject := "Amount due"
 +
 +
    var template_data = `
 +
    Dear {{ .Name }}, your debt amount is ${{ .Debt }}.`
 +
 +
    for _, user := range users {
 +
 +
        t := template.Must(template.New("template_data").Parse(template_data))
 +
        var body bytes.Buffer
 +
 +
        err := t.Execute(&body, user)
 +
        if err != nil {
 +
            log.Fatal(err)
 +
        }
 +
 +
        request := Mail{
 +
            Sender:  sender,
 +
            To:      user.Email,
 +
            Subject: subject,
 +
            Body:    body,
 +
        }
 +
 +
        msg := BuildMessage(request)
 +
        auth := smtp.PlainAuth("", my_user, my_password, host)
 +
        err2 := smtp.SendMail(addr, auth, sender, []string{user.Email}, []byte(msg))
 +
 +
        if err2 != nil {
 +
            log.Fatal(err)
 +
        }
 +
    }
 +
 +
    fmt.Println("Emails sent successfully")
 +
}
 +
 +
func BuildMessage(mail Mail) string {
 +
    msg := ""
 +
    msg += fmt.Sprintf("From: %s\r\n", mail.Sender)
 +
    msg += fmt.Sprintf("To: %s\r\n", mail.To)
 +
    msg += fmt.Sprintf("Subject: %s\r\n", mail.Subject)
 +
    msg += fmt.Sprintf("\r\n%s\r\n", mail.Body.String())
 +
 +
    return msg
 +
}
 +
```
 +
 +
attachment
 +
```
 +
package main
 +
 +
import (
 +
    "bytes"
 +
    "encoding/base64"
 +
    "fmt"
 +
    "io/ioutil"
 +
    "log"
 +
    "net/smtp"
 +
    "strings"
 +
)
 +
 +
type Mail struct {
 +
    Sender  string
 +
    To      []string
 +
    Subject string
 +
    Body    string
 +
}
 +
 +
func main() {
 +
 +
    sender := "john.doe@example.com"
 +
 +
    to := []string{
 +
        "roger.roe@example.com",
 +
    }
 +
 +
    user := "9c1d45eaf7af5b"
 +
    password := "ad62926fa75d0f"
 +
 +
    subject := "testing mail with attachment"
 +
    body := "email body message"
 +
 +
    request := Mail{
 +
        Sender:  sender,
 +
        To:      to,
 +
        Subject: subject,
 +
        Body:    body,
 +
    }
 +
 +
    addr := "smtp.mailtrap.io:2525"
 +
    host := "smtp.mailtrap.io"
 +
 +
    data := BuildMail(request)
 +
    auth := smtp.PlainAuth("", user, password, host)
 +
    err := smtp.SendMail(addr, auth, sender, to, data)
 +
 +
    if err != nil {
 +
        log.Fatal(err)
 +
    }
 +
 +
    fmt.Println("Email sent successfully")
 +
}
 +
 +
func BuildMail(mail Mail) []byte {
 +
 +
    var buf bytes.Buffer
 +
 +
    buf.WriteString(fmt.Sprintf("From: %s\r\n", mail.Sender))
 +
    buf.WriteString(fmt.Sprintf("To: %s\r\n", strings.Join(mail.To, ";")))
 +
    buf.WriteString(fmt.Sprintf("Subject: %s\r\n", mail.Subject))
 +
 +
    boundary := "my-boundary-779"
 +
    buf.WriteString("MIME-Version: 1.0\r\n")
 +
    buf.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\n",
 +
        boundary))
 +
 +
    buf.WriteString(fmt.Sprintf("\r\n--%s\r\n", boundary))
 +
    buf.WriteString("Content-Type: text/plain; charset=\"utf-8\"\r\n")
 +
    buf.WriteString(fmt.Sprintf("\r\n%s", mail.Body))
 +
 +
    buf.WriteString(fmt.Sprintf("\r\n--%s\r\n", boundary))
 +
    buf.WriteString("Content-Type: text/plain; charset=\"utf-8\"\r\n")
 +
    buf.WriteString("Content-Transfer-Encoding: base64\r\n")
 +
    buf.WriteString("Content-Disposition: attachment; filename=words.txt\r\n")
 +
    buf.WriteString("Content-ID: <words.txt>\r\n\r\n")
 +
 +
    data := readFile("words.txt")
 +
 +
    b := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
 +
    base64.StdEncoding.Encode(b, data)
 +
    buf.Write(b)
 +
    buf.WriteString(fmt.Sprintf("\r\n--%s", boundary))
 +
 +
    buf.WriteString("--")
 +
 +
    return buf.Bytes()
 +
}
 +
 +
func readFile(fileName string) []byte {
 +
 +
    data, err := ioutil.ReadFile(fileName)
 +
    if err != nil {
 +
        log.Fatal(err)
 +
    }
 +
 +
    return data
 
}
 
}
 
```
 
```

Revision as of 16:04, 15 May 2023

https://zetcode.com/golang/email-smtp/

package main

import (
    "fmt"
    "log"
    "net/smtp"
)

func main() {

    from := "john.doe@example.com"

    user := "9c1d45eaf7af5b"
    password := "ad62926fa75d0f"

    to := []string{
        "roger.roe@example.com",
    }

    addr := "smtp.mailtrap.io:2525"
    host := "smtp.mailtrap.io"

    msg := []byte("From: john.doe@example.com\r\n" +
        "To: roger.roe@example.com\r\n" +
        "Subject: Test mail\r\n\r\n" +
        "Email body\r\n")

    auth := smtp.PlainAuth("", user, password, host)

    err := smtp.SendMail(addr, auth, from, to, msg)

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Email sent successfully")
}

more complex

package main

import (
   "fmt"
   "log"
   "net"
   "net/mail"
   "net/smtp"
   "crypto/tls"
)

func main() {

from := mail.Address{"", "username@example.tld"}
to   := mail.Address{"", "username@anotherexample.tld"}
subj := "This is the email subject"
body := "This is an example body.\n With two lines."

headers := make(map[string]string)
headers["From"] = from.String()
headers["To"] = to.String()
headers["Subject"] = subj

message := ""
for k,v := range headers {
    message += fmt.Sprintf("%s: %s\r\n", k, v)
}
message += "\r\n" + body

servername := "smtp.example.tld:465"

host, _, _ := net.SplitHostPort(servername)

auth := smtp.PlainAuth("","username@example.tld", "password", host)

tlsconfig := &tls.Config {
    InsecureSkipVerify: true,
    ServerName: host,
}

conn, err := tls.Dial("tcp", servername, tlsconfig)
if err != nil {
    log.Panic(err)
}
c, err := smtp.NewClient(conn, host)
if err != nil {
    log.Panic(err)
}
if err = c.Auth(auth); err != nil {
    log.Panic(err)
}
if err = c.Mail(from.Address); err != nil {
    log.Panic(err)
}
if err = c.Rcpt(to.Address); err != nil {
    log.Panic(err)
}
w, err := c.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)
}
c.Quit()
} 

template.go

package main

import (
    "bytes"
    "fmt"
    "log"
    "net/smtp"
    "text/template"

    "github.com/shopspring/decimal"
)

type Mail struct {
    Sender  string
    To      string
    Subject string
    Body    bytes.Buffer
}

type User struct {
    Name  string
    Email string
    Debt  decimal.Decimal
}

func main() {

    sender := "john.doe@example.com"

    var users = []User{
        {"Roger Roe", "roger.roe@example.com", decimal.NewFromFloat(890.50)},
        {"Peter Smith", "peter.smith@example.com", decimal.NewFromFloat(350)},
        {"Lucia Green", "lucia.green@example.com", decimal.NewFromFloat(120.80)},
    }

    my_user := "9c1d45eaf7af5b"
    my_password := "ad62926fa75d0f"
    addr := "smtp.mailtrap.io:2525"
    host := "smtp.mailtrap.io"

    subject := "Amount due"

    var template_data = `
    Dear {{ .Name }}, your debt amount is ${{ .Debt }}.`

    for _, user := range users {

        t := template.Must(template.New("template_data").Parse(template_data))
        var body bytes.Buffer

        err := t.Execute(&body, user)
        if err != nil {
            log.Fatal(err)
        }

        request := Mail{
            Sender:  sender,
            To:      user.Email,
            Subject: subject,
            Body:    body,
        }

        msg := BuildMessage(request)
        auth := smtp.PlainAuth("", my_user, my_password, host)
        err2 := smtp.SendMail(addr, auth, sender, []string{user.Email}, []byte(msg))

        if err2 != nil {
            log.Fatal(err)
        }
    }

    fmt.Println("Emails sent successfully")
}

func BuildMessage(mail Mail) string {
    msg := ""
    msg += fmt.Sprintf("From: %s\r\n", mail.Sender)
    msg += fmt.Sprintf("To: %s\r\n", mail.To)
    msg += fmt.Sprintf("Subject: %s\r\n", mail.Subject)
    msg += fmt.Sprintf("\r\n%s\r\n", mail.Body.String())

    return msg
}

attachment

package main

import (
    "bytes"
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "log"
    "net/smtp"
    "strings"
)

type Mail struct {
    Sender  string
    To      []string
    Subject string
    Body    string
}

func main() {

    sender := "john.doe@example.com"

    to := []string{
        "roger.roe@example.com",
    }

    user := "9c1d45eaf7af5b"
    password := "ad62926fa75d0f"

    subject := "testing mail with attachment"
    body := "email body message"

    request := Mail{
        Sender:  sender,
        To:      to,
        Subject: subject,
        Body:    body,
    }

    addr := "smtp.mailtrap.io:2525"
    host := "smtp.mailtrap.io"

    data := BuildMail(request)
    auth := smtp.PlainAuth("", user, password, host)
    err := smtp.SendMail(addr, auth, sender, to, data)

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Email sent successfully")
}

func BuildMail(mail Mail) []byte {

    var buf bytes.Buffer

    buf.WriteString(fmt.Sprintf("From: %s\r\n", mail.Sender))
    buf.WriteString(fmt.Sprintf("To: %s\r\n", strings.Join(mail.To, ";")))
    buf.WriteString(fmt.Sprintf("Subject: %s\r\n", mail.Subject))

    boundary := "my-boundary-779"
    buf.WriteString("MIME-Version: 1.0\r\n")
    buf.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\n", 
        boundary))

    buf.WriteString(fmt.Sprintf("\r\n--%s\r\n", boundary))
    buf.WriteString("Content-Type: text/plain; charset=\"utf-8\"\r\n")
    buf.WriteString(fmt.Sprintf("\r\n%s", mail.Body))

    buf.WriteString(fmt.Sprintf("\r\n--%s\r\n", boundary))
    buf.WriteString("Content-Type: text/plain; charset=\"utf-8\"\r\n")
    buf.WriteString("Content-Transfer-Encoding: base64\r\n")
    buf.WriteString("Content-Disposition: attachment; filename=words.txt\r\n")
    buf.WriteString("Content-ID: <words.txt>\r\n\r\n")

    data := readFile("words.txt")

    b := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
    base64.StdEncoding.Encode(b, data)
    buf.Write(b)
    buf.WriteString(fmt.Sprintf("\r\n--%s", boundary))

    buf.WriteString("--")

    return buf.Bytes()
}

func readFile(fileName string) []byte {

    data, err := ioutil.ReadFile(fileName)
    if err != nil {
        log.Fatal(err)
    }

    return data
}