first commit
This commit is contained in:
commit
91c3337f46
11
README.md
Normal file
11
README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# 中V监测器
|
||||
|
||||
监测中V歌曲并通知到钉钉,写的比较粗糙,十分钟干完(距离凉雨传说还有几百播放的时候,最后成功检测到凉雨传说),搭配 NineVocalRank 使用
|
||||
|
||||
```shell
|
||||
(base) mei@mei-SuperPC:~/work/v-alerm$ ./v-alarm
|
||||
2025/08/28 14:58:34 &{{1000010 23104 35676 46579 9343 5842 3753} {396194 COPY 【洛天依原创】凉雨【PV付/COSMOSⅡ】 http://i1.hdslb.com/bfs/archive/dce146224f830f84618e1e3caffa42800ae611de.jpg 1 1756364314} {8786522 BV12x411y7SN 30} {6730 330 287 244 394 128 78} {9939.34 传说曲 7 10.0001}}
|
||||
2025/08/28 14:58:39 &{{1000010 23104 35676 46579 9345 5842 3753} {396194 COPY 【洛天依原创】凉雨【PV付/COSMOSⅡ】 http://i1.hdslb.com/bfs/archive/dce146224f830f84618e1e3caffa42800ae611de.jpg 1 1756364319} {8786522 BV12x411y7SN 30} {6730 330 287 244 396 128 78} {9944.74 传说曲 7 10.0001}}
|
||||
2025/08/28 14:58:44 &{{1000010 23104 35676 46579 9343 5842 3753} {396194 COPY 【洛天依原创】凉雨【PV付/COSMOSⅡ】 http://i1.hdslb.com/bfs/archive/dce146224f830f84618e1e3caffa42800ae611de.jpg 1 1756364324} {8786522 BV12x411y7SN 30} {6730 330 287 244 394 128 78} {9939.34 传说曲 7 10.0001}}
|
||||
2025/08/28 14:58:49 &{{1000010 23104 35676 46579 9344 5842 3753} {396194 COPY 【洛天依原创】凉雨【PV付/COSMOSⅡ】 http://i1.hdslb.com/bfs/archive/dce146224f830f84618e1e3caffa42800ae611de.jpg 1 1756364329} {8786522 BV12x411y7SN 30} {6730 330 287 244 395 128 78} {9942.04 传说曲 7 10.0001}}
|
||||
```
|
6
configs/config.go
Normal file
6
configs/config.go
Normal file
@ -0,0 +1,6 @@
|
||||
package configs
|
||||
|
||||
const (
|
||||
DingTalkURL = ""
|
||||
BVID = "BV12x411y7SN"
|
||||
)
|
5
go.mod
Normal file
5
go.mod
Normal file
@ -0,0 +1,5 @@
|
||||
module git.mmeiblog.cn/mei/v-alarm
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require github.com/robfig/cron v1.2.0
|
2
go.sum
Normal file
2
go.sum
Normal file
@ -0,0 +1,2 @@
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
24
internal/alerm.go
Normal file
24
internal/alerm.go
Normal file
@ -0,0 +1,24 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.mmeiblog.cn/mei/v-alarm/configs"
|
||||
)
|
||||
|
||||
func Alerm() {
|
||||
SongData, err := Monitor(configs.BVID)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if SongData.Video_stat.View >= 1000000 {
|
||||
timestamp := time.Unix(SongData.Video_info.Timestamp, 0)
|
||||
message := fmt.Sprintf("歌曲%s已达成传说,信息输出在日志,达成时间:%s",
|
||||
SongData.Video_info.Title,
|
||||
timestamp.Format("2006-01-02 15:04:05"))
|
||||
SendDingTalkNotification(message)
|
||||
log.Println(SongData)
|
||||
}
|
||||
}
|
36
internal/dingTalk.go
Normal file
36
internal/dingTalk.go
Normal file
@ -0,0 +1,36 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.mmeiblog.cn/mei/v-alarm/configs"
|
||||
)
|
||||
|
||||
func SendDingTalkNotification(message string) error {
|
||||
msg := map[string]any{
|
||||
"msgtype": "text",
|
||||
"text": map[string]string{"content": message},
|
||||
}
|
||||
jsonBytes, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequest("POST", configs.DingTalkURL, strings.NewReader(string(jsonBytes)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("钉钉API请求失败,状态码: %d", resp.StatusCode)
|
||||
}
|
||||
return nil
|
||||
}
|
90
internal/monitor.go
Normal file
90
internal/monitor.go
Normal file
@ -0,0 +1,90 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type SongMessage struct {
|
||||
Video_stat VideoStat `json:"video_stat"`
|
||||
Video_info VideoInfo `json:"video_info"`
|
||||
Video_id VideoID `json:"video_id"`
|
||||
Video_increase VideoIncrease `json:"video_increase"`
|
||||
Vrank_info VrankInfo `json:"vrank_info"`
|
||||
}
|
||||
|
||||
type VideoStat struct {
|
||||
View int `json:"view"`
|
||||
Like int `json:"like"`
|
||||
Coin int `json:"coin"`
|
||||
Favorite int `json:"favorite"`
|
||||
Reply int `json:"reply"`
|
||||
Share int `json:"share"`
|
||||
Danmaku int `json:"danmaku"`
|
||||
}
|
||||
|
||||
type VideoInfo struct {
|
||||
Uploader_mid string `json:"uploader_mid"`
|
||||
Uploader_name string `json:"uploader_name"`
|
||||
Title string `json:"title"`
|
||||
Pic string `json:"pic"`
|
||||
Pages int `json:"pages"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type VideoID struct {
|
||||
Avid string `json:"avid"`
|
||||
Bvid string `json:"bvid"`
|
||||
Tid int `json:"tid"`
|
||||
}
|
||||
|
||||
type VideoIncrease struct {
|
||||
View int `json:"view"`
|
||||
Like int `json:"like"`
|
||||
Coin int `json:"coin"`
|
||||
Favorite int `json:"favorite"`
|
||||
Reply int `json:"reply"`
|
||||
Share int `json:"share"`
|
||||
Danmaku int `json:"danmaku"`
|
||||
}
|
||||
|
||||
type VrankInfo struct {
|
||||
Vrank_score float64 `json:"vrank_score"`
|
||||
Rank string `json:"rank"`
|
||||
Rank_code int `json:"rank_code"`
|
||||
Progress_percentage float64 `json:"progress_percentage"`
|
||||
}
|
||||
|
||||
func Monitor(bvid string) (SongData *SongMessage, error error) {
|
||||
|
||||
url := fmt.Sprintf("https://api.mmeiblog.cn/NineVocalRank/vocaloid_rank/v1/video/%s", bvid)
|
||||
method := "GET"
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return
|
||||
}
|
||||
|
||||
var Data SongMessage
|
||||
err = json.Unmarshal(body, &Data)
|
||||
if err != nil {
|
||||
log.Printf("解析JSON失败: %v\n", err)
|
||||
return nil, err
|
||||
}
|
||||
return &Data, nil
|
||||
}
|
26
main.go
Normal file
26
main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"git.mmeiblog.cn/mei/v-alarm/internal"
|
||||
"github.com/robfig/cron"
|
||||
)
|
||||
|
||||
// 写的比较粗糙,十分钟干完(距离凉雨传说还有几百播放的时候,最后成功检测到凉雨传说)
|
||||
func main() {
|
||||
c := cron.New()
|
||||
|
||||
c.AddFunc("@every 5s", internal.Alerm)
|
||||
|
||||
c.Start()
|
||||
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
|
||||
<-sig // 阻塞直到收到信号
|
||||
fmt.Printf("Hava a good Day!")
|
||||
c.Stop() // 关闭 cron
|
||||
}
|
Loading…
Reference in New Issue
Block a user