148 lines
3.4 KiB
Go
148 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"mime"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/jhillyerd/enmime"
|
|
"github.com/mhale/smtpd"
|
|
)
|
|
|
|
type Config struct {
|
|
Address string `json:"addr"`
|
|
ApiUrl string `json:"api_url"`
|
|
ApiKey string `json:"api_key"`
|
|
}
|
|
|
|
type MailContent struct {
|
|
Key string `json:"key"`
|
|
From string `json:"from"`
|
|
To string `json:"to"`
|
|
Title string `json:"title"`
|
|
Body string `json:"body"`
|
|
FromAddr string `json:"from_addr"`
|
|
FromProtocol string `json:"from_protocol"`
|
|
ReceivedAt string `json:"received_at"`
|
|
}
|
|
|
|
var appConfig Config
|
|
|
|
func decodeHeader(header string) (string, error) {
|
|
decoded, err := (&mime.WordDecoder{}).DecodeHeader(header)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return decoded, nil
|
|
}
|
|
|
|
func postMailContent(url string, key string, mailContent *MailContent) error {
|
|
// 将邮件内容转换为 JSON
|
|
jsonData, err := json.Marshal(mailContent)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 创建 HTTP 请求
|
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// 发送 HTTP 请求
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// 读取响应体(如果需要)
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Println("Response Status:", resp.Status)
|
|
log.Println("Response Body:", string(body))
|
|
|
|
return nil
|
|
}
|
|
|
|
func mailHandler(origin net.Addr, from string, to []string, data []byte) error {
|
|
reader := bytes.NewReader(data)
|
|
// msg, _ := mail.ReadMessage(reader)
|
|
// subject := msg.Header.Get("Subject")
|
|
// decodedSubject, _ := decodeHeader(subject)
|
|
env, _ := enmime.ReadEnvelope(reader)
|
|
|
|
subject := env.GetHeader("Subject")
|
|
// The plain text body is available as mime.Text.
|
|
fmt.Printf("Text Body: %v chars\n", len(env.Text))
|
|
|
|
// The HTML body is stored in mime.HTML.
|
|
fmt.Printf("HTML Body: %v chars\n", len(env.HTML))
|
|
// 获取邮件正文
|
|
// contentType := msg.Header.Get("Content-Type")
|
|
// mediaType, params, err := mime.ParseMediaType(contentType)
|
|
|
|
body := env.HTML
|
|
|
|
fmt.Println("Body:", body)
|
|
|
|
log.Printf("Received mail from %s for %s with subject %s body %s", from, to[0], subject, body)
|
|
|
|
receivedAt := time.Now() // 例如,使用当前时间作为接收时间
|
|
|
|
// 创建 MailContent 对象
|
|
mailContent := &MailContent{
|
|
Key: appConfig.ApiKey,
|
|
From: from,
|
|
To: to[0],
|
|
Title: subject,
|
|
Body: body,
|
|
FromAddr: origin.String(),
|
|
FromProtocol: origin.Network(),
|
|
ReceivedAt: receivedAt.Format(time.RFC3339),
|
|
}
|
|
|
|
// 将邮件内容发送到 API
|
|
err := postMailContent(appConfig.ApiUrl, appConfig.ApiKey, mailContent)
|
|
if err != nil {
|
|
log.Println("Failed to post mail content:", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
configPath := flag.String("c", "config.json", "Path to the configuration file")
|
|
flag.Parse()
|
|
|
|
file, err := os.Open(*configPath)
|
|
if err != nil {
|
|
log.Fatalf("Error opening config file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
configBytes, err := ioutil.ReadAll(file)
|
|
if err != nil {
|
|
log.Fatalf("Error reading config file: %v", err)
|
|
}
|
|
|
|
if err := json.Unmarshal(configBytes, &appConfig); err != nil {
|
|
log.Fatalf("Error parsing config file: %v", err)
|
|
}
|
|
|
|
log.Printf("Starting server at %s", appConfig.Address)
|
|
smtpd.ListenAndServe(appConfig.Address, mailHandler, "MyServerApp", "")
|
|
}
|