Spaces:
Configuration error
Configuration error
void
commited on
Commit
•
edaa5d4
1
Parent(s):
4bc647b
add feature sending chat
Browse files- blivedm/clients/web.py +45 -0
- blivedm/clients/ws_base.py +21 -0
- blivedm/requirements.txt +3 -0
- chatbot.py +84 -0
blivedm/clients/web.py
CHANGED
@@ -9,12 +9,15 @@ import yarl
|
|
9 |
from . import ws_base
|
10 |
from .. import utils
|
11 |
|
|
|
|
|
12 |
__all__ = (
|
13 |
'BLiveClient',
|
14 |
)
|
15 |
|
16 |
logger = logging.getLogger('blivedm')
|
17 |
|
|
|
18 |
UID_INIT_URL = 'https://api.bilibili.com/x/web-interface/nav'
|
19 |
BUVID_INIT_URL = 'https://data.bilibili.com/v/'
|
20 |
ROOM_INIT_URL = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom'
|
@@ -264,3 +267,45 @@ class BLiveClient(ws_base.WebSocketClientBase):
|
|
264 |
if self._host_server_token is not None:
|
265 |
auth_params['key'] = self._host_server_token
|
266 |
await self._websocket.send_bytes(self._make_packet(auth_params, ws_base.Operation.AUTH))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
from . import ws_base
|
10 |
from .. import utils
|
11 |
|
12 |
+
import time
|
13 |
+
|
14 |
__all__ = (
|
15 |
'BLiveClient',
|
16 |
)
|
17 |
|
18 |
logger = logging.getLogger('blivedm')
|
19 |
|
20 |
+
SEND_CHAT_URL = 'https://api.live.bilibili.com/msg/send'
|
21 |
UID_INIT_URL = 'https://api.bilibili.com/x/web-interface/nav'
|
22 |
BUVID_INIT_URL = 'https://data.bilibili.com/v/'
|
23 |
ROOM_INIT_URL = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom'
|
|
|
267 |
if self._host_server_token is not None:
|
268 |
auth_params['key'] = self._host_server_token
|
269 |
await self._websocket.send_bytes(self._make_packet(auth_params, ws_base.Operation.AUTH))
|
270 |
+
|
271 |
+
async def send_bulletchat(self, bulletchat: ws_base.BulletChat = None):
|
272 |
+
"""
|
273 |
+
:param bulletchat:BulletChat对象。
|
274 |
+
"""
|
275 |
+
|
276 |
+
cookies = self._session.cookie_jar.filter_cookies(yarl.URL(SEND_CHAT_URL))
|
277 |
+
sessdata_cookie = cookies.get('SESSDATA', None)
|
278 |
+
if sessdata_cookie is None or sessdata_cookie.value == '':
|
279 |
+
return False
|
280 |
+
|
281 |
+
headers = { 'referer': 'https://live.bilibili.com/',
|
282 |
+
'User-Agent': utils.USER_AGENT}
|
283 |
+
dict_data = {"bubble": bulletchat.bubble,
|
284 |
+
"msg": bulletchat.msg,
|
285 |
+
"color": bulletchat.color,
|
286 |
+
"mode": bulletchat.mode,
|
287 |
+
"fontsize": bulletchat.fontsize,
|
288 |
+
"rnd": str(int(time.time())),
|
289 |
+
"roomid": self.room_id,
|
290 |
+
"csrf": cookies['bili_jct'].value,
|
291 |
+
"csrf_token": cookies['bili_jct'].value}
|
292 |
+
dict_cookies = {"SESSDATA": cookies['SESSDATA'].value,
|
293 |
+
"buvid3": cookies['buvid3'].value,
|
294 |
+
"bili_jct": cookies['bili_jct'].value,}
|
295 |
+
|
296 |
+
try:
|
297 |
+
async with self._session.request(
|
298 |
+
method="POST",
|
299 |
+
url=SEND_CHAT_URL,
|
300 |
+
data=dict_data,
|
301 |
+
headers=headers,
|
302 |
+
cookies=dict_cookies,
|
303 |
+
) as res:
|
304 |
+
if res.status != 200:
|
305 |
+
logger.warning('send_bulletchat() failed, status=%d, reason=%s', res.status, res.reason)
|
306 |
+
return False
|
307 |
+
# print(res)
|
308 |
+
return True
|
309 |
+
except (aiohttp.ClientConnectionError, asyncio.TimeoutError):
|
310 |
+
logger.exception('send_bulletchat() failed:')
|
311 |
+
return False
|
blivedm/clients/ws_base.py
CHANGED
@@ -492,3 +492,24 @@ class WebSocketClientBase:
|
|
492 |
self._handler.handle(self, command)
|
493 |
except Exception as e:
|
494 |
logger.exception('room=%d _handle_command() failed, command=%s', self.room_id, command, exc_info=e)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
492 |
self._handler.handle(self, command)
|
493 |
except Exception as e:
|
494 |
logger.exception('room=%d _handle_command() failed, command=%s', self.room_id, command, exc_info=e)
|
495 |
+
|
496 |
+
class BulletChat:
|
497 |
+
def __init__(self,
|
498 |
+
bubble: int = 0,
|
499 |
+
msg: str = None,
|
500 |
+
color: int = int("FFFFFF", 16),
|
501 |
+
mode: int = 1,
|
502 |
+
fontsize: int = 25):
|
503 |
+
"""
|
504 |
+
:param bubble:功能未知,默认0。
|
505 |
+
:param msg:弹幕内容,长度需不大于30。
|
506 |
+
:param color:字体颜色。
|
507 |
+
:param mode:弹幕模式。
|
508 |
+
:param fontsize:字体大小。
|
509 |
+
:param roomid:房间号。
|
510 |
+
"""
|
511 |
+
self.bubble = bubble
|
512 |
+
self.msg = msg
|
513 |
+
self.color = color
|
514 |
+
self.mode = mode
|
515 |
+
self.fontsize = fontsize
|
blivedm/requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
aiohttp~=3.9.0
|
2 |
+
Brotli~=1.1.0
|
3 |
+
yarl~=1.9.3
|
chatbot.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
|
3 |
+
import time
|
4 |
+
|
5 |
+
import asyncio
|
6 |
+
import http.cookies
|
7 |
+
import random
|
8 |
+
from typing import *
|
9 |
+
|
10 |
+
import aiohttp
|
11 |
+
|
12 |
+
import blivedm
|
13 |
+
import blivedm.models.web as web_models
|
14 |
+
from blivedm.clients.ws_base import BulletChat
|
15 |
+
|
16 |
+
import USER_INFO
|
17 |
+
|
18 |
+
# 直播间ID的取值看直播间URL
|
19 |
+
TEST_ROOM_ID = 9792252
|
20 |
+
|
21 |
+
# 这里填一个已登录账号的cookie的SESSDATA字段的值。不填也可以连接,但是收到弹幕的用户名会打码,UID会变成0
|
22 |
+
cookies = http.cookies.SimpleCookie()
|
23 |
+
cookies['SESSDATA'] = USER_INFO.SESSDATA
|
24 |
+
cookies['SESSDATA']['domain'] = 'bilibili.com'
|
25 |
+
cookies['bili_jct'] = USER_INFO.bili_jct
|
26 |
+
cookies['buvid3'] = USER_INFO.buvid3
|
27 |
+
|
28 |
+
session: Optional[aiohttp.ClientSession] = None
|
29 |
+
|
30 |
+
async def dm_monitor():
|
31 |
+
init_session()
|
32 |
+
try:
|
33 |
+
await run_single_client()
|
34 |
+
finally:
|
35 |
+
await session.close()
|
36 |
+
|
37 |
+
def init_session():
|
38 |
+
global session
|
39 |
+
session = aiohttp.ClientSession()
|
40 |
+
session.cookie_jar.update_cookies(cookies)
|
41 |
+
|
42 |
+
async def run_single_client():
|
43 |
+
room_id = TEST_ROOM_ID
|
44 |
+
|
45 |
+
global client
|
46 |
+
client = blivedm.BLiveClient(room_id, session=session)
|
47 |
+
handler = MyHandler()
|
48 |
+
client.set_handler(handler)
|
49 |
+
|
50 |
+
client.start()
|
51 |
+
try:
|
52 |
+
await client.join()
|
53 |
+
finally:
|
54 |
+
await client.stop_and_close()
|
55 |
+
|
56 |
+
class MyHandler(blivedm.BaseHandler):
|
57 |
+
_CMD_CALLBACK_DICT = blivedm.BaseHandler._CMD_CALLBACK_DICT.copy()
|
58 |
+
|
59 |
+
def __interact_word_callback(self, client: blivedm.BLiveClient, command: dict):
|
60 |
+
uname = command['data']['uname']
|
61 |
+
msg_type = command['data']['msg_type']
|
62 |
+
if msg_type == 2:
|
63 |
+
asyncio.create_task(client.send_bulletchat(BulletChat(msg=f'谢谢{uname}的关注喵')))
|
64 |
+
|
65 |
+
_CMD_CALLBACK_DICT['INTERACT_WORD'] = __interact_word_callback
|
66 |
+
|
67 |
+
def _on_heartbeat(self, client: blivedm.BLiveClient, message: web_models.HeartbeatMessage):
|
68 |
+
pass
|
69 |
+
|
70 |
+
def _on_danmaku(self, client: blivedm.BLiveClient, message: web_models.DanmakuMessage):
|
71 |
+
pass
|
72 |
+
|
73 |
+
def _on_gift(self, client: blivedm.BLiveClient, message: web_models.GiftMessage):
|
74 |
+
pass
|
75 |
+
|
76 |
+
def _on_buy_guard(self, client: blivedm.BLiveClient, message: web_models.GuardBuyMessage):
|
77 |
+
pass
|
78 |
+
|
79 |
+
def _on_super_chat(self, client: blivedm.BLiveClient, message: web_models.SuperChatMessage):
|
80 |
+
pass
|
81 |
+
|
82 |
+
|
83 |
+
if __name__ == '__main__':
|
84 |
+
asyncio.run(dm_monitor())
|