mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-18 20:50:12 +08:00
Some checks failed
自动更新 nix 依赖 / gomod2nix update (push) Has been cancelled
最新版 / Build binary CI (386, linux) (push) Has been cancelled
最新版 / Build binary CI (386, windows) (push) Has been cancelled
最新版 / Build binary CI (amd64, linux) (push) Has been cancelled
最新版 / Build binary CI (amd64, windows) (push) Has been cancelled
最新版 / Build binary CI (arm, linux) (push) Has been cancelled
最新版 / Build binary CI (arm64, linux) (push) Has been cancelled
PushLint / lint (push) Has been cancelled
153 lines
5.5 KiB
Go
153 lines
5.5 KiB
Go
// Package rsshub rss_hub订阅插件
|
||
package rsshub
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"regexp"
|
||
|
||
ctrl "github.com/FloatTech/zbpctrl"
|
||
"github.com/FloatTech/zbputils/control"
|
||
zbpCtxExt "github.com/FloatTech/zbputils/ctxext"
|
||
"github.com/sirupsen/logrus"
|
||
zero "github.com/wdvxdr1123/ZeroBot"
|
||
"github.com/wdvxdr1123/ZeroBot/message"
|
||
|
||
"github.com/FloatTech/ZeroBot-Plugin/plugin/rsshub/domain"
|
||
)
|
||
|
||
// 初始化 repo
|
||
var (
|
||
rssRepo *domain.RssDomain
|
||
initErr error
|
||
regexpForSQL = regexp.MustCompile(`[\^<>\[\]%&\*\(\)\{\}\|\=]|(union\s+select|update\s+|delete\s+|drop\s+|truncate\s+|insert\s+|exec\s+|declare\s+)`)
|
||
)
|
||
|
||
var (
|
||
// 注册插件
|
||
engine = control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
||
// 默认不启动
|
||
DisableOnDefault: false,
|
||
Brief: "rsshub订阅姬",
|
||
// 详细帮助
|
||
Help: "rsshub订阅姬desu~ \n" +
|
||
"支持的详细订阅列表文档可见:\n" +
|
||
"https://rsshub.netlify.app/zh/ \n" +
|
||
"- 添加rsshub订阅-/bookfere/weekly \n" +
|
||
"- 删除rsshub订阅-/bookfere/weekly \n" +
|
||
"- 查看rsshub订阅列表 \n" +
|
||
"- rsshub同步 \n" +
|
||
"Tips: 定时刷新rsshub订阅信息需要配合job一起使用, 全局只需要设置一个, 无视响应状态推送, 下为例子\n" +
|
||
"记录在\"@every 10m\"触发的指令)\n" +
|
||
"rsshub同步",
|
||
// 插件数据存储路径
|
||
PrivateDataFolder: "rsshub",
|
||
OnEnable: func(ctx *zero.Ctx) {
|
||
ctx.SendChain(message.Text("rsshub订阅姬现在启动了哦"))
|
||
},
|
||
OnDisable: func(ctx *zero.Ctx) {
|
||
ctx.SendChain(message.Text("rsshub订阅姬现在关闭了哦"))
|
||
},
|
||
}).ApplySingle(zbpCtxExt.DefaultSingle)
|
||
)
|
||
|
||
// init 命令路由
|
||
func init() {
|
||
rssRepo, initErr = domain.NewRssDomain(engine.DataFolder() + "rsshub.db")
|
||
if initErr != nil {
|
||
logrus.Errorln("rsshub订阅姬:初始化失败", initErr)
|
||
panic(initErr)
|
||
}
|
||
engine.OnFullMatch("rsshub同步", zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||
// 群组-频道推送视图 map[群组]推送内容数组
|
||
groupToFeedsMap, err := rssRepo.Sync(context.Background())
|
||
if err != nil {
|
||
logrus.Errorln("rsshub同步失败", err)
|
||
ctx.SendPrivateMessage(zero.BotConfig.SuperUsers[0], message.Text("rsshub同步失败", err))
|
||
return
|
||
}
|
||
// 没有更新的[群组-频道推送视图]则不推送
|
||
if len(groupToFeedsMap) == 0 {
|
||
logrus.Info("rsshub未发现更新")
|
||
return
|
||
}
|
||
sendRssUpdateMsg(ctx, groupToFeedsMap)
|
||
})
|
||
// 添加订阅
|
||
engine.OnPrefix("添加rsshub订阅-", zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||
routeStr := ctx.State["args"].(string)
|
||
input := regexpForSQL.ReplaceAllString(routeStr, "")
|
||
logrus.Debugf("添加rsshub订阅:raw(%s), replaced(%s)", routeStr, input)
|
||
rv, _, isSubExisted, err := rssRepo.Subscribe(context.Background(), ctx.Event.GroupID, input)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text("rsshub订阅姬:添加失败", err.Error()))
|
||
return
|
||
}
|
||
if isSubExisted {
|
||
ctx.SendChain(message.Text("rsshub订阅姬:已存在,更新成功"))
|
||
} else {
|
||
ctx.SendChain(message.Text("rsshub订阅姬:添加成功\n", rv.Source.Title))
|
||
}
|
||
// 添加成功,发送订阅源快照
|
||
msg, err := newRssDetailsMsg(ctx, rv)
|
||
if len(msg) == 0 || err != nil {
|
||
ctx.SendPrivateMessage(zero.BotConfig.SuperUsers[0], message.Text("rsshub推送错误", err))
|
||
return
|
||
}
|
||
if id := ctx.Send(msg).ID(); id == 0 {
|
||
ctx.SendChain(message.Text("ERROR: 发送订阅源快照失败,可能被风控了"))
|
||
}
|
||
})
|
||
engine.OnPrefix("删除rsshub订阅-", zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||
routeStr := ctx.State["args"].(string)
|
||
input := regexpForSQL.ReplaceAllString(routeStr, "")
|
||
logrus.Debugf("删除rsshub订阅:raw(%s), replaced(%s)", routeStr, input)
|
||
err := rssRepo.Unsubscribe(context.Background(), ctx.Event.GroupID, input)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text("rsshub订阅姬:删除失败 ", err.Error()))
|
||
return
|
||
}
|
||
ctx.SendChain(message.Text(fmt.Sprintf("rsshub订阅姬:删除%s成功", input)))
|
||
})
|
||
engine.OnFullMatch("查看rsshub订阅列表", zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||
rv, err := rssRepo.GetSubscribedChannelsByGroupID(context.Background(), ctx.Event.GroupID)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text("rsshub订阅姬:查询失败 ", err.Error()))
|
||
return
|
||
}
|
||
// 添加成功,发送订阅源信息
|
||
msg, err := newRssSourcesMsg(ctx, rv)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text("rsshub订阅姬:查询失败 ", err.Error()))
|
||
return
|
||
}
|
||
if len(msg) == 0 {
|
||
ctx.SendChain(message.Text("ん? 没有订阅的频道哦~"))
|
||
return
|
||
}
|
||
ctx.SendChain(msg...)
|
||
})
|
||
}
|
||
|
||
// sendRssUpdateMsg 发送Rss更新消息
|
||
func sendRssUpdateMsg(ctx *zero.Ctx, groupToFeedsMap map[int64][]*domain.RssClientView) {
|
||
for groupID, views := range groupToFeedsMap {
|
||
logrus.Infof("rsshub插件在群 %d 触发推送检查", groupID)
|
||
for _, view := range views {
|
||
if view == nil || len(view.Contents) == 0 {
|
||
continue
|
||
}
|
||
msg, err := newRssDetailsMsg(ctx, view)
|
||
if len(msg) == 0 || err != nil {
|
||
ctx.SendPrivateMessage(zero.BotConfig.SuperUsers[0], message.Text(rssHubPushErrMsg, err))
|
||
continue
|
||
}
|
||
logrus.Infof("rsshub插件在群 %d 开始推送 %s", groupID, view.Source.Title)
|
||
ctx.SendGroupMessage(groupID, message.Text(fmt.Sprintf("%s\n该rsshub频道下有更新了哦~", view.Source.Title)))
|
||
if res := ctx.SendGroupForwardMessage(groupID, msg); !res.Exists() {
|
||
ctx.SendPrivateMessage(zero.BotConfig.SuperUsers[0], message.Text(rssHubPushErrMsg))
|
||
}
|
||
}
|
||
}
|
||
}
|