diff --git a/README.md b/README.md index 5750499..0c90c50 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,14 @@ beautiful and cute Logo for this project! ## Features * Single file operation and easy deployment. - * The binary file is only 15MB and takes up less than 10M of memory during the run. - * Support dkim, spf checksum, [Email Test](https://www.mail-tester.com/) score 10 points if correctly configured. - * Implementing the ACME protocol, the program will automatically obtain and update Let's Encrypt certificates. > By default, a ssl certificate is generated for the web service, allowing pages to use the https protocol. > If you have your own gateway or don't need https, set `httpsEnabled` to `2` in the configuration file so that the web > service will not use https. -(Note: Even if you don't need https, please make sure the path to the ssl certificate file is correct, although the web +> (Note: Even if you don't need https, please make sure the path to the ssl certificate file is correct, although the web > service doesn't use the certificate anymore, the smtp protocol still needs the certificate) * Support pop3, smtp protocol, you can use any mail client you like. @@ -40,7 +37,6 @@ beautiful and cute Logo for this project! * At present, only the core function of sending and receiving emails has been completed. Basically, it can only be used by a single person, and does not deal with issues related to permission management in the process of multiple users. - * The UI is ugly # How to run @@ -52,14 +48,13 @@ First go to [spamhaus](https://check.spamhaus.org/) and check your domain name a ## 1、Download * [Click Here](https://github.com/Jinnrry/PMail/releases) Download a program file that matches you. - * Or use Docker `docker pull ghcr.io/jinnrry/pmail:latest` ## 2、Run -`./pmail` +`./pmail` -Or +Or `docker run -p 25:25 -p 80:80 -p 443:443 -p 110:110 -p 465:465 -p 995:995 -v $(pwd)/config:/work/config ghcr.io/jinnrry/pmail:latest` @@ -82,9 +77,14 @@ Open the `config/config.json` file in the run directory, edit a few configuratio and restart the service. ## 6、Telegram Message Push + Create bot and get token from [BotFather](https://t.me/BotFather) Open the `config/config.json` file in the run directory, edit a few configuration items at the beginning of `tg`and restart the service. +## 7、WebHook Push + +Open the `config/config.json` file in the running directory, edit the webPushUrl and webPushToken (optional). After receiving an email, the email information will be posted to the hook address, and the token will also be placed in the body for easy verification. After configuring, restart the service. + # Configuration file format description ```json @@ -108,6 +108,8 @@ Open the `config/config.json` file in the run directory, edit a few configuratio "weChatPushUserId": "", // weChat UserId "tgChatId": "", // telegram chatid "tgBotToken": "", // telegram token + "webPushUrl": "", // webhook 推送地址 + "webPushToken": "", // webhook 推送 token "isInit": true // If false, it will enter the bootstrap process. } ``` diff --git a/README_CN.md b/README_CN.md index cb1ae4d..ab66279 100644 --- a/README_CN.md +++ b/README_CN.md @@ -32,8 +32,8 @@ PMail是一个追求极简部署流程、极致资源占用的个人域名邮箱 实现了ACME协议,程序将自动获取并更新Let’s Encrypt证书。 -默认情况下,会为web后台也生成ssl证书,让后台使用https访问,如果你有自己的网关层,不需要https的话,在配置文件中将`httpsEnabled` -设置为`2`,这样管理后台就不会使用https协议。( 注意:即使你不需要https,也请保证ssl证书文件路径正确,http协议虽然不使用证书了,但是smtp协议还需要证书) +默认情况下,会为web后台也生成ssl证书,让后台使用https访问,如果你有自己的网关层,不需要https的话,在配置文件中将 `httpsEnabled` +设置为 `2`,这样管理后台就不会使用https协议。( 注意:即使你不需要https,也请保证ssl证书文件路径正确,http协议虽然不使用证书了,但是smtp协议还需要证书) ### 5、邮件客户端支持 @@ -56,12 +56,11 @@ PMail是一个追求极简部署流程、极致资源占用的个人域名邮箱 ## 1、下载文件 * [点击这里](https://github.com/Jinnrry/PMail/releases)下载一个与你匹配的程序文件。 - * 或者使用Docker运行 `docker pull ghcr.io/jinnrry/pmail:latest` ## 2、运行 -`./pmail` +`./pmail` 或者 @@ -83,8 +82,12 @@ PMail是一个追求极简部署流程、极致资源占用的个人域名邮箱 打开运行目录下的 `config/config.json`文件,编辑 `weChatPush` 开头的几个配置项,重启服务即可。 ## 6、Telegram推送 + 从 [BotFather](https://t.me/BotFather) 创建并获取令牌机器人。 打开运行目录下的 config/config.json 文件,编辑 `tg` 开头的几个配置项,重启服务即可。 +## 7、WebHook推送 + +打开运行目录下的 `config/config.json`文件,编辑 webPushUrl 跟webPushToken (可选),接收到邮件后会往hook地址post发送邮件信息,token也会放在body中,方便需要的进行校验,配置完重启服务即可。 # 配置文件说明 @@ -109,6 +112,8 @@ PMail是一个追求极简部署流程、极致资源占用的个人域名邮箱 "weChatPushUserId": "", // 微信推送用户id "tgChatId": "", // telegram 推送chatid "tgBotToken": "", // telegram 推送 token + "webPushUrl": "", // webhook 推送地址 + "webPushToken": "", // webhook 推送 token "isInit": true // 为false的时候会进入安装引导流程 } ``` @@ -129,11 +134,11 @@ SMTP端口: 25/465(SSL) 1、前端: vue3+element-plus -前端代码位于`fe`目录中,运行参考`fe`目录中的README文件 +前端代码位于 `fe`目录中,运行参考 `fe`目录中的README文件 2、后端: golang + mysql -后端代码进入`server`文件夹,运行`main.go`文件 +后端代码进入 `server`文件夹,运行 `main.go`文件 ## 后端接口文档 @@ -141,5 +146,4 @@ SMTP端口: 25/465(SSL) ## 插件开发 -参考微信推送插件`server/hooks/wechat_push/wechat_push.go` - +参考微信推送插件 `server/hooks/wechat_push/wechat_push.go` diff --git a/server/config/config.dev.json b/server/config/config.dev.json index 2ff7256..1843ff7 100644 --- a/server/config/config.dev.json +++ b/server/config/config.dev.json @@ -17,6 +17,8 @@ "weChatPushUserId": "", "tgChatId": "", "tgBotToken": "", + "webPushUrl": "", + "webPushToken": "", "isInit": true, "httpsEnabled": 2 } \ No newline at end of file diff --git a/server/config/config.go b/server/config/config.go index 5dd20c7..b6ce9b2 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -32,6 +32,8 @@ type Config struct { TgBotToken string `json:"tgBotToken"` TgChatId string `json:"tgChatId"` IsInit bool `json:"isInit"` + WebPushUrl string `json:"webPushUrl"` + WebPushToken string `json:"webPushToken"` Tables map[string]string `json:"-"` TablesInitData map[string]string `json:"-"` } diff --git a/server/config/config.json b/server/config/config.json index 77fab9a..bf63c9b 100644 --- a/server/config/config.json +++ b/server/config/config.json @@ -17,6 +17,8 @@ "weChatPushUserId": "", "tgChatId": "", "tgBotToken": "", + "webPushUrl": "", + "webPushToken": "", "isInit": true, "httpsEnabled": 1 } \ No newline at end of file diff --git a/server/config/config_mysql.json b/server/config/config_mysql.json index cb74799..c2e7d64 100644 --- a/server/config/config_mysql.json +++ b/server/config/config_mysql.json @@ -17,6 +17,8 @@ "weChatPushUserId": "", "tgChatId": "", "tgBotToken": "", + "webPushUrl": "", + "webPushToken": "", "isInit": true, "httpsEnabled": 2 } \ No newline at end of file diff --git a/server/hooks/base.go b/server/hooks/base.go index a146a44..aa5c760 100644 --- a/server/hooks/base.go +++ b/server/hooks/base.go @@ -3,6 +3,7 @@ package hooks import ( "pmail/dto/parsemail" "pmail/hooks/telegram_push" + "pmail/hooks/web_push" "pmail/hooks/wechat_push" "pmail/utils/context" ) @@ -26,5 +27,6 @@ func Init() { HookList = []EmailHook{ wechat_push.NewWechatPushHook(), telegram_push.NewTelegramPushHook(), + web_push.NewWebPushHook(), } } diff --git a/server/hooks/web_push/web_push.go b/server/hooks/web_push/web_push.go new file mode 100644 index 0000000..400a70c --- /dev/null +++ b/server/hooks/web_push/web_push.go @@ -0,0 +1,88 @@ +package web_push + +import ( + "bytes" + "encoding/json" + "net/http" + "pmail/config" + "pmail/dto/parsemail" + "pmail/utils/context" + + log "github.com/sirupsen/logrus" +) + +type WebPushHook struct { + url string + token string +} + +// EmailData 用于存储解析后的邮件数据 +type EmailData struct { + From string `json:"from"` + To []string `json:"to"` + Subject string `json:"subject"` + Body string `json:"body"` + Token string `json:"token"` +} + +func (w *WebPushHook) SendBefore(ctx *context.Context, email *parsemail.Email) { + +} + +func (w *WebPushHook) SendAfter(ctx *context.Context, email *parsemail.Email, err map[string]error) { + +} + +func (w *WebPushHook) ReceiveParseBefore(email []byte) { + +} + +func (w *WebPushHook) ReceiveParseAfter(email *parsemail.Email) { + if w.url == "" { + return + } + + content := string(email.Text) + + if content == "" { + content = email.Subject + } + + webhookURL := w.url // 替换为您的 Webhook URL + + to := make([]string, len(email.To)) + for i, user := range email.To { + to[i] = user.EmailAddress + } + + data := EmailData{ + From: email.From.EmailAddress, + To: to, + Subject: email.Subject, + Body: content, + Token: w.token, + } + + var ctx *context.Context = nil + jsonData, err := json.Marshal(data) + + if err != nil { + log.WithContext(ctx).Errorf("web push error %+v", err) + } + + resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(jsonData)) + if err != nil { + log.WithContext(ctx).Errorf("web push error %+v", err) + } + defer resp.Body.Close() +} + +func NewWebPushHook() *WebPushHook { + + ret := &WebPushHook{ + url: config.Instance.WebPushUrl, + token: config.Instance.WebPushToken, + } + return ret + +} diff --git a/server/hooks/web_push/wechat_push_test.go b/server/hooks/web_push/wechat_push_test.go new file mode 100644 index 0000000..bbd7511 --- /dev/null +++ b/server/hooks/web_push/wechat_push_test.go @@ -0,0 +1,19 @@ +package web_push + +import ( + "pmail/config" + "pmail/dto/parsemail" + "testing" +) + +func testInit() { + + config.Init() + +} +func TestWebPushHook_ReceiveParseAfter(t *testing.T) { + testInit() + + w := NewWebPushHook() + w.ReceiveParseAfter(&parsemail.Email{Subject: "标题", Text: []byte("文本内容")}) +} diff --git a/server/http_server/https_server.go b/server/http_server/https_server.go index 705b153..9a58c35 100644 --- a/server/http_server/https_server.go +++ b/server/http_server/https_server.go @@ -4,8 +4,6 @@ import ( "embed" "encoding/json" "fmt" - log "github.com/sirupsen/logrus" - "github.com/spf13/cast" "io/fs" olog "log" "net/http" @@ -19,6 +17,9 @@ import ( "pmail/utils/context" "pmail/utils/id" "time" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cast" ) //go:embed dist/*