emersion / go-smtp

📤 An SMTP client & server library written in Go
MIT License
1.72k stars 216 forks source link

Request an example code for smtp relay #242

Closed CaledoniaProject closed 7 months ago

CaledoniaProject commented 10 months ago

Can you add an example that would relay all emails to another SMTP server?

emersion commented 7 months ago

Sorry, but I don't have time for this.

olljanat commented 7 months ago

In case someone is still interested. This is version which I got from ChatGPT:

package main

import (
    "io"
    "log"

    smtp "github.com/emersion/go-smtp"
)

// Backend defines your backend to handle SMTP sessions.
type Backend struct{}

// NewSession is called after client greeting (EHLO, HELO).
func (bkd *Backend) NewSession(c *smtp.Conn) (smtp.Session, error) {
    session := &Session{
        from: "",
        to:   []string{},
    }
    return session, nil
}

// Session is used to store state of an SMTP session through the authentication and message sending process.
type Session struct {
    from string
    to   []string
}

// AuthPlain allows all credentials.
func (s *Session) AuthPlain(username, password string) error {
    return nil
}

func (s *Session) Mail(from string, opts *smtp.MailOptions) error {
    log.Println("Mail from:", from)
    s.from = from
    return nil
}

func (s *Session) Rcpt(to string, opts *smtp.RcptOptions) error {
    log.Println("Rcpt to:", to)
    s.to = append(s.to, to)
    return nil
}

func (s *Session) Data(r io.Reader) error {
    log.Println("Starting to read email data...")
    // Example of sending the email, replace with actual sending logic
    err := smtp.SendMail("smtp.example.com:25", nil, s.from, s.to, r)
    if err != nil {
        log.Printf("Failed to send email: %v\n", err)
        return err
    }

    log.Println("Email sent successfully.")
    return nil
}

func (s *Session) Reset() {
    log.Println("Resetting session")
}

func (s *Session) Logout() error {
    log.Println("Logging out")
    return nil
}

func main() {
    be := &Backend{}

    s := smtp.NewServer(be)

    s.Addr = ":1025"
    s.Domain = "localhost"
    s.AllowInsecureAuth = true

    log.Println("Starting SMTP server on port 1025")
    if err := s.ListenAndServe(); err != nil {
        log.Fatal(err)
    }
}

and it should do the trick.