From 4f305cfeda4375f6a4ef5c4331c783985458ab9d Mon Sep 17 00:00:00 2001 From: mei Date: Sun, 1 Mar 2026 15:27:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(sender/onebot):=20=20=E6=96=B0=E5=A2=9Eone?= =?UTF-8?q?bot=E5=8D=8F=E8=AE=AE=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 62 ++++++++-------- config.example.json | 47 ++++++------ configs/config.go | 35 +++++---- docker-compose.yml | 2 +- go.mod | 5 +- go.sum | 10 ++- internal/{basicInfo.go => base/base.go} | 2 +- internal/{web.go => frontend/frontend.go} | 2 +- internal/remind.go | 32 -------- internal/reminder/reminder.go | 23 ++++++ internal/{ => reminder}/timer.go | 2 +- internal/sendQQMsg.go | 90 ----------------------- internal/{ => sender}/bilibili.go | 7 +- internal/sender/dingtalk.go | 16 ++++ internal/{sendMail.go => sender/email.go} | 19 ++--- internal/{github.go => sender/gitub.go} | 11 ++- internal/sender/onebot.go | 43 +++++++++++ main.go | 49 ++++++------ pkg/{ => github}/github.go | 2 +- 19 files changed, 214 insertions(+), 245 deletions(-) rename internal/{basicInfo.go => base/base.go} (98%) rename internal/{web.go => frontend/frontend.go} (95%) delete mode 100644 internal/remind.go create mode 100644 internal/reminder/reminder.go rename internal/{ => reminder}/timer.go (98%) delete mode 100644 internal/sendQQMsg.go rename internal/{ => sender}/bilibili.go (97%) create mode 100644 internal/sender/dingtalk.go rename internal/{sendMail.go => sender/email.go} (80%) rename internal/{github.go => sender/gitub.go} (64%) create mode 100644 internal/sender/onebot.go rename pkg/{ => github}/github.go (99%) diff --git a/README.md b/README.md index cd1506c..4d84661 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ 4. 发送邮件 5. 将 Github 上的遗言仓库设置为 public 6. 发送一条 Bilibili 动态 +7. 当倒计时小于48小时时,向用钉钉机器人发消息提醒你 ## 配置 @@ -19,40 +20,41 @@ ```json { - "basic": { - "name": "xx", // 你的名字 - "qq_number": "123", // QQ号 - "nickname": "", // 网名 - "age": 16, // 你的年龄 - "cause_stop": "自杀" // 你最可能的死因 - }, - "signal_secret": "", // 发送 signal请求时需要的密钥 - "debug": false, // debug 模式 - "disconnect_duration": 5, // 失连时间,超出后会触发系统 - "enable_qq": true, // 是否启用QQ - "cat_bot_url": "", // CatBot 的 webhook地址(https://github.com/ssdomei232/CatBot) - "cat_bot_key": "", // CatBot 的 key - "qq_send_group": [], // 要发送QQ消息的群号 - "qq_msg": "", // 要附加的QQ消息 - "mail_list": [], // 要发送的邮箱 - "mail_title": "摇篮系统已触发", // 邮件标题 - "smtp_config": { // 邮件服务器配置 - "host": "", + "signal_secret": "xxx", // 发送 signal请求时需要的密钥 + "debug": false, // debug 模式 + "disconnect_duration": 80, // 失连时间,超出后会触发系统(小时) + "bili_msg": "摇篮系统测试", // 哔哩哔哩动态的附加消息 + "mail_config": { + "host": "smtp.example.com", "port": 465, - "user": "", - "pass": "" + "user": "xxx", + "pass": "xxx", + "mail_list": ["xxx@example.com", "xxx1@example.com"],// 要发送的邮箱 + "mail_title": "摇篮系统已触发", // 邮件标题 + "mail_content": "这是摇篮系统的邮件内容。" // 要附加的邮件内容 + }, // 邮件配置 + "basic": { + "name": "xx", // 你的名字 + "qq_number": "123", // 你的QQ号 + "nickname": "xx_123", // 网名 + "age": 16, // 你的年龄 + "cause_stop": "自杀" // 你最可能的死因 }, - "mail_content": "", // 要附加的邮件内容 - "github_config": { // Github 配置 - "owner": "", - "repos": [""], - "token": "ghp_xxxx" + "github_config": { + "owner": "example", // github用户名 + "repos": ["example-repo1", "example-repo2"], // 要公开的 github 仓库 + "token": "ghp_xxxx" // github token }, - "bili_msg": "xxx", // 哔哩哔哩动态的附加消息 "dingtalk_bot": { - "access_token": "", // 钉钉机器人的 access_token - "secret": "" // 钉钉机器人的 secret - } // 钉钉机器人(用于提醒发送signal和bilibili过期提醒) + "access_token": "xxx", + "secret": "xxx" + }, // 钉钉机器人(用于提醒发送signal和bilibili过期提醒) + "onebot_config": { + "url": "http://localhost:5700", + "token": "xxx", + "send_groups": [12345678, 87654321], // 要发送到的Onebot群组 + "msg": "这是OneBot的消息内容。" // Onebot消息 + } } ``` diff --git a/config.example.json b/config.example.json index d9b668d..0289afd 100644 --- a/config.example.json +++ b/config.example.json @@ -1,36 +1,37 @@ { + "signal_secret": "xxx", + "debug": true, + "disconnect_duration": 80, + "bili_msg": "摇篮系统测试", + "mail_config": { + "host": "smtp.example.com", + "port": 465, + "user": "xxx", + "pass": "xxx", + "mail_list": ["xxx@example.com", "xxx1@example.com"], + "mail_title": "摇篮系统已触发", + "mail_content": "这是摇篮系统的邮件内容。" + }, "basic": { "name": "xx", "qq_number": "123", - "nickname": "", + "nickname": "xx_123", "age": 16, "cause_stop": "自杀" }, - "signal_secret": "", - "debug": false, - "disconnect_duration": 5, - "enable_qq": true, - "cat_bot_url": "", - "cat_bot_key": "", - "qq_send_group": [], - "qq_msg": "", - "mail_list": [], - "mail_title": "摇篮系统已触发", - "smtp_config": { - "host": "", - "port": 465, - "user": "", - "pass": "" - }, - "mail_content": "", "github_config": { - "owner": "", - "repos": [""], + "owner": "example", + "repos": ["example-repo1", "example-repo2"], "token": "ghp_xxxx" }, - "bili_msg": "摇篮系统测试", "dingtalk_bot": { - "access_token": "", - "secret": "" + "access_token": "xxx", + "secret": "xxx" + }, + "onebot_config": { + "url": "http://localhost:5700", + "token": "xxx", + "send_groups": [12345678, 87654321], + "msg": "这是OneBot的消息内容。" } } \ No newline at end of file diff --git a/configs/config.go b/configs/config.go index c50be23..ae0e815 100644 --- a/configs/config.go +++ b/configs/config.go @@ -6,29 +6,25 @@ import ( ) type Config struct { - Basic Basic `json:"basic"` SignalSecret string `json:"signal_secret"` Debug bool `json:"debug"` DisconnectDuration int `json:"disconnect_duration"` // Hours - EnableQQ bool `json:"enable_qq"` - CatBotUrl string `json:"cat_bot_url"` - CatBotKey string `json:"cat_bot_key"` - QQSendGroup []int `json:"qq_send_group"` - QQMsg string `json:"qq_msg"` - MailList []string `json:"mail_list"` - MailTitle string `json:"mail_title"` - SMTPConfig SMTPConfig `json:"smtp_config"` - MailContent string `json:"mail_content"` - GithubConfig GithubConfig `json:"github_config"` BiliMsg string `json:"bili_msg"` + Basic Basic `json:"basic"` + MailConfig MailConfig `json:"mail_config"` + GithubConfig GithubConfig `json:"github_config"` DingtalkBot DingtalkBot `json:"dingtalk_bot"` + OneBotConfig OneBotConfig `json:"onebot_config"` } -type SMTPConfig struct { - Host string `json:"host"` - Port int `json:"port"` - User string `json:"user"` - Password string `json:"pass"` +type MailConfig struct { + Host string `json:"host"` + Port int `json:"port"` + User string `json:"user"` + Password string `json:"pass"` + MailList []string `json:"mail_list"` + MailTitle string `json:"mail_title"` + MailContent string `json:"mail_content"` } type GithubConfig struct { @@ -50,6 +46,13 @@ type DingtalkBot struct { Secret string `json:"secret"` } +type OneBotConfig struct { + URL string `json:"url"` // 例如 "http://localhost:5700" + Token string `json:"token"` + SendGroups []int `json:"send_groups"` + Msg string `json:"msg"` +} + // Get config from json file func GetConfig() (config Config, err error) { content, err := os.ReadFile("config.json") diff --git a/docker-compose.yml b/docker-compose.yml index 6a16cb2..f7fa533 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ services: goodbaby: - image: mei232/goodbaby:v0.1.8 + image: mei232/goodbaby:v0.2.0 ports: - "8088:8088" environment: diff --git a/go.mod b/go.mod index 558a372..7cfc0db 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,13 @@ module github.com/ssdomei232/goodBaby -go 1.24.0 +go 1.24.10 require ( github.com/CatchZeng/dingtalk v1.5.0 github.com/CuteReimu/bilibili/v2 v2.3.5 github.com/gin-gonic/gin v1.11.0 github.com/robfig/cron/v3 v3.0.1 + github.com/ssdomei232/napcat-http-go-sdk v0.0.0-20260301031057-040b9c49010b github.com/wneessen/go-mail v0.7.2 ) @@ -20,7 +21,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.27.0 // indirect - github.com/go-resty/resty/v2 v2.16.5 // indirect + github.com/go-resty/resty/v2 v2.17.2 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-yaml v1.18.0 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/go.sum b/go.sum index 52bde9f..40e9f9a 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= -github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= -github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= +github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= @@ -78,6 +78,8 @@ github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/ssdomei232/napcat-http-go-sdk v0.0.0-20260301031057-040b9c49010b h1:eeKLVKw+YAqxUuSzoKampbkDAS0krP5QMbNrFkMi2ss= +github.com/ssdomei232/napcat-http-go-sdk v0.0.0-20260301031057-040b9c49010b/go.mod h1:yPsSaMs3OyKMVPXwIs5ZB5G532vRi1GvL/WiWUEwblU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -110,8 +112,8 @@ golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= diff --git a/internal/basicInfo.go b/internal/base/base.go similarity index 98% rename from internal/basicInfo.go rename to internal/base/base.go index 0718961..d2cc6b8 100644 --- a/internal/basicInfo.go +++ b/internal/base/base.go @@ -1,4 +1,4 @@ -package internal +package base import ( "fmt" diff --git a/internal/web.go b/internal/frontend/frontend.go similarity index 95% rename from internal/web.go rename to internal/frontend/frontend.go index fcc01b1..4169666 100644 --- a/internal/web.go +++ b/internal/frontend/frontend.go @@ -1,4 +1,4 @@ -package internal +package frontend import ( "html/template" diff --git a/internal/remind.go b/internal/remind.go deleted file mode 100644 index 7173dae..0000000 --- a/internal/remind.go +++ /dev/null @@ -1,32 +0,0 @@ -package internal - -import ( - "fmt" - "log" - "time" - - "github.com/CatchZeng/dingtalk/pkg/dingtalk" - "github.com/ssdomei232/goodBaby/configs" -) - -func Reminder() { - config, err := configs.GetConfig() - if err != nil { - log.Printf("获取配置文件失败: %v", err) - } - - remainingTime := GlobalTimerManager.GetRemainingTime() - if remainingTime <= 48*time.Hour { - sendMsg := fmt.Sprintf("距离摇篮系统触发还有%d小时,请尽快发送Signal", int(remainingTime.Hours())) - sendDingTalkMsg("摇篮系统触发提醒", sendMsg, config.DingtalkBot.AccessToken, config.DingtalkBot.Secret) - } -} - -func sendDingTalkMsg(title string, msg string, accessToken string, secret string) { - client := dingtalk.NewClient(accessToken, secret) - sendMsg := dingtalk.NewMarkdownMessage().SetMarkdown(title, msg) - _, _, err := client.Send(sendMsg) - if err != nil { - log.Printf("发送钉钉消息失败: %v", err) - } -} diff --git a/internal/reminder/reminder.go b/internal/reminder/reminder.go new file mode 100644 index 0000000..a9a5ec6 --- /dev/null +++ b/internal/reminder/reminder.go @@ -0,0 +1,23 @@ +package reminder + +import ( + "fmt" + "log" + "time" + + "github.com/ssdomei232/goodBaby/configs" + "github.com/ssdomei232/goodBaby/internal/sender" +) + +func Reminder() { + config, err := configs.GetConfig() + if err != nil { + log.Printf("获取配置文件失败: %v", err) + } + + remainingTime := GlobalTimerManager.GetRemainingTime() + if remainingTime <= 48*time.Hour { + sendMsg := fmt.Sprintf("距离摇篮系统触发还有%d小时,请尽快发送Signal", int(remainingTime.Hours())) + sender.SendDingTalkMsg("摇篮系统触发提醒", sendMsg, config.DingtalkBot.AccessToken, config.DingtalkBot.Secret) + } +} diff --git a/internal/timer.go b/internal/reminder/timer.go similarity index 98% rename from internal/timer.go rename to internal/reminder/timer.go index 0962def..f613cc0 100644 --- a/internal/timer.go +++ b/internal/reminder/timer.go @@ -1,4 +1,4 @@ -package internal +package reminder import ( "net/http" diff --git a/internal/sendQQMsg.go b/internal/sendQQMsg.go deleted file mode 100644 index bd956fa..0000000 --- a/internal/sendQQMsg.go +++ /dev/null @@ -1,90 +0,0 @@ -package internal - -import ( - "bytes" - "fmt" - "log" - "mime/multipart" - "net/http" - "strconv" - "time" - - "github.com/ssdomei232/goodBaby/configs" -) - -// 在QQ发送死亡通告 -func SendQQ() { - config, err := configs.GetConfig() - if err != nil { - log.Printf("获取配置文件失败: %v", err) - return // 添加return避免继续执行 - } - - url := fmt.Sprintf("%s/?secret=%s", config.CatBotUrl, config.CatBotKey) - stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送(摇篮系统)", GetBasicInfo(), config.QQMsg) - - for _, groupId := range config.QQSendGroup { - sendQQMsg(url, groupId, stopMsg) - } -} - -func sendQQMsg(url string, groupId int, msg string) { - method := "POST" - payload := &bytes.Buffer{} - writer := multipart.NewWriter(payload) - - // 处理写入字段的错误 - if err := writer.WriteField("group_id", strconv.Itoa(groupId)); err != nil { - log.Printf("写入group_id字段失败: %v", err) - return - } - - if err := writer.WriteField("message", msg); err != nil { - log.Printf("写入message字段失败: %v", err) - return - } - - err := writer.Close() - if err != nil { - log.Printf("关闭multipart writer失败: %v", err) - return - } - - client := &http.Client{} - req, err := http.NewRequest(method, url, payload) - if err != nil { - log.Printf("创建HTTP请求失败: %v", err) - return - } - - req.Header.Set("Content-Type", writer.FormDataContentType()) - - var res *http.Response - - for i := range maxRetries { - res, err = client.Do(req) - if err == nil { - break // 请求成功,跳出循环 - } - if i < maxRetries { - time.Sleep(retryDelay * time.Duration(i+1)) // 递增延迟 - } - log.Printf("请求QQ API失败,正在重试... (%d/%d): %v", i+1, maxRetries, err) - } - - // 检查res是否为nil,避免panic - if res == nil { - log.Println("QQ API请求失败,无法获取响应") - return - } - - // 使用defer确保资源被释放,但要确保res不为nil - defer func() { - if res != nil && res.Body != nil { - res.Body.Close() - } - }() - - // 可选:记录响应结果 - log.Println("QQ消息发送完成") -} diff --git a/internal/bilibili.go b/internal/sender/bilibili.go similarity index 97% rename from internal/bilibili.go rename to internal/sender/bilibili.go index be71084..e730991 100644 --- a/internal/bilibili.go +++ b/internal/sender/bilibili.go @@ -1,4 +1,4 @@ -package internal +package sender import ( "fmt" @@ -10,6 +10,7 @@ import ( "github.com/CuteReimu/bilibili/v2" "github.com/ssdomei232/goodBaby/configs" + "github.com/ssdomei232/goodBaby/internal/base" ) // check tmp dir exist @@ -134,7 +135,7 @@ func SendBili(biliClient *bilibili.Client) { return } - stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送(摇篮系统)", GetBasicInfo(), config.BiliMsg) + stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送(摇篮系统)", base.GetBasicInfo(), config.BiliMsg) var dynamicParams bilibili.CreateDynamicParam dynamicParams = bilibili.CreateDynamicParam{ @@ -254,7 +255,7 @@ func triggerLoginRequest(biliClient *bilibili.Client) { // 发送Dingtalk通知 if config.DingtalkBot.AccessToken != "" && config.DingtalkBot.Secret != "" { - sendDingTalkMsg(title, msg, config.DingtalkBot.AccessToken, config.DingtalkBot.Secret) + SendDingTalkMsg(title, msg, config.DingtalkBot.AccessToken, config.DingtalkBot.Secret) } } diff --git a/internal/sender/dingtalk.go b/internal/sender/dingtalk.go new file mode 100644 index 0000000..94b9623 --- /dev/null +++ b/internal/sender/dingtalk.go @@ -0,0 +1,16 @@ +package sender + +import ( + "log" + + "github.com/CatchZeng/dingtalk/pkg/dingtalk" +) + +func SendDingTalkMsg(title string, msg string, accessToken string, secret string) { + client := dingtalk.NewClient(accessToken, secret) + sendMsg := dingtalk.NewMarkdownMessage().SetMarkdown(title, msg) + _, _, err := client.Send(sendMsg) + if err != nil { + log.Printf("发送钉钉消息失败: %v", err) + } +} diff --git a/internal/sendMail.go b/internal/sender/email.go similarity index 80% rename from internal/sendMail.go rename to internal/sender/email.go index 8874fa3..9c64353 100644 --- a/internal/sendMail.go +++ b/internal/sender/email.go @@ -1,4 +1,4 @@ -package internal +package sender import ( "fmt" @@ -6,6 +6,7 @@ import ( "time" "github.com/ssdomei232/goodBaby/configs" + "github.com/ssdomei232/goodBaby/internal/base" "github.com/wneessen/go-mail" ) @@ -22,10 +23,10 @@ func SendMail() { return } - stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送", GetBasicInfo(), config.MailContent) + stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送", base.GetBasicInfo(), config.MailConfig.MailContent) - for _, address := range config.MailList { - sendMailMsgWithRetry(address, stopMsg, config.MailTitle) + for _, address := range config.MailConfig.MailList { + sendMailMsgWithRetry(address, stopMsg, config.MailConfig.MailTitle) } } @@ -65,11 +66,11 @@ func sendMailMsg(address string, msg string, title string) error { } client, err := mail.NewClient( - config.SMTPConfig.Host, - mail.WithPort(config.SMTPConfig.Port), + config.MailConfig.Host, + mail.WithPort(config.MailConfig.Port), mail.WithSSL(), - mail.WithUsername(config.SMTPConfig.User), - mail.WithPassword(config.SMTPConfig.Password), + mail.WithUsername(config.MailConfig.User), + mail.WithPassword(config.MailConfig.Password), mail.WithSMTPAuth(mail.SMTPAuthPlain), ) if err != nil { @@ -78,7 +79,7 @@ func sendMailMsg(address string, msg string, title string) error { // 创建邮件 message := mail.NewMsg() - if err := message.From(config.SMTPConfig.User); err != nil { + if err := message.From(config.MailConfig.User); err != nil { return fmt.Errorf("设置发件人失败: %v", err) } diff --git a/internal/github.go b/internal/sender/gitub.go similarity index 64% rename from internal/github.go rename to internal/sender/gitub.go index c4549ef..8528107 100644 --- a/internal/github.go +++ b/internal/sender/gitub.go @@ -1,11 +1,11 @@ -package internal +package sender import ( "log" "time" "github.com/ssdomei232/goodBaby/configs" - "github.com/ssdomei232/goodBaby/pkg" + "github.com/ssdomei232/goodBaby/pkg/github" ) // 将repos设置为public @@ -18,19 +18,18 @@ func Github() { for _, repo := range config.GithubConfig.Repos { maxRetries := 10 for attempt := range maxRetries { - err := pkg.MakeRepositoryPublic(config.GithubConfig.Owner, repo, config.GithubConfig.Token) + err := github.MakeRepositoryPublic(config.GithubConfig.Owner, repo, config.GithubConfig.Token) if err == nil { - // 成功执行,跳出重试循环 break } - log.Printf("尝试设置仓库 %s 为私有失败 (尝试 %d/%d): %v", repo, attempt+1, maxRetries, err) + log.Printf("尝试设置仓库 %s 为公开失败 (尝试 %d/%d): %v", repo, attempt+1, maxRetries, err) // 如果不是最后一次尝试,则等待一段时间后重试 if attempt < maxRetries-1 { time.Sleep(time.Duration(attempt+1) * time.Second) // 逐步增加等待时间 } else { - log.Printf("设置仓库 %s 为私有最终失败", repo) + log.Printf("设置仓库 %s 为公开最终失败", repo) } } } diff --git a/internal/sender/onebot.go b/internal/sender/onebot.go new file mode 100644 index 0000000..189866e --- /dev/null +++ b/internal/sender/onebot.go @@ -0,0 +1,43 @@ +package sender + +import ( + "fmt" + "log" + "strconv" + + "github.com/ssdomei232/goodBaby/configs" + "github.com/ssdomei232/goodBaby/internal/base" + napcat "github.com/ssdomei232/napcat-http-go-sdk" +) + +func SendOneBot() { + config, err := configs.GetConfig() + if err != nil { + log.Printf("获取配置文件失败: %v", err) + return + } + + stopMsg := fmt.Sprintf("%s\n\n%s\n\n本消息由自动程序发送(摇篮系统)", base.GetBasicInfo(), config.OneBotConfig.Msg) + + for _, groupId := range config.OneBotConfig.SendGroups { + sendOneBotMsg(groupId, stopMsg) + } +} + +// 发送一条消息到OneBot +func sendOneBotMsg(groupID int, msg string) { + config, err := configs.GetConfig() + if err != nil { + log.Printf("获取配置文件失败: %v", err) + return + } + + client := napcat.NewClient(config.OneBotConfig.URL, config.OneBotConfig.Token) + + err = client.SendGroupMsg(strconv.Itoa(groupID), msg) + if err != nil { + log.Printf("发送消息到OneBot失败: %v", err) + } else { + log.Printf("成功发送消息到OneBot群 %d", groupID) + } +} diff --git a/main.go b/main.go index 810c167..4d54bea 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,3 @@ -// main.go package main import ( @@ -12,7 +11,9 @@ import ( "github.com/gin-gonic/gin" "github.com/robfig/cron/v3" "github.com/ssdomei232/goodBaby/configs" - "github.com/ssdomei232/goodBaby/internal" + "github.com/ssdomei232/goodBaby/internal/frontend" + "github.com/ssdomei232/goodBaby/internal/reminder" + "github.com/ssdomei232/goodBaby/internal/sender" ) //go:embed static/* @@ -27,7 +28,7 @@ var biliClient *bilibili.Client var cookieCheckTimer *time.Ticker func init() { - // Get COnfig + // 1. 加载配置文件 config, err := configs.GetConfig() if err != nil { log.Printf("获取配置文件失败: %v", err) @@ -39,17 +40,17 @@ func init() { duration = time.Duration(config.DisconnectDuration) * time.Hour } - // Check and create tmp dir - if err := internal.EnsureTmpDirectory(); err != nil { + // 2. 检查并创建tmp目录 + if err := sender.EnsureTmpDirectory(); err != nil { log.Printf("创建tmp目录失败: %v", err) } - // Init Bilibili Clinet + // 3. 初始化哔哩哔哩和定时器 biliClient = bilibili.New() - internal.InitBilibili(biliClient) - internal.StartCookieChecker(cookieCheckTimer, biliClient) // Check Bilibili cookie + sender.InitBilibili(biliClient) + sender.StartCookieChecker(cookieCheckTimer, biliClient) // Check Bilibili cookie - internal.InitTimerManager(duration) + reminder.InitTimerManager(duration) timer = time.NewTimer(duration) go func() { <-timer.C @@ -57,15 +58,13 @@ func init() { }() } -// trigger +// 触发器 func trigger(config configs.Config) { - if config.EnableQQ { - go internal.SendQQ() - } - go internal.SendMail() - go internal.Github() + go sender.SendOneBot() + go sender.SendMail() + go sender.Github() if !config.Debug { - go internal.SendBili(biliClient) + go sender.SendBili(biliClient) } } @@ -74,26 +73,26 @@ func main() { if err != nil { log.Printf("获取配置文件失败: %v", err) } - // cron job - internal.Reminder() + // 定时任务 + reminder.Reminder() c := cron.New() if config.Debug { - c.AddFunc("@every 1s", internal.Reminder) + c.AddFunc("@every 1s", reminder.Reminder) } else { - c.AddFunc("@every 1h", internal.Reminder) + c.AddFunc("@every 1h", reminder.Reminder) } c.Start() - // Web service + // 前端/后端 r := gin.Default() templFS, _ := fs.Sub(templateFiles, "templates") - r.SetHTMLTemplate(internal.LoadTemplates(templFS)) + r.SetHTMLTemplate(frontend.LoadTemplates(templFS)) staticFS, _ := fs.Sub(staticFiles, "static") r.StaticFS("/static", http.FS(staticFS)) - r.GET("/", internal.IndexPage) + r.GET("/", frontend.IndexPage) r.GET("/signal", handleSignal) - r.GET("/timer/status", internal.HandleTimerStatus) + r.GET("/timer/status", reminder.HandleTimerStatus) r.Run(":8088") } @@ -113,7 +112,7 @@ func handleSignal(c *gin.Context) { return } timer.Reset(duration) - internal.GlobalTimerManager.Reset() + reminder.GlobalTimerManager.Reset() c.JSON(200, gin.H{ "code": 200, "message": "ok", diff --git a/pkg/github.go b/pkg/github/github.go similarity index 99% rename from pkg/github.go rename to pkg/github/github.go index f5bd049..ff0ea4e 100644 --- a/pkg/github.go +++ b/pkg/github/github.go @@ -1,4 +1,4 @@ -package pkg +package github import ( "bytes"