def run(): INFO('读入配置文件...') try: file = open(Configpath + '\config.json', mode='r', encoding='utf-8') config = json.load(file) file.close() except: ERROR( '读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.douyin目录下的config.json。如果没有则需要复制文件 _config(将我复制改名为config.json).json 为 config.json' ) return INFO('开始初始化所有需要监听的抖音用户') user = [] user.clear() delay = int(config['delay']) for u in config['config']: if u.get('sec_uid'): user.append(dy(u)) else: ERROR(f'{u}未填写sec_uid') if len(user) == 0: INFO('没有载入任何需要监听的用户') return INFO('开始轮询抖音') i = 0 while True: for u in user: #print(u.vid) if u.check(): for g in u.conf['Group']: Send['sendGroupMsg'](g, u.msg) Send['sendGroupMsg'](g, u.video) time.sleep(delay) time.sleep(5)
def run_task(): # 读入配置文件 INFO('读入配置文件...') try: file = open(Configpath + '\config.json', mode='r', encoding='utf-8') config = json.load(file) file.close() except: ERROR( '读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.LIVEBILI目录下的config.json。如果没有则需要复制文件 _config(将我复制改名为config.json).json 为 config.json 如果你已经配置好了BILI的配置文件也可将其直接复制过来使用(必须要填写roomid)' ) return INFO('开始初始化所有需要监听的用户') user = [] user.clear() for u in config['config']: if u.get('roomid'): user.append(Livebiliws(u)) else: ERROR(f'{u}未填写roomid') if len(user) == 0: INFO('没有载入任何需要监听的用户') return INFO('开始启动ws') i = 0 for u in user: Thread(target=u.run_forever, name=f'[T{i}] {u.roomid}-websocket').start() i += 1 #开始刷新用户信息,间隔5秒 for u in user: u.RefreshInfo() time.sleep(5)
def getWeibo(index): idoleName = getName(index) weibo = Weibo(index) groups = groupid(index) at = str(groupAt(index)) try: #INFO('check weibo') global weibo_id_array # 初次启动记录前十条微博id if firstcheck_weibo is True: INFO('first check weibo') weibo_id_array[index] = weibo.IdArray # ****** INFO(weibo_id_array[index]) if firstcheck_weibo is False: # 取最新的前三条微博 for idcount in range(0, 3): # 广告位微博id为0,忽略 if int(weibo.IdArray[idcount]) == 0: continue # 微博id不在记录的id列表里,判断为新微博 if weibo.IdArray[idcount] not in weibo_id_array[index]: msg = MsgChain() if groupAt(index): msg.joinAT(-1) # 将id计入id列表 weibo_id_array[index].append(weibo.IdArray[idcount]) # 检查新微博是否是转发 if weibo.checkRetweet(idcount): msg.joinPlain('%s 刚刚转发了一条微博:\n' % idoleName) msg.joinPlain('%s\n' % weibo.getRetweetWeibo(idcount)) # 原创微博 else: msg.joinPlain('%s 刚刚发了一条新微博:\n' % idoleName) msg.joinPlain('%s\n' % weibo.getWeibo(idcount)) # 检查原创微博是否带图 if weibo.checkPic(idcount): # 只取第一张图,pro可以直接发图,air则无 for pic in weibo.getPic(idcount): msg.joinImg(Url=pic) # msg.append( # { # 'type': 'text', # 'data': {'text': '\n传送门:%s\n' % weibo.getScheme(idcount)}}) for grpid in groups: Send['sendGroupMsg'](grpid, msg) time.sleep(0.5) # print(msg) except Exception as e: WARN('error when getWeibo:' + str(e)) finally: pass
def SendFriendMsg(self,FriendId,Msg: MsgChain): INFO(f'发送私聊消息[{str(FriendId)}] <- {Msg.GetCQ()}') if Msg.Quote: mes = '[CQ:reply,id=' + str(Msg.Quote) + ']' + Msg.GetCQ() else: mes = Msg.GetCQ() s = { 'access_token':self.access_token, 'user_id':FriendId, 'message':mes } j = self.GET('send_private_msg',data=s) INFO(str(j)) return j
def SendGroupMsg(self,GroupId, Msg: MsgChain): INFO(f'发送群消息[{str(GroupId)}] <- {Msg.GetCQ()}') if Msg.Quote: mes = '[CQ:reply,id=' + str(Msg.Quote) + ']' + Msg.GetCQ() else: mes = Msg.GetCQ() s = { 'access_token':self.access_token, 'group_id':GroupId, 'message':mes } j = self.GET('send_group_msg',data=s) INFO(str(j)) return j
def OnLIVE(self, data): '''开播调用''' INFO( f'{self.roomid}[{self.info.get("showname",self.info.get("name"))}]收到开播推送' ) if not self.status: for group in self.info['Group']: msg = MsgChain() if group['ATall']: msg.joinAT(-1) msg.joinPlain( f'你的小可爱{self.info.get("showname",self.info.get("name"))}开播啦~' ) if self.title: msg.joinPlain(f'\n【{self.title}】') if group['sendPic']: '''''' if group['sendUrl']: msg.joinPlain(f'\nhttps://live.bilibili.com/{self.roomid}') Send['sendGroupMsg'](group['id'], msg) time.sleep(0.2) self.status = True #保存开播日志在弹幕表中 if self.info.get('savedanmu'): self.SQL.savedanmu( time.time() * 1000, #时间 'null', #用户名 'null', #用户uid 'LIVE' #弹幕 )
def check(self): '''检查是否更新''' j = self.Getaweme() if not self.vid and len(j) != 1: for v in j: self.vid.append(v.get('video', {}).get('vid')) return False if j: for v in j: video = v.get('video', {}) vid = video.get('vid') if vid in self.vid: #当前视频在本地记录过,直接跳出循环既可 pass else: #未记录,表示为新视频 INFO(f'用户{self.conf.get("showname",self.name)}有新作品了') self.msg = MsgChain() self.msg.joinPlain( f'【抖音】{self.conf.get("showname",self.name)}更新视频啦~\n{v.get("desc")}' ) self.msg.joinImg(Url=video.get('origin_cover', {}).get( 'url_list', ['1'])[0]) self.msg.joinPlain( video.get('play_addr', {}).get('url_list', ['1'])[1]) self.video = MsgChain().joinVideo(Url=video.get( 'play_addr', {}).get('url_list', ['1'])[1]) self.vid.append(vid) return True return False
def run(): #读取配置文件 try: file = open(path, mode='r', encoding='utf-8') #转化yml配置数据 data = yaml.load(file, Loader=yaml.FullLoader) file.close() #print(data) except Exception as e: ERROR(f'读入配置文件时发生异常,无法继续运行Acfun模块。异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}') return #实例化所有需要监听的对象放进列表里 user = [] for u in data['user']: INFO('初始化用户:'+u['uid']) us = Acfun(u) user.append(us) #开始循环执行 while True: i = 0 l = len(user) while i < l: try:#获取信息 user[i].Getinfo() user[i].GetDynamic() #判断 if user[i].IsNewLive():#开播 INFO(f'主播{user[i].Name}开播了~') SendGroupsMsg(user[i].user['group'],user[i].LiveLoad()) if user[i].IsNewVideo():#有新视频 INFO(f'主播{user[i].Name}有新视频了~') SendGroupsMsg(user[i].user['group'],user[i].VideoLoad()) if user[i].IsNewDynamic():#有新动态 INFO(f'主播{user[i].Name}有新动态了~') SendGroupsMsg(user[i].user['group'],user[i].DynamincLoad()) pass except Exception as e: ERROR(f'处理时发现异常,跳过!。异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}') pass i = i + 1 time.sleep(data.get('delay',5)) time.sleep(2)
def on_GroupMessage(Message: MsgChain, sender: GroupInfo): if Message.GetCQ().startswith('我想吃'): try: INFO('出现食谱查询指令:'+Message.GetCQ()) name = Message.GetCQ()[3:] if name.isnumeric(): Send['sendGroupMsg'](sender.GroupId,MsgChain().joinPlain(Getfangfa(name))) else: Send['sendGroupMsg'](sender.GroupId,MsgChain().joinImg(Path=合成图片(Getname(name)))) except: ERROR('食谱查询异常')
def __init__(self, user: UserData) -> None: self.user = user if self.user.StartVideo: self.video = bilibili_video(uid=self.user.uid) if self.user.StartDynamic: self.dynamic = bilibii_dynamic(uid=self.user.uid) if self.user.StartLive: self.live = bilibili_live(uid=self.user.uid, roomid=self.user.roomid) # 更新昵称 if self.live.RoomStatus: self.user.uname = self.live.roominfo.uname INFO(f'用户:{self.user.GetName()}[{self.user.uid}] 初始化完成!')
def Send(self,target:int,Msg: MsgChain,m = 'sendGroupMessage'): '''发送一条消息(可以为指定发送群消息还是私聊消息),消息为消息链类型,封装的类型''' try: #语音文件单独处理,后期可能会修改 if len(Msg.msg) == 1 and Msg.msg[0]['type'] == 'Voice': #因为语音只能单独发送 if Msg.msg[0]['url'] and not Msg.msg[0]['voiceId']: #进行上传并赋值 fname=f'./data/{str(time.time()*1000)}.mp3' with open( fname,'wb' ) as f: f.write(requests.get(Msg.msg[0]['url']).content) Msg.msg[0]['voiceId'] = self.uploadVoice(fname)['voiceId'] except: pass INFO(f'发送{"群" if m == "sendGroupMessage" else "私聊"}消息[{str(target)}] <- {Msg.GetCQ()}') s = {'sessionKey': self.sessionstr, 'target': target,'quote':Msg.Quote, 'messageChain': Msg.msg} ss = json.dumps(s) j = self.POST(m, ss) INFO(str(j)) if j.get('code') == 6: #指定文件不存在,出现于发送本地图片 #表示我发送的图片路径对于机器人而言并找不到,直接读取发送文件 try: mesg = MsgChain() for msg in Msg.msg: if msg['type'] == 'Image': p = msg['path'] img = self.uploadImage(p,'group' if m == 'sendGroupMessage' else 'friend') if img: mesg.joinImg(ImageId=img['imageId'], #Url=img['url'] ) else: #来点魔法,但这样使用会导致下一步发送消息时日志输出缺失 mesg.msg.append(msg.copy()) return self.Send(target,mesg,m) except Exception as e: ERROR(f'mirai在上传图片时发生错误:异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}') else: return j
def Import_module(modeule: list): '''安装列表内的模块''' # 导入模块 # 包名为目录名,模块为文件夹下的__init__.py,启动后会调用执行一次__init__下的Main函数, # 如果不存Main函数将不会执行此模块任何方法 for t in modeule: m = __import__(name=t) if 'Main' in dir(m): INFO('安装模块:' + str(m)) tasks.append(m) else: ERROR('模块:' + str(m) + '未找到Main') ERROR(dir(m))
def __Getsessionstr__(self): '''获取sessionstr''' data = {'authKey': self.authkey} r = self.POST('auth', json.dumps(data)) if r['code'] == 0: self.sessionstr = r['session'] INFO(f'session:{self.sessionstr}') else: #err = '错误的MIRAI API HTTP auth key' ERROR(r['msg']) return False '''获取到session,绑定机器人''' data = {'sessionKey': self.sessionstr, 'qq': int(self.BOTQQ)} r = self.POST('verify', json.dumps(data)) if r['code'] == 0: INFO("绑定机器人成功") super().__init__(self.host.replace('http','ws')+'all?sessionKey='+self.sessionstr) else: err = r['msg'] ERROR(err) return False return True
def IsNewDynamic(self) -> bool: '''判断动态是否更新''' if self.OldDynamic.get('resourceId') != None and self.Dynamic[0].get( 'resourceId') != None: if self.OldDynamic['resourceId'] != self.Dynamic[0]['resourceId']: self.OldDynamic = self.Dynamic[0] if self.OldDynamic.get('resourceId') in self.DynamicID: INFO(f'用户{self.Name}似乎删除了一条动态,清空列表,等待下次查询时刷新') self.DynamicID = None return False else: self.DynamicID = None return True return False
def IsNewVideo(self) -> bool: '''判断视频是否更新''' if self.OldVideo.get('dougaId') != None and self.Video[0].get( 'dougaId') != None: #当两个值都不能为空时才能作为有效的数据进行判断 if self.OldVideo['dougaId'] != self.Video[0]['dougaId']: #两个数据不相同,表明视频列表被刷新,更新Oldvideo数据,并判断此次最新一条是否为删除原第一条数据后的第二条,尝试在旧列表中寻找他 self.OldVideo = self.Video[0] if self.OldVideo.get('dougaId') in self.VideoID: #表示此条并非最新,而是第一条数据被删除,他成为的第一条,不能算是新动态,清空列表,等待下次获取动态时刷新他 INFO(f'用户{self.Name}似乎删除了一条视频,清空列表,等待下次查询时刷新') self.VideoID = None #动态数据有变动,清空列表,等待下次刷新 return False else: self.VideoID = None #动态数据有变动,清空列表,等待下次刷新 return True return False
def OnPREPARING(self, data): '''下播调用''' INFO( f'{self.roomid}[{self.info.get("showname",self.info.get("name"))}]收到下播推送' ) #self.SendMSG(f'你的小可爱{self.info.get("showname","None")}开播啦~\nhttps://live.bilibili.com/{self.roomid}') self.status = False self.SendMSG(MsgChain().joinPlain( f'你的小可爱{self.info.get("showname",self.info.get("name"))}下播啦~')) #保存下播日志在弹幕表中 if self.info.get('savedanmu'): self.SQL.savedanmu( time.time() * 1000, #时间 'null', #用户名 'null', #用户uid 'PREPARING' #弹幕 )
def run_forever(self): '''阻塞运行连接ws,并接受消息''' try: #检查sessionstr是否可用 j = self.GET('config','sessionKey='+self.sessionstr) if j.get('sessionKey') == self.sessionstr: pass elif j.get('code') == 3: #sessionstr失效 INFO(f'{j["msg"]},重新获取') self.__Getsessionstr__() else: ERROR(j['msg']) return True return self.ws.run_forever(ping_interval=30,ping_timeout=3) except: ERROR(f'mirai_api_http在ws连接时发生异常。') return True
def Main(sendGroupMsg, SendFriendMsg): Send['sendGroupMsg'] = sendGroupMsg Send['SendFriendMsg'] = SendFriendMsg INFO('微博启动') # 打开json文件 try: fb = open( os.path.dirname(os.path.realpath(__file__)) + '\ini.json', 'rb') data = json.load(fb) fb.close() except: ERROR( '读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.BILI目录下的ini.json。如果没有则需要复制文件 _ini(将我复制改名为ini.json).json 为 ini.json' ) return while True: chaWeribo(data) time.sleep(20)
def mute(self, Group, QQID, time): ''' 设置禁言 QQID > 0 时为群成员禁言设置,否则为全体禁言设置 time > 0 时为禁言时长(全体禁言直接填1既可),否则为解除禁言 ''' INFO(f'设置禁言:Gropu:{Group},QQ:{QQID},TIME:{time}') s = {'sessionKey': self.sessionstr, 'target': Group,} if QQID > 0: #禁言或者解除群员禁言 if time > 0: path = 'mute' s['memberId'] = QQID s['time'] = time else: path = 'unmute' s['memberId'] = QQID else: #全体禁言或解除 if time > 0: path = 'muteAll' else: path = 'unmuteAll' print(self.POST(path,s))
def run_task(): #循环的在try下运行 while True: try: # 读入配置文件 INFO('读入配置文件...') try: file = open(Configpath, mode='r', encoding='utf-8') config = json.load(file) file.close() except: ERROR('读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.BILI目录下的config.json。如果没有则需要复制文件 _config(将我复制改名为config.json).json 为 config.json') return # 初始化 INFO('开始初始化所有需要监听的用户') user = [] user.clear() delay = config['delay'] forward_draw = config.get('forward_draw',False) for u in config['config']: user.append(bilibili_user(UserData(uid=u['uid'], uname=u.get('uname'), showname=u.get('showname'),roomid=u.get('roomid'),PushGroupInfo=u['Group'], StartDynamic=u['StartDynamic'], StartLive=u['StartLive'], Startvideo=u['Startvideo']))) sleep(0.2) INFO('所有用户初始化完成') INFO('开始执行监听任务') INFO('用户列表:'+','.join(list(map(str,[u.user.uid for u in user])))) if len(user) == 0: INFO('没有载入任何需要监听的用户') return #执行任务 while True: #循环执行任务! errN = 0 #用于记录异常次数,超过十次则跳出while True 循环重新加载 try: for u in user: #延迟 sleep(delay) #检查是否投稿 if u.user.StartVideo: #是否启用视频监听 Y,Data = u.video.IsNewVideo() if Y: INFO(f'{u.user.GetName()}更新了视频,准备推送。') for group in u.user.PushGroupInfo: msg = MsgChain() if group.get('ATall'): msg.joinAT(-1) msg.joinPlain(f'你的小可爱{u.user.GetName(Data.owner_name)}有新的作品发布了哟~\n{Data.title}\n{Data.desc}\n') if group.get('sendPic'): msg.joinImg(Url=Data.pic) if group.get('sendUrl'): msg.joinPlain('https://www.bilibili.com/video/'+str(Data.bvid)) Send['sendGroupMsg'](group.get('id',0),msg) #检查是否开播 if u.user.StartLive: #是否启用直播监听 Y=u.live.IsLive() if Y: INFO(f'{u.user.GetName()}开播了,准备推送。') for group in u.user.PushGroupInfo: msg = MsgChain() if group.get('ATall'): msg.joinAT(-1) msg.joinPlain(f'你的小可爱{u.user.GetName()}开播啦~\n{u.live.roominfo.title}\n{u.live.roominfo.area}') if group.get('sendPic'): msg.joinImg(Url=u.live.roominfo.pic) if group.get('sendUrl'): msg.joinPlain('https://live.bilibili.com/'+str(u.live.roominfo.roomid)) Send['sendGroupMsg'](group.get('id',0),msg) #检查是否发布新动态 if u.user.StartDynamic: #是否启用动态监听 Y,Data = u.dynamic.IsNewDynamic() if Y: INFO(f'{u.user.GetName()}更新了动态,准备推送。') #检查是否为转发的抽奖动态 if Data.orig_type == 2 and Data.title.find('互动抽奖') != -1 and forward_draw == False: INFO(f'{u.user.GetName()}的动态内容为转发内容:{Data.title}。\n被判断为转发的抽奖动态,不发送。如果需要发送请在设置里把 forward_draw改为true。如果没有此选项在delay下面添加既可') else: for group in u.user.PushGroupInfo: msg = MsgChain() if group.get('ATall'): msg.joinAT(-1) msg.joinPlain(f'你的小可爱{u.user.GetName(Data.uname)}{Data.msg}\n{Data.title}') if group.get('sendPic'): for pic in Data.pic: msg.joinImg(Url=pic) if group.get('sendUrl'): msg.joinPlain('https://t.bilibili.com/'+str(Data.dynamic_id)) Send['sendGroupMsg'](group.get('id',0),msg) except Exception as e: ERROR(f'执行任务期间发生异常,异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}') errN += 1 if errN == 10: #for循环体出现10次异常,重启任务 break #循环固定延时 time.sleep(2) except Exception as e: ERROR(f'运行时发生异常,将重新启动任务。异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}') #防止一直出错 time.sleep(10)
def on_open(self): INFO(self.mode + '_websocket连接成功')
from msgType import MsgChain, GroupInfo, SenderInfo from Bot_mirai_cq import on_FriendMessage, on_GroupMessage, mirai, cq from Log import INFO, ERROR import threading import yaml, json import time from webserver import zr, apichecklogin, checklogin, request INFO('开始运行...') #对,这就是记录版本号的地方,你自己不要改乱了(仅表示发行版本) INFO('版本号:V 1.1') #用于存放导入成功的模块 tasks = [] def Import_module(modeule: list): '''安装列表内的模块''' # 导入模块 # 包名为目录名,模块为文件夹下的__init__.py,启动后会调用执行一次__init__下的Main函数, # 如果不存Main函数将不会执行此模块任何方法 for t in modeule: m = __import__(name=t) if 'Main' in dir(m): INFO('安装模块:' + str(m)) tasks.append(m) else: ERROR('模块:' + str(m) + '未找到Main') ERROR(dir(m))
def OnCHANGE(self, data): '''房间信息:修改标题,修改分区''' self.title = data['data']['title'] self.area = f'{data["data"]["area_name"]}·{data["data"]["parent_area_name"]}' INFO(f'{self.roomid}修改分区或标题 【{self.title}】 {self.area}') self.SendMSG(MsgChain().joinPlain(f'{self.title}\n{self.area}'))