async def calculatespeak(msg: Message, from_contact: Contact, room: Room, collection): print("对用户发出信息进行对应操作") if room == None: return find_res = find(collection=collection, id=from_contact.contact_id) update(collection, from_contact.contact_id, "speak_num", find_res["speak_num"] + 1) if msg.message_type() == MessageType.MESSAGE_TYPE_IMAGE: update(collection, from_contact.contact_id, "imgs_num", find_res["imgs_num"] + 1)
async def on_message(self, msg: Message): # 加载消息发送者 talker = msg.talker() await talker.ready() # 忽略自己发的消息 if talker.contact_id == self.my_contact_id: return # 加载聊天室信息 room = msg.room() room_topic = None if room: await room.ready() room_topic = await room.topic() # 基本信息 msg_text = msg.text() msg_text_inline = msg.text().replace('\n', '') msg_type = msg.message_type() msg_id = msg.message_id if msg_type == 6: log.info('Received text, msg_type = {}, id = {}'.format( msg_type, msg_id)) else: log.info('Received text = {}, msg_type = {}, id = {}'.format( msg_text, msg_type, msg_id)) # 保存聊天记录 insert_data = { 'contact_id': talker.contact_id, 'contact_name': talker.name, 'room_id': room.room_id if room else None, 'room_name': room_topic, 'msg_id': msg_id, 'msg_text': msg_text[:20], 'created_at': datetime.now() } keys = ','.join(['`{}`'.format(str(v)) for v in insert_data.keys()]) values = ','.join( ['\'{}\''.format(str(v)) for v in insert_data.values()]) sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format( table='msg_records', keys=keys, values=values) try: self.db.cursor.execute(sql) self.db.db.commit() except Exception as e: log.error(e) self.db.db.rollback() # 鉴定是否为广告 if room and not re.match(r'.*(kda|kadena|可达).*', msg_text_inline.lower()): is_ad = False if msg_type == 4: pass elif msg_type == 5: # 识别是否有二维码 img = await msg.to_file_box() log.info('get img {}'.format(img.name)) img_path = './images/{}'.format(img.name) img_file = await img.to_file(img_path) log.info('get img stored') img = cv2.imread(img_path) data, bbox, straight_qrcode = self.detector.detectAndDecode( img) log.info('qrcode results: {}, {}, {}'.format( data, bbox, straight_qrcode)) if bbox is not None: log.info('ad detected qr_code') is_ad = True os.remove(img_path) elif msg_type == 6: if len(msg_text) >= 50 and re.match( r'.*(http|空投|撸).*', msg_text) and not re.match(r'.*bihu\.com.*', msg_text): log.info('ad detected text') is_ad = True if is_ad: sql = """SELECT count(*) as msg_cnt FROM {} where contact_id = '{}'""".format( 'msg_records', talker.contact_id) self.db.cursor.execute(sql) if list(self.db.cursor.fetchall())[0]['msg_cnt'] < 10: q_list = list(self.ad_qa_dict.keys()) question = q_list[random.randrange(0, len(q_list))] threading.Thread(target=self.kick_member, args=(talker, room, question)).start() reply = '@{}\n你有打广告的嫌疑哦,请在15秒内回答以下问题,否则给你抱出去~~~\n{}'.format( talker.name, question) await room.say(reply, mention_ids=[talker.contact_id]) return # GOD的指令 if talker.contact_id == self.god_contact_id and 'c/' in msg_text: if 'c/new' in msg_text: if '上一条' in msg_text: sql = """SELECT msg_id FROM {} where contact_id = '{}' order by created_at desc""".format( 'msg_records', self.god_contact_id) self.db.cursor.execute(sql) refer_msg_id = list(self.db.cursor.fetchall())[1]['msg_id'] title = msg_text else: root = ET.fromstring(msg_text) refer_msg_id = root.find('.//refermsg//svrid').text title = root.find('.//title').text keyword = re.findall('#.+#', title)[0].replace('#', '') log.info('title = {}, keyword = {}'.format(title, keyword)) insert_data = { 'keyword': keyword, 'msg_id': refer_msg_id, 'created_at': datetime.now() } keys = ','.join( ['`{}`'.format(str(v)) for v in insert_data.keys()]) values = ','.join( ['\'{}\''.format(str(v)) for v in insert_data.values()]) sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format( table='materials', keys=keys, values=values) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('INSERT succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() reply = '指令已储存,关键词:{}'.format(keyword) await msg.say(reply) elif 'c/list' in msg_text: sql = """SELECT keyword FROM {} group by keyword""".format( 'materials') self.db.cursor.execute(sql) reply = '现有指令' for row in self.db.cursor.fetchall(): reply += '\n' + row['keyword'] await msg.say(reply) elif 'c/show' in msg_text: keyword = re.findall('#.+#', msg_text)[0].replace('#', '') await self.send_msg_with_keyword(keyword, contact=talker, room=room) elif 'c/active' in msg_text: today = datetime.now() start_dt = datetime(today.year, today.month, today.day) sql = """SELECT contact_id, count(*) as msg_cnt FROM {} where room_id = '{}' and created_at >= '{}' group by contact_id""".format('msg_records', room.room_id, start_dt) self.db.cursor.execute(sql) records = [ row['contact_id'] for row in self.db.cursor.fetchall() ] member_list = await room.member_list() reply = '今日群内未发言成员:' for member in member_list: if member.contact_id != self.my_contact_id and member.contact_id not in records: reply += '\n' + member.name topic = await room.topic() if '星火' in topic: reply += '\n如果没法保持每天活跃,会被移出此群哦~' await msg.say(reply) elif 'c/fixroomname' in msg_text: log.info('to fix room name') sql = """SELECT * FROM {} WHERE room_id is not null and room_name = ''""".format( 'msg_records') self.db.cursor.execute(sql) for row in self.db.cursor.fetchall(): to_fix_room = self.Room(room_id=row['room_id']) await to_fix_room.ready() to_fix_room_name = await to_fix_room.topic() sql = """UPDATE {} SET room_name = '{}' where id = {}""".format( 'msg_records', to_fix_room_name, row['id']) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('update succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() log.info('finished') elif 'c/kdashill_to_tg' in msg_text: log.info('to send telegram') sql = """SELECT * FROM {} WHERE has_sent_tg is null""".format( 'kdashill_records') self.db.cursor.execute(sql) for row in self.db.cursor.fetchall(): url = 'https://m.bihu.com/shortcontent/{}'.format( row['content_id']) data = None with concurrent.futures.ThreadPoolExecutor() as executor: future = executor.submit(self.telegram.send_msg, url) data = future.result() log.info('get res: {}'.format(data)) if data: sql = """UPDATE {} SET has_sent_tg = {} where content_id = '{}'""".format( 'kdashill_records', 1, row['content_id']) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('update succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() time.sleep(1) break return # 推荐活动 if room and re.match(r'.*[bihu|chainnode]\.com.*', msg_text_inline): content_id = None match_results = re.search(r'(?<=bihu\.com/s/)[0-9A-Za-z]{1,}', msg_text) if match_results: key = match_results[0] x = 0 for y in key: k = digit62.find(y) if k >= 0: x = x * 62 + k content_id = str(x) platform = 'bihu' log.info('transfer {} to {}'.format(key, content_id)) elif 'bihu' in msg_text: match_results = re.search( r'(?<=bihu\.com/shortcontent/)\d{1,}', msg_text_inline.lower()) content_id = match_results[0] platform = 'bihu' elif 'chainnode' in msg_text: match_results = re.search(r'(?<=chainnode\.com/post/)\d{1,}', msg_text_inline.lower()) content_id = match_results[0] platform = 'chainnode' else: log.info('not find pattern') if content_id: log.info('get content id = {}'.format(content_id)) data = None with concurrent.futures.ThreadPoolExecutor() as executor: if platform == 'bihu': future = executor.submit(self.crawler.fetch_bihu, content_id) else: future = executor.submit(self.crawler.fetch_chainnode, content_id) data = future.result() log.info('fetched data = {}'.format(data)) if data: content_inline = data['content'].replace('\n', '') post_date = data['post_date'] if not re.match(r'.*(kda|kadena|可达).*', content_inline.lower()): reply = '未发现Kadena相关信息哦~' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return elif post_date < datetime( 2021, 3, 26) or post_date >= datetime(2021, 4, 2): reply = '文章发布时间不在活动范围内,不能算入哦~' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return # 展示 sql = """SELECT * FROM {} where phase = 1 and platform = '{}' and content_id = '{}'""".format( 'kdashill_records', platform, content_id) self.db.cursor.execute(sql) results = list(self.db.cursor.fetchall()) if len(results): # 处理重复 is_duplicate = True ww_id = results[0]['id'] from_room = self.Room(room_id=results[0]['room_id']) await from_room.ready() from_room_name = await from_room.topic() room_name_str = '「{}」\n'.format( from_room_name.replace('Kadena', '')) from_contact = self.Contact( contact_id=results[0]['contact_id']) await from_contact.ready() from_contact_name = from_contact.name else: is_duplicate = False sql = """SELECT max(id) as max_id FROM {} """.format( 'kdashill_records') self.db.cursor.execute(sql) max_id = list(self.db.cursor.fetchall())[0]['max_id'] ww_id = max_id + 1 room_name_str = '「{}」\n'.format( room_topic.replace('Kadena', '')) from_contact_name = talker.name reply_title = '可达秀.{:02} @ {}'.format( ww_id, from_contact_name) if platform == 'bihu': reply_url = 'https://m.bihu.com/shortcontent/{}'.format( content_id) score = 1 if 'img_url' in data: prefix = 'https://oss-cdn1.bihu-static.com/' reply_thumbnail = prefix + data['img_url'] else: reply_thumbnail = 'https://m.bihu.com/static/img/pic300.jpg' else: score = 2 reply_url = 'https://www.chainnode.com/post/{}'.format( content_id) if 'img_url' in data: reply_thumbnail = data['img_url'] else: reply_thumbnail = 'https://webcdn.chainnode.com/mobile-1.3.15/img/ChainNode.4e5601a.svg' reply_description = room_name_str + data['content'][:60] log.info('to create url_link: {},{},{},{}'.format( reply_url, reply_title, reply_thumbnail, reply_description)) reply_link = UrlLink.create(reply_url, reply_title, reply_thumbnail, reply_description) log.info('url created') # 查重 if is_duplicate: reply = '文章已有录入哦~' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return # 记分 insert_data = { 'phase': 2, 'platform': platform, 'content_id': content_id, 'contact_id': talker.contact_id, 'contact_name': talker.name, 'room_id': room.room_id, 'created_at': datetime.now(), 'score': score, } keys = ','.join( ['`{}`'.format(str(v)) for v in insert_data.keys()]) values = ','.join([ '\'{}\''.format(str(v)) for v in insert_data.values() ]) sql = 'INSERT INTO {table}({keys}) VALUES({values})'.format( table='kdashill_records', keys=keys, values=values) try: self.db.cursor.execute(sql) self.db.db.commit() log.info('INSERT succesfully: {}'.format(sql)) except Exception as e: log.error(e) self.db.db.rollback() # 报积分 sql = """SELECT contact_id, sum(score) as score FROM {} where phase = 2 group by contact_id order by score desc""".format( 'kdashill_records') self.db.cursor.execute(sql) rank = 0 for row in self.db.cursor.fetchall(): rank += 1 if row['contact_id'] == talker.contact_id: reply = '感谢参加可达秀 [KDA-Show] 活动!🍻\n' reply += '您当前积分为{},排名为{}'.format( row['score'], rank) break reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) # 发送至其他群 sql = """SELECT room_id, max(room_name) as room_name FROM {} group by room_id""".format( 'msg_records') self.db.cursor.execute(sql) for row in self.db.cursor.fetchall(): if '可达社区信息流' in row['room_name']: forward_room = self.Room(room_id=row['room_id']) await forward_room.ready() try: await forward_room.say(reply_link) except Exception as e: log.exception(e) # 发送至Telegram #threading.Thread(target=self.telegram.send_msg, args=(reply_url)).start() return else: reply = '未查到相关网页' reply = reply + ' @{}'.format(talker.name) await room.say(reply, mention_ids=[talker.contact_id]) return # 关键词回复 if re.match(r'(资料|学习|学习资料|新人)', msg_text_inline): await self.send_msg_with_keyword('新手指南', contact=talker, room=room) return coin_dict = { 'kda': 'kadena', 'btc': 'bitcoin', 'eth': 'ethereum', 'dot': 'polkadot', 'link': 'chainlink', 'atom': 'cosmos', 'mkr': 'maker', 'luna': 'terra-luna', 'celo': 'celo', } if room and msg_text.lower() in coin_dict: name = msg_text.lower() full_name = coin_dict[name] url = 'https://api.coingecko.com/api/v3/coins/{}/market_chart?vs_currency=usd&days=30&interval=daily'.format( full_name) data = requests.get(url).json() log.info('get chart, response: {}'.format(data)) url = 'http://*****:*****@{}'.format(self.my_contact_name) in msg_text): data = {'msg': msg_text, 'appid': '0', 'key': 'free'} url = 'http://api.qingyunke.com/api.php' res = requests.get(url, params=data) log.info('get AI request: {}, {}, response: {}'.format( url, data, res.text)) data = res.json() reply = data['content'].replace('{br}', '\n') reply = reply + ' @{}'.format(talker.name) if room: await room.say(reply, mention_ids=[talker.contact_id]) else: await msg.say(reply)