mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 22:00:11 +08:00
feat:添加b站推送功能 (#106)
* feat:添加b站推送,写了一半 * feat:添加b站推送(后续看情况,替换掉chromepd) * fix:修复一直推送直播的bug * fix:添加缓存路径 * feat:添加推送列表,修复重复发消息的bug * feat:发现禁用有用,删除多余指令 * fix:修改格式 * fix:sleep无效 * fix:修改直播card * fix:增加长度 * fix:修改readme * fix:修lint,并去掉cron * fix:修lint * fix:去掉日志 Co-authored-by: Guohuiyuan <haibaraguo@yeahka.com>
This commit is contained in:
parent
af8e6a63b9
commit
cb1e4bcdb7
@ -255,6 +255,13 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
|
||||
- [x] 骂我
|
||||
- [x] 大力骂我
|
||||
- [x] @bot 他妈|公交车|你妈|操|屎|去死|快死|日|逼|尼玛|艾滋|癌症|有病|戴套|啊对对对|烦你|你爹|屮|tui|cnm
|
||||
- **b站推送** `_ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili_push"`
|
||||
- [x] 添加订阅[uid]
|
||||
- [x] 取消订阅[uid]
|
||||
- [x] 取消动态订阅[uid]
|
||||
- [x] 取消直播订阅[uid]
|
||||
- [x] 推送列表
|
||||
- 注: linux下要想动态图片显示正常,需要下载chrome浏览器,并安装字体,具体看https://www.yuque.com/xiangrikuidezhongzi/zerobot/qrwxth
|
||||
- **TODO...**
|
||||
|
||||
## 使用方法
|
||||
|
||||
8
go.mod
8
go.mod
@ -6,6 +6,7 @@ require (
|
||||
github.com/FloatTech/AnimeAPI v1.2.4-beta1
|
||||
github.com/FloatTech/zbputils v1.2.4-beta1
|
||||
github.com/antchfx/htmlquery v1.2.4
|
||||
github.com/chromedp/chromedp v0.7.6
|
||||
github.com/corona10/goimagehash v1.0.3
|
||||
github.com/fogleman/gg v1.3.0
|
||||
github.com/fumiama/cron v1.3.0
|
||||
@ -25,16 +26,23 @@ require (
|
||||
|
||||
require (
|
||||
github.com/antchfx/xpath v1.2.0 // indirect
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77 // indirect
|
||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||
github.com/disintegration/imaging v1.6.2 // indirect
|
||||
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
|
||||
20
go.sum
20
go.sum
@ -13,6 +13,12 @@ github.com/antchfx/htmlquery v1.2.4/go.mod h1:2xO6iu3EVWs7R2JYqBbp8YzG50gj/ofqs5
|
||||
github.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
|
||||
github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8=
|
||||
github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77 h1:Et/9YcQRCsaZVT74sy6AHwWy/FcbYqm39jNprlfXF7c=
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+jA=
|
||||
github.com/chromedp/chromedp v0.7.6/go.mod h1:ayT4YU/MGAALNfOg9gNrpGSAdnU51PMx+FCeuT1iXzo=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/corona10/goimagehash v1.0.3 h1:NZM518aKLmoNluluhfHGxT3LGOnrojrxhGn63DR/CZA=
|
||||
github.com/corona10/goimagehash v1.0.3/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYMHl2ZJLn0mOGI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -51,6 +57,12 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
@ -78,6 +90,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
@ -90,6 +104,8 @@ github.com/logoove/sqlite v1.13.0 h1:XM7QKK9R3tm8o7bI75R3zmwYBFQ5S3Jqg+XCaqsAMQQ
|
||||
github.com/logoove/sqlite v1.13.0/go.mod h1:MRpE/o3qQhT7AgfIdnBue5c63+//xT+KXV0gHeVAUAg=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
@ -106,6 +122,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -193,6 +211,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -201,6 +220,7 @@ golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY=
|
||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
||||
1
main.go
1
main.go
@ -52,6 +52,7 @@ import (
|
||||
|
||||
// b站相关
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili" // 查询b站用户信息
|
||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili_push" // b站推送(需要安装chrome浏览器)
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_diana" // 嘉心糖发病
|
||||
|
||||
// 二次元图片
|
||||
|
||||
448
plugin_bilibili_push/bilibili_push.go
Normal file
448
plugin_bilibili_push/bilibili_push.go
Normal file
@ -0,0 +1,448 @@
|
||||
// Package bilibilipush b站推送
|
||||
package bilibilipush
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/FloatTech/zbputils/file"
|
||||
"github.com/FloatTech/zbputils/txt2img"
|
||||
"github.com/FloatTech/zbputils/web"
|
||||
"github.com/chromedp/chromedp"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
"github.com/wdvxdr1123/ZeroBot/utils/helper"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
|
||||
referer = "https://www.bilibili.com/"
|
||||
infoURL = "https://api.bilibili.com/x/space/acc/info?mid=%d"
|
||||
userDynamicsURL = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?host_uid=%d&offset_dynamic_id=0&need_top=0"
|
||||
liveListURL = "https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids"
|
||||
tURL = "https://t.bilibili.com/"
|
||||
liveURL = "https://live.bilibili.com/"
|
||||
prio = 10
|
||||
serviceName = "bilibilipush"
|
||||
)
|
||||
|
||||
var (
|
||||
lastTime = map[int64]int64{}
|
||||
typeMsg = map[int64]string{
|
||||
0: "发布了新动态",
|
||||
1: "转发了一条动态",
|
||||
2: "发布了新动态",
|
||||
4: "发布了新动态",
|
||||
8: "发布了新投稿",
|
||||
16: "发布了短视频",
|
||||
64: "发布了新专栏",
|
||||
256: "发布了新音频",
|
||||
}
|
||||
liveStatus = map[int64]int{}
|
||||
uidErrorMsg = map[int]string{
|
||||
0: "输入的uid有效",
|
||||
-400: "uid不存在,注意uid不是房间号",
|
||||
-402: "uid不存在,注意uid不是房间号",
|
||||
-412: "操作过于频繁IP暂时被风控,请半小时后再尝试",
|
||||
}
|
||||
upMap = map[int64]string{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
go bilibiliPushDaily()
|
||||
en := control.Register(serviceName, &control.Options{
|
||||
DisableOnDefault: false,
|
||||
Help: "bilibilipush\n" +
|
||||
"- 添加订阅[uid]\n" +
|
||||
"- 取消订阅[uid]\n" +
|
||||
"- 取消动态订阅[uid]\n" +
|
||||
"- 取消直播订阅[uid]\n" +
|
||||
"- 推送列表",
|
||||
})
|
||||
|
||||
en.OnRegex(`^添加订阅(\d+)$`, ctxext.UserOrGrpAdmin).SetBlock(true).SetPriority(prio).Handle(func(ctx *zero.Ctx) {
|
||||
buid, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
|
||||
var name string
|
||||
var ok bool
|
||||
if name, ok = upMap[buid]; !ok {
|
||||
var status int
|
||||
status, name = checkBuid(buid)
|
||||
if status != 0 {
|
||||
msg, ok := uidErrorMsg[status]
|
||||
if !ok {
|
||||
msg = "未知错误,请私聊反馈给" + zero.BotConfig.NickName[0]
|
||||
}
|
||||
ctx.SendChain(message.Text(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
if err := subscribe(buid, gid); err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
} else {
|
||||
ctx.SendChain(message.Text("已添加" + name + "的订阅"))
|
||||
}
|
||||
|
||||
})
|
||||
en.OnRegex(`^取消订阅(\d+)$`, ctxext.UserOrGrpAdmin).SetBlock(true).SetPriority(prio).Handle(func(ctx *zero.Ctx) {
|
||||
buid, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
|
||||
var name string
|
||||
var ok bool
|
||||
if name, ok = upMap[buid]; !ok {
|
||||
var status int
|
||||
status, name = checkBuid(buid)
|
||||
if status != 0 {
|
||||
msg, ok := uidErrorMsg[status]
|
||||
if !ok {
|
||||
msg = "未知错误,请私聊反馈给" + zero.BotConfig.NickName[0]
|
||||
}
|
||||
ctx.SendChain(message.Text(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
if err := unsubscribe(buid, gid); err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
} else {
|
||||
ctx.SendChain(message.Text("已取消" + name + "的订阅"))
|
||||
}
|
||||
|
||||
})
|
||||
en.OnRegex(`^取消动态订阅(\d+)$`, ctxext.UserOrGrpAdmin).SetBlock(true).SetPriority(prio).Handle(func(ctx *zero.Ctx) {
|
||||
buid, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
|
||||
var name string
|
||||
var ok bool
|
||||
if name, ok = upMap[buid]; !ok {
|
||||
var status int
|
||||
status, name = checkBuid(buid)
|
||||
if status != 0 {
|
||||
msg, ok := uidErrorMsg[status]
|
||||
if !ok {
|
||||
msg = "未知错误,请私聊反馈给" + zero.BotConfig.NickName[0]
|
||||
}
|
||||
ctx.SendChain(message.Text(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
if err := unsubscribeDynamic(buid, gid); err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
} else {
|
||||
ctx.SendChain(message.Text("已取消" + name + "的动态订阅"))
|
||||
}
|
||||
|
||||
})
|
||||
en.OnRegex(`^取消直播订阅(\d+)$`, ctxext.UserOrGrpAdmin).SetBlock(true).SetPriority(prio).Handle(func(ctx *zero.Ctx) {
|
||||
buid, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
|
||||
var name string
|
||||
var ok bool
|
||||
if name, ok = upMap[buid]; !ok {
|
||||
var status int
|
||||
status, name = checkBuid(buid)
|
||||
if status != 0 {
|
||||
msg, ok := uidErrorMsg[status]
|
||||
if !ok {
|
||||
msg = "未知错误,请私聊反馈给" + zero.BotConfig.NickName[0]
|
||||
}
|
||||
ctx.SendChain(message.Text(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
if err := unsubscribeLive(buid, gid); err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
} else {
|
||||
ctx.SendChain(message.Text("已取消" + name + "的直播订阅"))
|
||||
}
|
||||
|
||||
})
|
||||
en.OnFullMatch("推送列表", ctxext.UserOrGrpAdmin).SetBlock(true).SetPriority(prio).Handle(func(ctx *zero.Ctx) {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
bpl := bdb.getAllPushByGroup(gid)
|
||||
fmt.Println(bpl)
|
||||
msg := "--------推送列表--------"
|
||||
for _, v := range bpl {
|
||||
if _, ok := upMap[v.BilibiliUID]; !ok {
|
||||
bdb.updateAllUp()
|
||||
fmt.Println(upMap)
|
||||
}
|
||||
msg += fmt.Sprintf("\nuid:%-12d 动态:", v.BilibiliUID)
|
||||
if v.DynamicDisable == 0 {
|
||||
msg += "●"
|
||||
} else {
|
||||
msg += "○"
|
||||
}
|
||||
msg += " 直播:"
|
||||
if v.LiveDisable == 0 {
|
||||
msg += "●"
|
||||
} else {
|
||||
msg += "○"
|
||||
}
|
||||
msg += " up主:" + upMap[v.BilibiliUID]
|
||||
}
|
||||
data, err := txt2img.RenderToBase64(msg, txt2img.FontFile, 600, 20)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func bilibiliPushDaily() {
|
||||
t := time.NewTicker(time.Second * 10)
|
||||
defer t.Stop()
|
||||
for range t.C {
|
||||
log.Println("-----bilibilipush拉取推送信息-----")
|
||||
sendDynamic()
|
||||
sendLive()
|
||||
}
|
||||
}
|
||||
|
||||
func checkBuid(buid int64) (status int, name string) {
|
||||
data, err := web.ReqWith(fmt.Sprintf(infoURL, buid), "GET", referer, ua)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
status = int(gjson.Get(helper.BytesToString(data), "code").Int())
|
||||
name = gjson.Get(helper.BytesToString(data), "data.name").String()
|
||||
if status == 0 {
|
||||
bdb.insertBilibiliUp(buid, name)
|
||||
upMap[buid] = name
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// subscribe 订阅
|
||||
func subscribe(buid, groupid int64) (err error) {
|
||||
bpMap := map[string]interface{}{
|
||||
"bilibili_uid": buid,
|
||||
"group_id": groupid,
|
||||
"live_disable": 0,
|
||||
"dynamic_disable": 0,
|
||||
}
|
||||
err = bdb.insertOrUpdateLiveAndDynamic(bpMap)
|
||||
return
|
||||
}
|
||||
|
||||
// unsubscribe 取消订阅
|
||||
func unsubscribe(buid, groupid int64) (err error) {
|
||||
bpMap := map[string]interface{}{
|
||||
"bilibili_uid": buid,
|
||||
"group_id": groupid,
|
||||
"live_disable": 1,
|
||||
"dynamic_disable": 1,
|
||||
}
|
||||
err = bdb.insertOrUpdateLiveAndDynamic(bpMap)
|
||||
return
|
||||
}
|
||||
|
||||
func unsubscribeDynamic(buid, groupid int64) (err error) {
|
||||
bpMap := map[string]interface{}{
|
||||
"bilibili_uid": buid,
|
||||
"group_id": groupid,
|
||||
"dynamic_disable": 1,
|
||||
}
|
||||
err = bdb.insertOrUpdateLiveAndDynamic(bpMap)
|
||||
return
|
||||
}
|
||||
|
||||
func unsubscribeLive(buid, groupid int64) (err error) {
|
||||
bpMap := map[string]interface{}{
|
||||
"bilibili_uid": buid,
|
||||
"group_id": groupid,
|
||||
"live_disable": 1,
|
||||
}
|
||||
err = bdb.insertOrUpdateLiveAndDynamic(bpMap)
|
||||
return
|
||||
}
|
||||
|
||||
func getUserDynamicCard(buid int64) (cardList []gjson.Result) {
|
||||
data, err := web.ReqWith(fmt.Sprintf(userDynamicsURL, buid), "GET", referer, ua)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
cardList = gjson.Get(helper.BytesToString(data), "data.cards").Array()
|
||||
return
|
||||
}
|
||||
|
||||
func getLiveList(uids ...int64) string {
|
||||
m := make(map[string]interface{})
|
||||
m["uids"] = uids
|
||||
b, _ := json.Marshal(m)
|
||||
client := &http.Client{}
|
||||
// 提交请求
|
||||
request, err := http.NewRequest("POST", liveListURL, bytes.NewBuffer(b))
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
request.Header.Add("Referer", referer)
|
||||
request.Header.Add("User-Agent", ua)
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
data, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
return helper.BytesToString(data)
|
||||
}
|
||||
|
||||
func sendDynamic() {
|
||||
uids := bdb.getAllBuidByDynamic()
|
||||
for _, buid := range uids {
|
||||
cardList := getUserDynamicCard(buid)
|
||||
if len(cardList) == 0 {
|
||||
return
|
||||
}
|
||||
t, ok := lastTime[buid]
|
||||
if !ok {
|
||||
lastTime[buid] = cardList[0].Get("desc.timestamp").Int()
|
||||
return
|
||||
}
|
||||
for i := len(cardList) - 1; i >= 0; i-- {
|
||||
ct := cardList[i].Get("desc.timestamp").Int()
|
||||
if ct > t && ct > time.Now().Unix()-600 {
|
||||
lastTime[buid] = ct
|
||||
m, ok := control.Lookup(serviceName)
|
||||
if ok {
|
||||
groupList := bdb.getAllGroupByBuidAndDynamic(buid)
|
||||
cID := cardList[i].Get("desc.dynamic_id").String()
|
||||
cType := cardList[i].Get("desc.type").Int()
|
||||
cName := cardList[i].Get("desc.user_profile.info.uname").String()
|
||||
screenshotFile := cachePath + cID + ".png"
|
||||
initDynamicScreenshot(cID)
|
||||
var msg []message.MessageSegment
|
||||
msg = append(msg, message.Text(cName+typeMsg[cType]))
|
||||
msg = append(msg, message.Image("file:///"+file.BOTPATH+"/"+screenshotFile))
|
||||
msg = append(msg, message.Text(tURL+cID))
|
||||
|
||||
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
|
||||
for _, gid := range groupList {
|
||||
if m.IsEnabledIn(gid) {
|
||||
if gid > 0 {
|
||||
ctx.SendGroupMessage(gid, msg)
|
||||
} else if gid < 0 {
|
||||
ctx.SendPrivateMessage(-gid, msg)
|
||||
} else {
|
||||
log.Errorln("[bilibilipush]:gid为0")
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func sendLive() {
|
||||
uids := bdb.getAllBuidByLive()
|
||||
gjson.Get(getLiveList(uids...), "data").ForEach(func(key, value gjson.Result) bool {
|
||||
newStatus := int(value.Get("live_status").Int())
|
||||
if newStatus == 2 {
|
||||
newStatus = 0
|
||||
}
|
||||
if _, ok := liveStatus[key.Int()]; !ok {
|
||||
liveStatus[key.Int()] = newStatus
|
||||
return true
|
||||
}
|
||||
oldStatus := liveStatus[key.Int()]
|
||||
if newStatus != oldStatus && newStatus == 1 {
|
||||
liveStatus[key.Int()] = newStatus
|
||||
m, ok := control.Lookup(serviceName)
|
||||
if ok {
|
||||
groupList := bdb.getAllGroupByBuidAndLive(key.Int())
|
||||
roomID := value.Get("short_id").Int()
|
||||
if roomID == 0 {
|
||||
roomID = value.Get("room_id").Int()
|
||||
}
|
||||
lURL := liveURL + strconv.FormatInt(roomID, 10)
|
||||
lName := value.Get("uname").String()
|
||||
lTitle := value.Get("title").String()
|
||||
lCover := value.Get("cover_from_user").String()
|
||||
if lCover == "" {
|
||||
lCover = value.Get("keyframe").String()
|
||||
}
|
||||
var msg []message.MessageSegment
|
||||
msg = append(msg, message.Text(lName+" 正在直播:\n"))
|
||||
msg = append(msg, message.Text(lTitle))
|
||||
msg = append(msg, message.Image(lCover))
|
||||
msg = append(msg, message.Text(lURL))
|
||||
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
|
||||
for _, gid := range groupList {
|
||||
if m.IsEnabledIn(gid) {
|
||||
if gid > 0 {
|
||||
ctx.SendGroupMessage(gid, msg)
|
||||
} else if gid < 0 {
|
||||
ctx.SendPrivateMessage(-gid, msg)
|
||||
} else {
|
||||
log.Errorln("[bilibilipush]:gid为0")
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func initDynamicScreenshot(dynamicID string) {
|
||||
screenshotFile := cachePath + dynamicID + ".png"
|
||||
if file.IsNotExist(screenshotFile) {
|
||||
var imageBuf []byte
|
||||
dynamicURL := tURL + dynamicID
|
||||
ctx, cancel := chromedp.NewContext(context.Background(), chromedp.WithDebugf(log.Printf))
|
||||
defer cancel()
|
||||
|
||||
if err := chromedp.Run(ctx, chromedp.Tasks{
|
||||
chromedp.Navigate(dynamicURL),
|
||||
chromedp.SetAttributeValue(`div.unlogin-popover-avatar`, "style", "display:none;", chromedp.ByQuery),
|
||||
chromedp.SetAttributeValue(`div.bb-comment`, "style", "display:none;", chromedp.ByQuery),
|
||||
chromedp.Screenshot(`.card`, &imageBuf, chromedp.NodeVisible, chromedp.ByQuery),
|
||||
}); err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(screenshotFile, imageBuf, 0644); err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
28
plugin_bilibili_push/data.go
Normal file
28
plugin_bilibili_push/data.go
Normal file
@ -0,0 +1,28 @@
|
||||
package bilibilipush
|
||||
|
||||
import (
|
||||
"github.com/FloatTech/zbputils/process"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
cachePath = dbpath + "cache/"
|
||||
dbpath = "data/bilibilipush/"
|
||||
dbfile = dbpath + "push.db"
|
||||
)
|
||||
|
||||
// bdb bilibili推送数据库
|
||||
var bdb *bilibilipushdb
|
||||
|
||||
// 加载数据库
|
||||
func init() {
|
||||
go func() {
|
||||
process.SleepAbout1sTo2s()
|
||||
_ = os.MkdirAll(dbpath, 0755)
|
||||
os.RemoveAll(cachePath)
|
||||
_ = os.MkdirAll(cachePath, 0755)
|
||||
bdb = initialize(dbfile)
|
||||
log.Println("[bilibilipush]加载bilibilipush数据库")
|
||||
}()
|
||||
}
|
||||
158
plugin_bilibili_push/model.go
Normal file
158
plugin_bilibili_push/model.go
Normal file
@ -0,0 +1,158 @@
|
||||
package bilibilipush
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/logoove/sqlite" // import sql
|
||||
"os"
|
||||
)
|
||||
|
||||
// bilibilipushdb bili推送数据库
|
||||
type bilibilipushdb gorm.DB
|
||||
|
||||
type bilibilipush struct {
|
||||
ID int64 `gorm:"column:id;primary_key" json:"id"`
|
||||
BilibiliUID int64 `gorm:"column:bilibili_uid;index:idx_buid_gid" json:"bilibili_uid"`
|
||||
GroupID int64 `gorm:"column:group_id;index:idx_buid_gid" json:"group_id"`
|
||||
LiveDisable int64 `gorm:"column:live_disable;default:0" json:"live_disable"`
|
||||
DynamicDisable int64 `gorm:"column:dynamic_disable;default:0" json:"dynamic_disable"`
|
||||
}
|
||||
|
||||
// TableName ...
|
||||
func (bilibilipush) TableName() string {
|
||||
return "bilibili_push"
|
||||
}
|
||||
|
||||
type bilibiliup struct {
|
||||
BilibiliUID int64 `gorm:"column:bilibili_uid;primary_key"`
|
||||
Name string `gorm:"column:name"`
|
||||
}
|
||||
|
||||
// TableName ...
|
||||
func (bilibiliup) TableName() string {
|
||||
return "bilibili_up"
|
||||
}
|
||||
|
||||
// initialize 初始化ScoreDB数据库
|
||||
func initialize(dbpath string) *bilibilipushdb {
|
||||
var err error
|
||||
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
|
||||
// 生成文件
|
||||
f, err := os.Create(dbpath)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer f.Close()
|
||||
}
|
||||
gdb, err := gorm.Open("sqlite3", dbpath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
gdb.AutoMigrate(&bilibilipush{}).AutoMigrate(&bilibiliup{})
|
||||
return (*bilibilipushdb)(gdb)
|
||||
}
|
||||
|
||||
// open ...
|
||||
func open(dbpath string) (*bilibilipushdb, error) {
|
||||
db, err := gorm.Open("sqlite3", dbpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return (*bilibilipushdb)(db), nil
|
||||
}
|
||||
|
||||
// close ...
|
||||
func (bdb *bilibilipushdb) close() error {
|
||||
db := (*gorm.DB)(bdb)
|
||||
return db.Close()
|
||||
}
|
||||
|
||||
// insertOrUpdateLiveAndDynamic 插入或更新数据库
|
||||
func (bdb *bilibilipushdb) insertOrUpdateLiveAndDynamic(bpMap map[string]interface{}) (err error) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
bp := bilibilipush{}
|
||||
data, _ := json.Marshal(&bpMap)
|
||||
_ = json.Unmarshal(data, &bp)
|
||||
if err = db.Debug().Model(&bilibilipush{}).First(&bp, "bilibili_uid = ? and group_id = ?", bp.BilibiliUID, bp.GroupID).Error; err != nil {
|
||||
if gorm.IsRecordNotFoundError(err) {
|
||||
err = db.Debug().Model(&bilibilipush{}).Create(&bp).Error
|
||||
}
|
||||
} else {
|
||||
err = db.Debug().Model(&bilibilipush{}).Where("bilibili_uid = ? and group_id = ?", bp.BilibiliUID, bp.GroupID).Update(bpMap).Error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) getAllBuidByLive() (buidList []int64) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
var bpl []bilibilipush
|
||||
db.Debug().Model(&bilibilipush{}).Find(&bpl, "live_disable = 0")
|
||||
temp := make(map[int64]bool)
|
||||
for _, v := range bpl {
|
||||
_, ok := temp[v.BilibiliUID]
|
||||
if !ok {
|
||||
buidList = append(buidList, v.BilibiliUID)
|
||||
temp[v.BilibiliUID] = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) getAllBuidByDynamic() (buidList []int64) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
var bpl []bilibilipush
|
||||
db.Debug().Model(&bilibilipush{}).Find(&bpl, "dynamic_disable = 0")
|
||||
temp := make(map[int64]bool)
|
||||
for _, v := range bpl {
|
||||
_, ok := temp[v.BilibiliUID]
|
||||
if !ok {
|
||||
buidList = append(buidList, v.BilibiliUID)
|
||||
temp[v.BilibiliUID] = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) getAllGroupByBuidAndLive(buid int64) (groupList []int64) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
var bpl []bilibilipush
|
||||
db.Debug().Model(&bilibilipush{}).Find(&bpl, "bilibili_uid = ? and live_disable = 0", buid)
|
||||
for _, v := range bpl {
|
||||
groupList = append(groupList, v.GroupID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) getAllGroupByBuidAndDynamic(buid int64) (groupList []int64) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
var bpl []bilibilipush
|
||||
db.Debug().Model(&bilibilipush{}).Find(&bpl, "bilibili_uid = ? and dynamic_disable = 0", buid)
|
||||
for _, v := range bpl {
|
||||
groupList = append(groupList, v.GroupID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) getAllPushByGroup(groupID int64) (bpl []bilibilipush) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
db.Debug().Model(&bilibilipush{}).Find(&bpl, "group_id = ? and (live_disable = 0 or dynamic_disable = 0)", groupID)
|
||||
return
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) insertBilibiliUp(buid int64, name string) {
|
||||
db := (*gorm.DB)(bdb)
|
||||
bu := bilibiliup{
|
||||
BilibiliUID: buid,
|
||||
Name: name,
|
||||
}
|
||||
db.Debug().Model(&bilibiliup{}).Create(bu)
|
||||
}
|
||||
|
||||
func (bdb *bilibilipushdb) updateAllUp() {
|
||||
db := (*gorm.DB)(bdb)
|
||||
var bul []bilibiliup
|
||||
db.Debug().Model(&bilibiliup{}).Find(&bul)
|
||||
for _, v := range bul {
|
||||
upMap[v.BilibiliUID] = v.Name
|
||||
}
|
||||
}
|
||||
@ -76,7 +76,7 @@ func (sdb *scoredb) InsertOrUpdateScoreByUID(uid int64, score int) (err error) {
|
||||
if err = db.Debug().Model(&scoretable{}).First(&s, "uid = ? ", uid).Error; err != nil {
|
||||
// error handling...
|
||||
if gorm.IsRecordNotFoundError(err) {
|
||||
db.Debug().Model(&scoretable{}).Create(&s) // newUser not user
|
||||
err = db.Debug().Model(&scoretable{}).Create(&s).Error // newUser not user
|
||||
}
|
||||
} else {
|
||||
err = db.Debug().Model(&scoretable{}).Where("uid = ? ", uid).Update(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user