随笔 - 192  文章 - 0  评论 - 14  阅读 - 24万

使用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   项希盛  阅读(528)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示