# Golang

:::info
This guide covers SMTP integration. For full configuration options and available headers, see the [SMTP Introduction](/guides/send-email-with-smtp).
:::

## Basic Configuration

Use environment variables for credentials:

```go
import "os"

const (
    SMTPHost = "smtp.lettermint.co"
    Username = "lettermint"
)

var APIToken = os.Getenv("LETTERMINT_PROJECT_TOKEN")
```

<CodeTabs>
```go title="Port 587 (STARTTLS)"
package main

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

const (
    SMTPHost = "smtp.lettermint.co"
    SMTPPort = "587"
    Username = "lettermint"
)

func sendEmail(to, subject, body string) error {
    from := "sender@yourdomain.com"
    apiToken := os.Getenv("LETTERMINT_PROJECT_TOKEN")

    msg := []byte(fmt.Sprintf(
        "From: %s\r\n"+
        "To: %s\r\n"+
        "Subject: %s\r\n"+
        "Content-Type: text/html; charset=UTF-8\r\n"+
        "\r\n"+
        "%s\r\n",
        from, to, subject, body,
    ))

    auth := smtp.PlainAuth("", Username, apiToken, SMTPHost)

    return smtp.SendMail(
        SMTPHost+":"+SMTPPort,
        auth,
        from,
        []string{to},
        msg,
    )
}

func main() {
    err := sendEmail(
        "recipient@example.com",
        "Test Email",
        "<h1>Hello!</h1><p>This is a test email.</p>",
    )

    if err != nil {
        fmt.Printf("Error: %v\n", err)
    } else {
        fmt.Println("Email sent successfully")
    }
}
```

```go title="Port 465 (Implicit TLS)"
package main

import (
    "crypto/tls"
    "fmt"
    "net/smtp"
    "os"
)

const (
    SMTPHost = "smtp.lettermint.co"
    SMTPPort = "465"
    Username = "lettermint"
)

func sendEmail(to, subject, body string) error {
    from := "sender@yourdomain.com"
    apiToken := os.Getenv("LETTERMINT_PROJECT_TOKEN")

    msg := []byte(fmt.Sprintf(
        "From: %s\r\n"+
        "To: %s\r\n"+
        "Subject: %s\r\n"+
        "Content-Type: text/html; charset=UTF-8\r\n"+
        "\r\n"+
        "%s\r\n",
        from, to, subject, body,
    ))

    auth := smtp.PlainAuth("", Username, apiToken, SMTPHost)

    tlsConfig := &tls.Config{
        ServerName: SMTPHost,
    }

    conn, err := tls.Dial("tcp", SMTPHost+":"+SMTPPort, tlsConfig)
    if err != nil {
        return err
    }
    defer conn.Close()

    client, err := smtp.NewClient(conn, SMTPHost)
    if err != nil {
        return err
    }
    defer client.Quit()

    if err = client.Auth(auth); err != nil {
        return err
    }

    if err = client.Mail(from); err != nil {
        return err
    }

    if err = client.Rcpt(to); err != nil {
        return err
    }

    writer, err := client.Data()
    if err != nil {
        return err
    }

    _, err = writer.Write(msg)
    if err != nil {
        return err
    }

    return writer.Close()
}

func main() {
    err := sendEmail(
        "recipient@example.com",
        "Test Email",
        "<h1>Hello!</h1><p>This is a test email.</p>",
    )

    if err != nil {
        fmt.Printf("Error: %v\n", err)
    } else {
        fmt.Println("Email sent successfully")
    }
}
```
</CodeTabs>

## Advanced Features

### Multiple Recipients

Send to multiple recipients with CC and BCC:

```go
func sendEmailMultipleRecipients(to, cc, bcc []string, subject, body string) error {
    from := "sender@yourdomain.com"
    apiToken := os.Getenv("LETTERMINT_PROJECT_TOKEN")

    // Build recipient list for headers
    toHeader := strings.Join(to, ", ")
    ccHeader := strings.Join(cc, ", ")

    headers := fmt.Sprintf(
        "From: %s\r\n"+
        "To: %s\r\n"+
        "Cc: %s\r\n"+
        "Subject: %s\r\n"+
        "Content-Type: text/html; charset=UTF-8\r\n"+
        "\r\n",
        from, toHeader, ccHeader, subject,
    )

    msg := []byte(headers + body + "\r\n")

    auth := smtp.PlainAuth("", Username, apiToken, SMTPHost)

    // All recipients (to + cc + bcc) receive the email
    allRecipients := append(append(to, cc...), bcc...)

    return smtp.SendMail(
        SMTPHost+":587",
        auth,
        from,
        allRecipients,
        msg,
    )
}

// Usage
sendEmailMultipleRecipients(
    []string{"user1@example.com", "user2@example.com"},
    []string{"manager@yourdomain.com"},
    []string{"archive@yourdomain.com"},
    "Monthly Newsletter",
    "<h1>This Month's Updates</h1>",
)
```

### Attachments

Send emails with file attachments:

```go
import (
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "mime"
    "net/smtp"
    "os"
    "path/filepath"
    "strings"
)

func sendEmailWithAttachment(to, subject, body, filePath string) error {
    from := "sender@yourdomain.com"
    apiToken := os.Getenv("LETTERMINT_PROJECT_TOKEN")

    // Read file
    fileContent, err := ioutil.ReadFile(filePath)
    if err != nil {
        return err
    }

    fileName := filepath.Base(filePath)
    mimeType := mime.TypeByExtension(filepath.Ext(filePath))
    if mimeType == "" {
        mimeType = "application/octet-stream"
    }

    boundary := "boundary123"

    var msg strings.Builder
    msg.WriteString(fmt.Sprintf("From: %s\r\n", from))
    msg.WriteString(fmt.Sprintf("To: %s\r\n", to))
    msg.WriteString(fmt.Sprintf("Subject: %s\r\n", subject))
    msg.WriteString(fmt.Sprintf("MIME-Version: 1.0\r\n"))
    msg.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\r\n", boundary))
    msg.WriteString("\r\n")

    // HTML body
    msg.WriteString(fmt.Sprintf("--%s\r\n", boundary))
    msg.WriteString("Content-Type: text/html; charset=UTF-8\r\n")
    msg.WriteString("\r\n")
    msg.WriteString(body)
    msg.WriteString("\r\n")

    // Attachment
    msg.WriteString(fmt.Sprintf("--%s\r\n", boundary))
    msg.WriteString(fmt.Sprintf("Content-Type: %s\r\n", mimeType))
    msg.WriteString("Content-Transfer-Encoding: base64\r\n")
    msg.WriteString(fmt.Sprintf("Content-Disposition: attachment; filename=\"%s\"\r\n", fileName))
    msg.WriteString("\r\n")
    msg.WriteString(base64.StdEncoding.EncodeToString(fileContent))
    msg.WriteString("\r\n")

    msg.WriteString(fmt.Sprintf("--%s--\r\n", boundary))

    auth := smtp.PlainAuth("", Username, apiToken, SMTPHost)

    return smtp.SendMail(
        SMTPHost+":587",
        auth,
        from,
        []string{to},
        []byte(msg.String()),
    )
}
```

### Lettermint Headers

Add Lettermint-specific headers for tags, metadata, and routing:

```go
func sendEmailWithHeaders(to, subject, body string) error {
    from := "sender@yourdomain.com"
    apiToken := os.Getenv("LETTERMINT_PROJECT_TOKEN")

    msg := []byte(fmt.Sprintf(
        "From: %s\r\n"+
        "To: %s\r\n"+
        "Subject: %s\r\n"+
        "Content-Type: text/html; charset=UTF-8\r\n"+
        "X-LM-Tag: order-confirmation\r\n"+
        "X-LM-Metadata-order_id: 12345\r\n"+
        "X-LM-Metadata-customer_id: cust_789\r\n"+
        "X-Lettermint-Route: transactional\r\n"+
        "\r\n"+
        "%s\r\n",
        from, to, subject, body,
    ))

    auth := smtp.PlainAuth("", Username, apiToken, SMTPHost)

    return smtp.SendMail(
        SMTPHost+":587",
        auth,
        from,
        []string{to},
        msg,
    )
}
```

:::note
Metadata headers are extracted by Lettermint and included in webhook payloads, but not added to the actual email sent to recipients.
See the [SMTP Introduction](/guides/send-email-with-smtp#custom-headers) for full details on available headers.
:::

## Using Third-Party Libraries

### With gomail

For a simpler API, use the gomail library:

```bash
go get gopkg.in/gomail.v2
```

```go
package main

import (
    "os"
    "gopkg.in/gomail.v2"
)

func sendEmailWithGomail() error {
    m := gomail.NewMessage()
    m.SetHeader("From", "sender@yourdomain.com")
    m.SetHeader("To", "recipient@example.com")
    m.SetHeader("Subject", "Test Email")
    m.SetBody("text/html", "<h1>Hello!</h1><p>This is a test email.</p>")

    // Add Lettermint headers
    m.SetHeader("X-LM-Tag", "test-email")
    m.SetHeader("X-LM-Metadata-campaign", "test")

    // Add attachments
    m.Attach("/path/to/document.pdf")

    d := gomail.NewDialer("smtp.lettermint.co", 587, "lettermint", os.Getenv("LETTERMINT_PROJECT_TOKEN"))

    return d.DialAndSend(m)
}
```
