mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 05:30:07 +08:00
192 lines
5.9 KiB
Go
192 lines
5.9 KiB
Go
// Package bilibili bilibili卡片解析
|
|
package bilibili
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
bz "github.com/FloatTech/AnimeAPI/bilibili"
|
|
"github.com/FloatTech/floatbox/web"
|
|
ctrl "github.com/FloatTech/zbpctrl"
|
|
"github.com/FloatTech/zbputils/control"
|
|
"github.com/FloatTech/zbputils/ctxext"
|
|
zero "github.com/wdvxdr1123/ZeroBot"
|
|
"github.com/wdvxdr1123/ZeroBot/message"
|
|
)
|
|
|
|
const (
|
|
enableHex = 0x10
|
|
unableHex = 0x7fffffff_fffffffd
|
|
)
|
|
|
|
var (
|
|
limit = ctxext.NewLimiterManager(time.Second*10, 1)
|
|
searchVideo = `bilibili.com\\?/video\\?/(?:av(\d+)|([bB][vV][0-9a-zA-Z]+))`
|
|
searchDynamic = `(t.bilibili.com|m.bilibili.com\\?/dynamic)\\?/(\d+)`
|
|
searchArticle = `bilibili.com\\?/read\\?/(?:cv|mobile\\?/)(\d+)`
|
|
searchLiveRoom = `live.bilibili.com\\?/(\d+)`
|
|
searchVideoRe = regexp.MustCompile(searchVideo)
|
|
searchDynamicRe = regexp.MustCompile(searchDynamic)
|
|
searchArticleRe = regexp.MustCompile(searchArticle)
|
|
searchLiveRoomRe = regexp.MustCompile(searchLiveRoom)
|
|
)
|
|
|
|
// 插件主体
|
|
func init() {
|
|
en := control.Register("bilibiliparse", &ctrl.Options[*zero.Ctx]{
|
|
DisableOnDefault: false,
|
|
Brief: "b站链接解析",
|
|
Help: "例:- t.bilibili.com/642277677329285174\n- bilibili.com/read/cv17134450\n- bilibili.com/video/BV13B4y1x7pS\n- live.bilibili.com/22603245 ",
|
|
})
|
|
en.OnRegex(`((b23|acg).tv|bili2233.cn)\\?/[0-9a-zA-Z]+`).SetBlock(true).Limit(limit.LimitByGroup).
|
|
Handle(func(ctx *zero.Ctx) {
|
|
u := ctx.State["regex_matched"].([]string)[0]
|
|
u = strings.ReplaceAll(u, "\\", "")
|
|
realurl, err := bz.GetRealURL("https://" + u)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR: ", err))
|
|
return
|
|
}
|
|
switch {
|
|
case searchVideoRe.MatchString(realurl):
|
|
ctx.State["regex_matched"] = searchVideoRe.FindStringSubmatch(realurl)
|
|
handleVideo(ctx)
|
|
case searchDynamicRe.MatchString(realurl):
|
|
ctx.State["regex_matched"] = searchDynamicRe.FindStringSubmatch(realurl)
|
|
handleDynamic(ctx)
|
|
case searchArticleRe.MatchString(realurl):
|
|
ctx.State["regex_matched"] = searchArticleRe.FindStringSubmatch(realurl)
|
|
handleArticle(ctx)
|
|
case searchLiveRoomRe.MatchString(realurl):
|
|
ctx.State["regex_matched"] = searchLiveRoomRe.FindStringSubmatch(realurl)
|
|
handleLive(ctx)
|
|
}
|
|
})
|
|
en.OnRegex(`^(开启|打开|启用|关闭|关掉|禁用)视频总结$`, zero.AdminPermission).SetBlock(true).
|
|
Handle(func(ctx *zero.Ctx) {
|
|
gid := ctx.Event.GroupID
|
|
if gid <= 0 {
|
|
// 个人用户设为负数
|
|
gid = -ctx.Event.UserID
|
|
}
|
|
option := ctx.State["regex_matched"].([]string)[1]
|
|
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
|
if !ok {
|
|
ctx.SendChain(message.Text("找不到服务!"))
|
|
return
|
|
}
|
|
data := c.GetData(ctx.Event.GroupID)
|
|
switch option {
|
|
case "开启", "打开", "启用":
|
|
data |= enableHex
|
|
case "关闭", "关掉", "禁用":
|
|
data &= unableHex
|
|
default:
|
|
return
|
|
}
|
|
err := c.SetData(gid, data)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("出错啦: ", err))
|
|
return
|
|
}
|
|
ctx.SendChain(message.Text("已", option, "视频总结"))
|
|
})
|
|
en.OnRegex(searchVideo).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleVideo)
|
|
en.OnRegex(searchDynamic).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleDynamic)
|
|
en.OnRegex(searchArticle).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleArticle)
|
|
en.OnRegex(searchLiveRoom).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleLive)
|
|
}
|
|
|
|
func handleVideo(ctx *zero.Ctx) {
|
|
id := ctx.State["regex_matched"].([]string)[1]
|
|
if id == "" {
|
|
id = ctx.State["regex_matched"].([]string)[2]
|
|
}
|
|
card, err := bz.GetVideoInfo(id)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR: ", err))
|
|
return
|
|
}
|
|
msg, err := videoCard2msg(card)
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR: ", err))
|
|
return
|
|
}
|
|
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
|
if ok && c.GetData(ctx.Event.GroupID)&enableHex == enableHex {
|
|
summaryMsg, err := getVideoSummary(cfg, card)
|
|
if err != nil {
|
|
msg = append(msg, message.Text("ERROR: ", err))
|
|
} else {
|
|
msg = append(msg, summaryMsg...)
|
|
}
|
|
}
|
|
ctx.SendChain(msg...)
|
|
}
|
|
|
|
func handleDynamic(ctx *zero.Ctx) {
|
|
msg, err := dynamicDetail(cfg, ctx.State["regex_matched"].([]string)[2])
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR: ", err))
|
|
return
|
|
}
|
|
ctx.SendChain(msg...)
|
|
}
|
|
|
|
func handleArticle(ctx *zero.Ctx) {
|
|
card, err := bz.GetArticleInfo(ctx.State["regex_matched"].([]string)[1])
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR: ", err))
|
|
return
|
|
}
|
|
ctx.SendChain(articleCard2msg(card, ctx.State["regex_matched"].([]string)[1])...)
|
|
}
|
|
|
|
func handleLive(ctx *zero.Ctx) {
|
|
card, err := bz.GetLiveRoomInfo(ctx.State["regex_matched"].([]string)[1])
|
|
if err != nil {
|
|
ctx.SendChain(message.Text("ERROR: ", err))
|
|
return
|
|
}
|
|
ctx.SendChain(liveCard2msg(card)...)
|
|
}
|
|
|
|
// getVideoSummary AI视频总结
|
|
func getVideoSummary(cookiecfg *bz.CookieConfig, card bz.Card) (msg []message.MessageSegment, err error) {
|
|
var (
|
|
data []byte
|
|
videoSummary bz.VideoSummary
|
|
)
|
|
data, err = web.RequestDataWithHeaders(web.NewDefaultClient(), bz.SignURL(fmt.Sprintf(bz.VideoSummaryURL, card.BvID, card.CID, card.Owner.Mid)), "GET", func(req *http.Request) error {
|
|
if cookiecfg != nil {
|
|
cookie := ""
|
|
cookie, err = cookiecfg.Load()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Add("cookie", cookie)
|
|
}
|
|
req.Header.Set("User-Agent", ua)
|
|
return nil
|
|
}, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = json.Unmarshal(data, &videoSummary)
|
|
msg = make([]message.MessageSegment, 0, 16)
|
|
msg = append(msg, message.Text("已为你生成视频总结\n\n"))
|
|
msg = append(msg, message.Text(videoSummary.Data.ModelResult.Summary, "\n\n"))
|
|
for _, v := range videoSummary.Data.ModelResult.Outline {
|
|
msg = append(msg, message.Text("● ", v.Title, "\n"))
|
|
for _, p := range v.PartOutline {
|
|
msg = append(msg, message.Text(fmt.Sprintf("%d:%d %s\n", p.Timestamp/60, p.Timestamp%60, p.Content)))
|
|
}
|
|
msg = append(msg, message.Text("\n"))
|
|
}
|
|
return
|
|
}
|