feat(bilibili): bilibili login

This commit is contained in:
mei
2026-04-05 22:28:38 +08:00
parent 202f53915f
commit 52dc548c53
10 changed files with 73 additions and 193 deletions
+25
View File
@@ -1,6 +1,8 @@
package rule package rule
import ( import (
"strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/ssdomei232/goodBaby/api/user" "github.com/ssdomei232/goodBaby/api/user"
"github.com/ssdomei232/goodBaby/handler/db" "github.com/ssdomei232/goodBaby/handler/db"
@@ -60,3 +62,26 @@ func HandleCreateRule(c *gin.Context) {
c.JSON(200, gin.H{"code": 200, "data": "规则创建成功"}) c.JSON(200, gin.H{"code": 200, "data": "规则创建成功"})
} }
// 根据删除规则
func HandleDeleteRule(c *gin.Context) {
userInfo, err := user.GetUserInfoByGinCtx(c)
if err != nil {
c.JSON(401, gin.H{"code": 401, "data": "获取用户信息失败"})
return
}
ruleID, err := strconv.Atoi(c.Param("ruleID"))
if err != nil {
c.JSON(400, gin.H{"code": 400, "data": "规则 ID 格式错误"})
return
}
err = DeleteRuleByID(uint(ruleID), userInfo.ID)
if err != nil {
c.JSON(500, gin.H{"code": 500, "data": "删除规则失败"})
return
}
c.JSON(200, gin.H{"code": 200, "data": "规则删除成功"})
}
+17
View File
@@ -0,0 +1,17 @@
package rule
import (
"github.com/ssdomei232/goodBaby/handler/db"
"github.com/ssdomei232/goodBaby/model"
)
// 根据 ID 删除规则
func DeleteRuleByID(id uint, uid uint) error {
gormDB, err := db.GetGormDB()
if err != nil {
return err
}
result := gormDB.Where("id = ? AND uid = ?", id, uid).Delete(&model.Rule{})
return result.Error
}
-37
View File
@@ -1,37 +0,0 @@
{
"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": "xx_123",
"age": 16,
"cause_stop": "自杀"
},
"github_config": {
"owner": "example",
"repos": ["example-repo1", "example-repo2"],
"token": "ghp_xxxx"
},
"dingtalk_bot": {
"access_token": "xxx",
"secret": "xxx"
},
"onebot_config": {
"url": "http://localhost:5700",
"token": "xxx",
"send_groups": [12345678, 87654321],
"msg": "这是OneBot的消息内容。"
}
}
+8 -8
View File
@@ -1,5 +1,13 @@
# Bilibili # Bilibili
## Account Config
```json
{
"raw_cookies": "xxxx"
}
```
## Dynamic Config ## Dynamic Config
```json ```json
@@ -7,11 +15,3 @@
"msg": "something" "msg": "something"
} }
``` ```
## Account Config
```json
{
"cookies_string": "xxxx"
}
```
-30
View File
@@ -1,30 +0,0 @@
package bilibili
import (
"log"
"os"
"github.com/CuteReimu/bilibili/v2"
)
// Qrcode login
func HandleLoginWithQRCode(biliClient *bilibili.Client) {
qrCode, err := biliClient.GetQRCode()
if err != nil {
log.Printf("获取二维码失败: %v", err)
return
}
buf, _ := qrCode.Encode()
os.WriteFile("tmp/qrcode.png", buf, 0644)
qrCode.Print()
result, err := biliClient.LoginWithQRCode(bilibili.LoginWithQRCodeParam{
QrcodeKey: qrCode.QrcodeKey,
})
if err != nil || result.Code != 0 {
log.Printf("登录失败: %v", err)
return
}
log.Println("登录成功")
}
+1 -1
View File
@@ -1,7 +1,7 @@
package bilibili package bilibili
type BiliAccount struct { type BiliAccount struct {
CookiesString string `json:"cookies_string"` RawCookies string `json:"raw_cookies"`
} }
type BiliDynamicRule struct { type BiliDynamicRule struct {
+1 -99
View File
@@ -2,110 +2,12 @@ package bilibili
import ( import (
"encoding/json" "encoding/json"
"log"
"net/http"
"strings"
"time"
"github.com/CuteReimu/bilibili/v2" "github.com/CuteReimu/bilibili/v2"
"github.com/ssdomei232/goodBaby/handler/db" "github.com/ssdomei232/goodBaby/handler/db"
"github.com/ssdomei232/goodBaby/model" "github.com/ssdomei232/goodBaby/model"
) )
// 检查cookie是否过期
func isCookiesExpired(cookiesString string) bool {
// 从cookie字符串中提取过期时间
lines := strings.SplitSeq(cookiesString, "\n")
for line := range lines {
if strings.Contains(line, "Expires=") {
// 提取过期时间字符串
expireStr := ""
parts := strings.SplitSeq(line, ";")
for part := range parts {
part = strings.TrimSpace(part)
if after, ok := strings.CutPrefix(part, "Expires="); ok {
expireStr = after
break
}
}
if expireStr != "" {
// 解析过期时间
expireTime, err := http.ParseTime(expireStr)
if err != nil {
log.Printf("解析过期时间失败: %v", err)
return true // 如果解析失败,cookie已过期
}
if time.Now().After(expireTime) {
return true
}
}
}
}
return false
}
// 检查cookie是否即将过期(提前1天)
func isCookiesExpiringSoon(cookiesString string) bool {
lines := strings.SplitSeq(cookiesString, "\n")
for line := range lines {
if strings.Contains(line, "Expires=") {
// 提取过期时间字符串
expireStr := ""
parts := strings.SplitSeq(line, ";")
for part := range parts {
part = strings.TrimSpace(part)
if after, ok := strings.CutPrefix(part, "Expires="); ok {
expireStr = after
break
}
}
if expireStr != "" {
// 解析过期时间
expireTime, err := http.ParseTime(expireStr)
if err != nil {
log.Printf("解析过期时间失败: %v", err)
return true // 如果解析失败,认为需要重新登录
}
// 检查是否即将过期(提前1天)
if time.Now().Add(24 * time.Hour).After(expireTime) {
return true // 即将过期
}
}
}
}
return false
}
// 触发登录请求
func triggerLoginRequest(biliClient *bilibili.Client) {
// 生成新的二维码
qrCode, err := biliClient.GetQRCode()
if err != nil {
log.Printf("获取二维码失败: %v", err)
return
}
// 在命令行打印二维码
log.Println("需要重新登录哔哩哔哩")
qrCode.Print()
// 通过Dingtalk发送登录请求
// title := "B站登录请求 - Cookie即将过期"
// msg := "您的B站cookie即将过期,请尽快重启摇篮系统进行登陆,请尽快完成登录操作。"
// 发送Dingtalk通知
// if config.DingtalkBot.AccessToken != "" && config.DingtalkBot.Secret != "" {
// SendDingTalkMsg(title, msg, config.DingtalkBot.AccessToken, config.DingtalkBot.Secret)
// }
}
// 获取 Bilibili Client // 获取 Bilibili Client
func GetBiliClient(rule *model.Rule) (*bilibili.Client, error) { func GetBiliClient(rule *model.Rule) (*bilibili.Client, error) {
client := bilibili.New() client := bilibili.New()
@@ -128,7 +30,7 @@ func GetBiliClient(rule *model.Rule) (*bilibili.Client, error) {
return nil, err return nil, err
} }
client.SetCookiesString(biliAccountConfig.CookiesString) client.SetRawCookies(biliAccountConfig.RawCookies)
return client, nil return client, nil
} }
+20 -2
View File
@@ -1,5 +1,23 @@
// dingtalk 仅用于发送提醒
package dingtalk package dingtalk
import "github.com/ssdomei232/goodBaby/model" import (
"log"
func SendDingTalkMsg(user *model.User, title string, msg string) {} "github.com/CatchZeng/dingtalk/pkg/dingtalk"
"github.com/ssdomei232/goodBaby/model"
)
func SendDingTalkMsg(user *model.User, title string, msg string) {
dingtalkAccount := getDingTalkConfigFromUser(user)
if dingtalkAccount == nil {
return
}
client := dingtalk.NewClient(dingtalkAccount.AccessToken, dingtalkAccount.Secret)
sendMsg := dingtalk.NewMarkdownMessage().SetMarkdown(title, msg)
_, _, err := client.Send(sendMsg)
if err != nil {
log.Printf("发送钉钉消息失败: %v", err)
}
}
-16
View File
@@ -1,16 +0,0 @@
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)
}
}
+1
View File
@@ -30,6 +30,7 @@ func main() {
authorized.GET("/user/info", user.HandleGetUserInfo) authorized.GET("/user/info", user.HandleGetUserInfo)
authorized.GET("/rules", rule.HandleGetAllRules) authorized.GET("/rules", rule.HandleGetAllRules)
authorized.POST("/rules", rule.HandleCreateRule) authorized.POST("/rules", rule.HandleCreateRule)
authorized.DELETE("/rules/:ruleID", rule.HandleDeleteRule)
authorized.GET("/accounts", account.HandleGetAllAccounts) authorized.GET("/accounts", account.HandleGetAllAccounts)
authorized.POST("/accounts", account.HandleAddAccount) authorized.POST("/accounts", account.HandleAddAccount)
} }