void commited on
Commit
edaa5d4
1 Parent(s): 4bc647b

add feature sending chat

Browse files
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())