-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
453 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import { appConfig } from 'app.config' | ||
import axios from 'axios' | ||
import { CronJob } from 'cron' | ||
import type { PluginFunction } from '~/lib/plugin' | ||
import type { BLRoom } from './types/room' | ||
import type { BLUser } from './types/user' | ||
|
||
import { userAgent } from '~/constants' | ||
|
||
const headers = { | ||
referer: `https://link.bilibili.com/p/center/index?visit_id=22ast2mb9zhc`, | ||
'User-Agent': userAgent, | ||
} | ||
export const register: PluginFunction = (ctx) => { | ||
let playStatus = false | ||
const config = appConfig.bilibili | ||
|
||
const liveId = config.live.id | ||
const work = async () => { | ||
const res = await axios | ||
.get( | ||
`https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo?room_id=${liveId}&protocol=0,1&format=0,1,2&codec=0,1&qn=0&platform=web&ptype=8&dolby=5`, | ||
{ | ||
headers, | ||
}, | ||
) | ||
.catch(() => null) | ||
|
||
if (!res?.data) { | ||
return | ||
} | ||
|
||
if (res?.data?.data.playurl_info) { | ||
if (playStatus) { | ||
return | ||
} | ||
|
||
const userInfo = await axios | ||
.get( | ||
`https://api.live.bilibili.com/live_user/v1/UserInfo/get_anchor_in_room?roomid=${liveId}`, | ||
{ | ||
headers, | ||
}, | ||
) | ||
.catch(() => null) | ||
|
||
if (!userInfo?.data) { | ||
return | ||
} | ||
|
||
const coverUrl = await axios | ||
.get( | ||
` https://api.live.bilibili.com/xlive/web-room/v1/index/getRoomBaseInfo?room_ids=${liveId}&req_biz=link-center`, | ||
{ | ||
headers, | ||
}, | ||
) | ||
.then((res) => { | ||
return (res.data as BLRoom).data.by_room_ids[liveId].cover | ||
}) | ||
const info = (userInfo.data as BLUser).data.info | ||
|
||
const { tgBot } = ctx | ||
await Promise.all( | ||
config.watchGroupIds.map(async (groupId) => { | ||
tgBot.telegram.sendMediaGroup(groupId, [ | ||
{ | ||
type: 'photo', | ||
media: coverUrl, | ||
caption: ` | ||
📺${info.uname}(${info.uid}) 开播了 | ||
前往直播间: https://live.bilibili.com/${liveId} | ||
`.trim(), | ||
}, | ||
]) | ||
}), | ||
) | ||
|
||
playStatus = true | ||
} else { | ||
playStatus = false | ||
} | ||
} | ||
const job = new CronJob('*/1 * * * *', work) | ||
job.start() | ||
work() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
export interface BLLive { | ||
code: number | ||
message: string | ||
ttl: number | ||
data: Data | ||
} | ||
interface Data { | ||
room_id: number | ||
short_id: number | ||
uid: number | ||
is_hidden: boolean | ||
is_locked: boolean | ||
is_portrait: boolean | ||
live_status: number | ||
hidden_till: number | ||
lock_till: number | ||
encrypted: boolean | ||
pwd_verified: boolean | ||
live_time: number | ||
room_shield: number | ||
all_special_types: any[] | ||
playurl_info: Playurl_info | ||
} | ||
export interface Playurl_info { | ||
conf_json: string | ||
playurl: Playurl | ||
} | ||
interface Playurl { | ||
cid: number | ||
g_qn_desc: GQnDescItem[] | ||
stream: StreamItem[] | ||
p2p_data: P2p_data | ||
dolby_qn: null | ||
} | ||
interface GQnDescItem { | ||
qn: number | ||
desc: string | ||
hdr_desc: string | ||
} | ||
interface StreamItem { | ||
protocol_name: string | ||
format: FormatItem[] | ||
} | ||
interface FormatItem { | ||
format_name: string | ||
codec: CodecItem[] | ||
} | ||
interface CodecItem { | ||
codec_name: string | ||
current_qn: number | ||
accept_qn: number[] | ||
base_url: string | ||
url_info: UrlInfoItem[] | ||
hdr_qn: null | ||
dolby_type: number | ||
} | ||
interface UrlInfoItem { | ||
host: string | ||
extra: string | ||
stream_ttl: number | ||
} | ||
interface P2p_data { | ||
p2p: boolean | ||
p2p_type: number | ||
m_p2p: boolean | ||
m_servers: null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
export interface BLRoom { | ||
code: number | ||
message: string | ||
ttl: number | ||
data: Data | ||
} | ||
interface Data { | ||
by_uids: {} | ||
by_room_ids: By_room_ids | ||
} | ||
|
||
interface By_room_ids { | ||
[key: number]: RoomInfo | ||
} | ||
export interface RoomInfo { | ||
room_id: number | ||
uid: number | ||
area_id: number | ||
live_status: number | ||
live_url: string | ||
parent_area_id: number | ||
title: string | ||
parent_area_name: string | ||
area_name: string | ||
live_time: string | ||
description: string | ||
tags: string | ||
attention: number | ||
online: number | ||
short_id: number | ||
uname: string | ||
cover: string | ||
background: string | ||
join_slide: number | ||
live_id: number | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
export interface BLUser { | ||
code: number | ||
msg: string | ||
message: string | ||
data: Data | ||
} | ||
interface Data { | ||
info: UserInfo | ||
level: Level | ||
san: number | ||
} | ||
export interface UserInfo { | ||
uid: number | ||
uname: string | ||
face: string | ||
rank: string | ||
platform_user_level: number | ||
mobile_verify: number | ||
identification: number | ||
official_verify: Official_verify | ||
vip_type: number | ||
gender: number | ||
} | ||
interface Official_verify { | ||
type: number | ||
desc: string | ||
role: number | ||
} | ||
interface Level { | ||
uid: number | ||
cost: number | ||
rcost: number | ||
user_score: string | ||
vip: number | ||
vip_time: string | ||
svip: number | ||
svip_time: string | ||
update_time: string | ||
master_level: Master_level | ||
user_level: number | ||
color: number | ||
anchor_score: number | ||
} | ||
interface Master_level { | ||
level: number | ||
color: number | ||
current: number[] | ||
next: number[] | ||
anchor_score: number | ||
upgrade_score: number | ||
master_level_color: number | ||
sort: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { appConfig } from 'app.config' | ||
import type { ModuleContext } from '~/types/context' | ||
import type { | ||
MxSocketEventTypes, | ||
MxSystemEventBusEvents, | ||
} from './types/mx-socket-types' | ||
|
||
import { createNamespaceLogger } from '~/lib/logger' | ||
|
||
import { getMxSpaceAggregateData } from './data' | ||
|
||
const logger = createNamespaceLogger('mx-event') | ||
|
||
interface TextMessage { | ||
type: 'text' | 'Markdown' | 'HTML' | 'MarkdownV2' | ||
content: string | ||
} | ||
|
||
interface MediaMessage { | ||
type: 'media' | ||
} | ||
|
||
type IMessage = TextMessage | MediaMessage | ||
type Sendable = string | IMessage[] | ||
|
||
export const handleEvent = | ||
(ctx: ModuleContext) => | ||
async ( | ||
type: MxSocketEventTypes | MxSystemEventBusEvents, | ||
payload: any, | ||
code?: number, | ||
) => { | ||
logger.debug(type, payload) | ||
|
||
const aggregateData = await getMxSpaceAggregateData() | ||
const sendToGroup = async (message: Sendable) => { | ||
const { watchGroupIds } = appConfig.mxSpace | ||
|
||
return await Promise.all( | ||
watchGroupIds.map((id) => { | ||
if (message instanceof Array) { | ||
for (const msg of message) { | ||
switch (msg.type) { | ||
case 'text': | ||
ctx.tgBot.telegram.sendMessage(id, msg.content) | ||
continue | ||
case 'HTML': | ||
case 'Markdown': | ||
case 'MarkdownV2': | ||
ctx.tgBot.telegram.sendMessage(id, msg.content, { | ||
parse_mode: msg.type, | ||
}) | ||
continue | ||
} | ||
} | ||
} else return ctx.tgBot.telegram.sendMessage(id, message) | ||
}), | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { appConfig } from 'app.config' | ||
import { io } from 'socket.io-client' | ||
import type { MxSocketEventTypes } from '~/modules/mx-space/types/mx-socket-types' | ||
import type { ModuleContext } from '~/types/context' | ||
import type { Socket } from 'socket.io-client' | ||
|
||
import { simpleCamelcaseKeys } from '@mx-space/api-client' | ||
|
||
import { createNamespaceLogger } from '~/lib/logger' | ||
|
||
import { handleEvent } from './event-handler' | ||
|
||
const logger = createNamespaceLogger('mx-socket') | ||
|
||
export function createMxSocket(ctx: ModuleContext): Socket<any, any> { | ||
const mxSocket = io(appConfig.mxSpace?.gateway, { | ||
transports: ['websocket'], | ||
timeout: 10000, | ||
forceNew: true, | ||
query: { | ||
token: appConfig.mxSpace.token, | ||
}, | ||
|
||
autoConnect: false, | ||
}) | ||
|
||
mxSocket.io.on('error', () => { | ||
logger.error('Socket 连接异常') | ||
}) | ||
mxSocket.io.on('reconnect', () => { | ||
logger.info('Socket 重连成功') | ||
}) | ||
mxSocket.io.on('reconnect_attempt', () => { | ||
logger.info('Socket 重连中') | ||
}) | ||
mxSocket.io.on('reconnect_failed', () => { | ||
logger.info('Socket 重连失败') | ||
}) | ||
|
||
mxSocket.on('disconnect', () => { | ||
const tryReconnect = () => { | ||
if (mxSocket.connected === false) { | ||
mxSocket.io.connect() | ||
} else { | ||
timer = clearInterval(timer) | ||
} | ||
} | ||
let timer: any = setInterval(tryReconnect, 2000) | ||
}) | ||
|
||
mxSocket.on( | ||
'message', | ||
(payload: string | Record<'type' | 'data' | 'code', any>) => { | ||
if (typeof payload !== 'string') { | ||
return handleEvent(ctx)( | ||
payload.type, | ||
simpleCamelcaseKeys(payload.data), | ||
payload.code, | ||
) | ||
} | ||
const { data, type, code } = JSON.parse(payload) as { | ||
data: any | ||
type: MxSocketEventTypes | ||
code?: number | ||
} | ||
handleEvent(ctx)(type, simpleCamelcaseKeys(data), code) | ||
}, | ||
) | ||
|
||
return mxSocket | ||
} |
Oops, something went wrong.