mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2026-02-12 18:20:27 +00:00
Feature zbpp bilibilipush 20230224 (#599)
* 🔥 删除小鸡词典 * ✨ 添加新插件和修改bilibilipush问题 * 🎨 去掉多余结构 * 🎨 简化语句
This commit is contained in:
321
plugin/vtbmusic/vtbmusic.go
Normal file
321
plugin/vtbmusic/vtbmusic.go
Normal file
@@ -0,0 +1,321 @@
|
||||
// Package vtbmusic vtb点歌
|
||||
package vtbmusic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/floatbox/binary"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
const (
|
||||
getGroupListURL = "https://aqua.chat/v1/GetGroupsList"
|
||||
getMusicListURL = "https://aqua.chat/v1/GetMusicList"
|
||||
fileURL = "https://cdn.aqua.chat/"
|
||||
musicListBody = `{"search":{"condition":"VocalId","keyword":"%v"},"sortField":"CreateTime","sortType":"desc","pageIndex":1,"pageRows":10000}`
|
||||
)
|
||||
|
||||
type groupsList struct {
|
||||
Total int `json:"Total"`
|
||||
Data []struct {
|
||||
ID string `json:"Id"`
|
||||
CreateTime string `json:"CreateTime"`
|
||||
Name string `json:"Name"`
|
||||
GroupImg string `json:"GroupImg"`
|
||||
VocalList []struct {
|
||||
ID string `json:"Id"`
|
||||
CreateTime string `json:"CreateTime"`
|
||||
ChineseName string `json:"ChineseName"`
|
||||
OriginName string `json:"OriginName"`
|
||||
AvatarImg string `json:"AvatarImg"`
|
||||
} `json:"VocalList"`
|
||||
} `json:"Data"`
|
||||
Success bool `json:"Success"`
|
||||
ErrorCode int `json:"ErrorCode"`
|
||||
Msg interface{} `json:"Msg"`
|
||||
}
|
||||
|
||||
type musicList struct {
|
||||
Total int `json:"Total"`
|
||||
Data []struct {
|
||||
ID string `json:"Id"`
|
||||
CreateTime string `json:"CreateTime"`
|
||||
PublishTime interface{} `json:"PublishTime"`
|
||||
CreatorID interface{} `json:"CreatorId"`
|
||||
CreatorRealName interface{} `json:"CreatorRealName"`
|
||||
Deleted bool `json:"Deleted"`
|
||||
OriginName string `json:"OriginName"`
|
||||
VocalID string `json:"VocalId"`
|
||||
VocalName string `json:"VocalName"`
|
||||
CoverImg string `json:"CoverImg"`
|
||||
Music string `json:"Music"`
|
||||
Lyric interface{} `json:"Lyric"`
|
||||
CDN string `json:"CDN"`
|
||||
BiliBili interface{} `json:"BiliBili"`
|
||||
YouTube interface{} `json:"YouTube"`
|
||||
Twitter interface{} `json:"Twitter"`
|
||||
Likes interface{} `json:"Likes"`
|
||||
Length float64 `json:"Length"`
|
||||
Label interface{} `json:"Label"`
|
||||
IsLike bool `json:"isLike"`
|
||||
Duration float64 `json:"Duration"`
|
||||
Source interface{} `json:"Source"`
|
||||
SourceName interface{} `json:"SourceName"`
|
||||
Statis struct {
|
||||
PlayCount int `json:"PlayCount"`
|
||||
CommentCount int `json:"CommentCount"`
|
||||
LikeCount int `json:"LikeCount"`
|
||||
ShareCount int `json:"ShareCount"`
|
||||
} `json:"Statis"`
|
||||
VocalList []struct {
|
||||
ID string `json:"Id"`
|
||||
Cn string `json:"cn"`
|
||||
Jp string `json:"jp"`
|
||||
En string `json:"en"`
|
||||
Originlang string `json:"originlang"`
|
||||
} `json:"VocalList"`
|
||||
} `json:"Data"`
|
||||
Success bool `json:"Success"`
|
||||
ErrorCode int `json:"ErrorCode"`
|
||||
Msg interface{} `json:"Msg"`
|
||||
}
|
||||
|
||||
func init() { // 插件主体
|
||||
engine := control.Register("vtbmusic", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "vtbmusic.com点歌",
|
||||
Help: "- vtb点歌\n" +
|
||||
"- vtb随机点歌",
|
||||
PrivateDataFolder: "vtbmusic",
|
||||
})
|
||||
storePath := engine.DataFolder()
|
||||
// 开启
|
||||
engine.OnFullMatch(`vtb点歌`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession(), zero.RegexRule(`^\d+$`))
|
||||
recv, cancel := next.Repeat()
|
||||
defer cancel()
|
||||
i := 0
|
||||
paras := [3]int{}
|
||||
data, err := web.PostData(getGroupListURL, "application/json", strings.NewReader(`{"PageIndex":1,"PageRows":9999}`))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
var (
|
||||
gl groupsList
|
||||
ml musicList
|
||||
num int
|
||||
imageBytes []byte
|
||||
)
|
||||
err = json.Unmarshal(data, &gl)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
tex := "请输入群组序号\n"
|
||||
for i, v := range gl.Data {
|
||||
tex += fmt.Sprintf("%d. %s\n", i, v.Name)
|
||||
}
|
||||
imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case <-time.After(time.Second * 120):
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("vtb点歌超时"))
|
||||
return
|
||||
case c := <-recv:
|
||||
msg := c.Event.Message.ExtractPlainText()
|
||||
num, err = strconv.Atoi(msg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请输入数字!"))
|
||||
continue
|
||||
}
|
||||
switch i {
|
||||
case 0:
|
||||
if num < 0 || num >= len(gl.Data) {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!"))
|
||||
continue
|
||||
}
|
||||
if len(gl.Data[num].VocalList) == 0 {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无内容, 点歌失败"))
|
||||
return
|
||||
}
|
||||
paras[0] = num
|
||||
tex = "请输入vtb序号\n"
|
||||
for i, v := range gl.Data[paras[0]].VocalList {
|
||||
tex += fmt.Sprintf("%d. %s\n", i, v.OriginName)
|
||||
}
|
||||
imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
case 1:
|
||||
if num < 0 || num >= len(gl.Data[paras[0]].VocalList) {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!"))
|
||||
continue
|
||||
}
|
||||
paras[1] = num
|
||||
data, err := web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID)))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(data, &ml)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if len(ml.Data) == 0 {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无内容, 点歌失败"))
|
||||
return
|
||||
}
|
||||
tex = "请输入歌曲序号\n"
|
||||
for i, v := range ml.Data {
|
||||
tex += fmt.Sprintf("%d. %s\n", i, v.OriginName)
|
||||
}
|
||||
imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
case 2:
|
||||
if num < 0 || num >= len(ml.Data) {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!"))
|
||||
continue
|
||||
}
|
||||
paras[2] = num
|
||||
// 最后播放歌曲
|
||||
groupName := gl.Data[paras[0]].Name
|
||||
vtbName := gl.Data[paras[0]].VocalList[paras[1]].OriginName
|
||||
musicName := ml.Data[paras[2]].OriginName
|
||||
recURL := fileURL + ml.Data[paras[2]].Music
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏", groupName, "-", vtbName, "的《", musicName, "》"))
|
||||
recordFile := storePath + fmt.Sprintf("%d-%d-%d", paras[0], paras[1], paras[2]) + path.Ext(recURL)
|
||||
if file.IsExist(recordFile) {
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
|
||||
return
|
||||
}
|
||||
err = dlrec(recordFile, recURL)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
|
||||
return
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
})
|
||||
engine.OnFullMatch(`vtb随机点歌`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var (
|
||||
paras = [3]int{}
|
||||
gl groupsList
|
||||
ml musicList
|
||||
)
|
||||
data, err := web.PostData(getGroupListURL, "application/json", strings.NewReader(`{"PageIndex":1,"PageRows":9999}`))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(data, &gl)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if len(gl.Data) == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 数组为空"))
|
||||
return
|
||||
}
|
||||
paras[0] = rand.Intn(len(gl.Data))
|
||||
for len(gl.Data[paras[0]].VocalList) == 0 {
|
||||
paras[0] = rand.Intn(len(gl.Data))
|
||||
}
|
||||
paras[1] = rand.Intn(len(gl.Data[paras[0]].VocalList))
|
||||
data, err = web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID)))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(data, &ml)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
for len(ml.Data) == 0 {
|
||||
paras[1] = rand.Intn(len(gl.Data[paras[0]].VocalList))
|
||||
data, err = web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID)))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(data, &ml)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
paras[2] = rand.Intn(len(ml.Data))
|
||||
// 最后播放歌曲
|
||||
groupName := gl.Data[paras[0]].Name
|
||||
vtbName := gl.Data[paras[0]].VocalList[paras[1]].OriginName
|
||||
musicName := ml.Data[paras[2]].OriginName
|
||||
recURL := fileURL + ml.Data[paras[2]].Music
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏", groupName, "-", vtbName, "的《", musicName, "》"))
|
||||
recordFile := storePath + fmt.Sprintf("%d-%d-%d", paras[0], paras[1], paras[2]) + path.Ext(recURL)
|
||||
if file.IsExist(recordFile) {
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
|
||||
return
|
||||
}
|
||||
err = dlrec(recordFile, recURL)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
|
||||
})
|
||||
}
|
||||
|
||||
func dlrec(recordFile, recordURL string) error {
|
||||
if file.IsNotExist(recordFile) {
|
||||
data, err := web.RequestDataWithHeaders(web.NewTLS12Client(), recordURL, "GET", func(r *http.Request) error {
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
r.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0")
|
||||
return nil
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(recordFile, data, 0666)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user