使用GO语言编写邮件接收服务器

使用Go语言编写的邮件接收服务器,并把收到的邮件存入mysql

 保存文件名smtpserver.go

package main

import (
    "database/sql"
    "errors"
    "io"
    "io/ioutil"
    "log"
    "strings"
    "time"

    "github.com/emersion/go-smtp"
    _ "github.com/go-sql-driver/mysql"
)

// The Backend implements SMTP server methods.
type Backend struct{}

func (bkd *Backend) NewSession(c *smtp.Conn) (smtp.Session, error) {
    return &Session{
        RemoteAddr: c.Conn().RemoteAddr().String(),
    }, nil
}

// A Session is returned after EHLO.
type Session struct {
    RemoteAddr string
    mail_from  string
    rcpt_to    []string
    data       []byte
}

func (s *Session) AuthPlain(username, password string) error {
    return errors.New("AuthPlain is Disabled")
    if username != "username" || password != "password" {
        return errors.New("Invalid username or password")
    }
    return nil
}

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

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

func (s *Session) Data(r io.Reader) error {
    if b, err := ioutil.ReadAll(r); err != nil {
        return err
    } else {
        //log.Println("Data:", string(b))
        s.data = append(s.data, b...)
    }
    return nil
}

func (s *Session) Reset() {
    return
    s.mail_from = ""
    s.rcpt_to = []string{}
    s.data = []byte{}
}

func (s *Session) Logout() error {
    // 处理邮件
    if s.mail_from == "" || len(s.rcpt_to) == 0 || len(s.data) == 0 {
        return nil
    }
    err := s.handleMail()
    if err != nil {
        log.Println(err)
        return err
    }
    return nil
}

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

    s := smtp.NewServer(be)

    s.Addr = ":25"
    s.Domain = "localhost"
    s.ReadTimeout = 10 * time.Second
    s.WriteTimeout = 10 * time.Second
    s.MaxMessageBytes = 1024 * 1024
    s.MaxRecipients = 50
    s.AllowInsecureAuth = true

    log.Println("Starting server at", s.Addr)
    if err := s.ListenAndServe(); err != nil {
        log.Fatal(err)
    }
}

// 用于处理邮件的回调函数
func (s *Session) handleMail() error {

    rcpt_to := strings.Join(s.rcpt_to, ",")
    log.Println(s.RemoteAddr, "Mail from:", s.mail_from, ", to:", rcpt_to, ", data-len:", len(s.data))

    // 将邮件存储到数据库
    db, err := sql.Open("mysql", "firadio_mail:firadio_mail@tcp(39.101.248.243:3306)/firadio_mail")
    if err != nil {
        return err
    }
    defer db.Close()

    // 准备插入语句
    stmt, err := db.Prepare("INSERT INTO emails (remote_addr, mail_from, rcpt_to, data) VALUES (?, ?, ?, ?)")
    if err != nil {
        return err
    }
    defer stmt.Close()

    // 执行插入语句
    _, err = stmt.Exec(s.RemoteAddr, s.mail_from, rcpt_to, s.data)
    if err != nil {
        return err
    }

    return nil
}

 

posted on 2023-02-24 21:43  项希盛  阅读(590)  评论(0)    收藏  举报