def receive_events(ctx: EventMsg): join_data = ep.group_join(ctx) if join_data is None: return userKey = "{}_{}".format(join_data.UserID, ctx.FromUin) code, capcha = genCapcha() with lock: new_users[userKey] = code Action(ctx.CurrentQQ).sendGroupPic( ctx.FromUin, picBase64Buf=capcha, content= f"请在{wait_time}分钟内发送验证码数字!否则将踢出本群!\n(验证成功才会回复提示!发送 看不清 可刷新验证码)", atUser=join_data.UserID, ) time.sleep(wait_time * 60) if userKey in new_users: Action(ctx.CurrentQQ).sendGroupText( ctx.FromUin, content= f"由于你({join_data.UserName})在进群后{wait_time}分钟内未成功验证, 即将踢出本群!\n如果没踢出去,说明本机器人不是管理员,请自行退群或联系群主管理员办理退群手续!谢谢~~", atUser=join_data.UserID, ) time.sleep(1) Action(ctx.CurrentQQ).driveUserAway(ctx.FromUin, join_data.UserID) with lock: new_users.pop(userKey)
def receive_group_msg(ctx: GroupMsg): try: if ctx.Content.startswith(const.PREFIX + "云图"): text = ctx.Content[3:].lstrip() if text == "": Text(const.BOTNAME + "现已支持的云图\n风云二号全国云图: {0}云图 fy2\n风云二号西北太平洋云图: {0}云图 fy2f\n风云四号全国云图: {0}云图 fy4a\n风云四号全圆盘云图: {0}云图 fy4af\n向日葵8号机动观测:{0}云图 h8".format(const.PREFIX)) return cloud_atlas_list = { "fy2": cloud_atlas.fy2, "fy2f": cloud_atlas.fy2f, "fy4a": cloud_atlas.fy4a, "fy4af": cloud_atlas.fy4af, "h8": cloud_atlas.h8 } if text in cloud_atlas_list: pic_url = cloud_atlas_list.get(text)() Action(ctx.CurrentQQ).sendGroupPic( ctx.FromGroupId, picUrl = pic_url ) else: Text(const.BOTNAME + "没有此类云图") elif ctx.Content.startswith(const.PREFIX + "预报"): text = ctx.Content[3:].lstrip() if text == "": text = "24" weather_forecast_list = { "24": weather_forecast.hour_pic("24"), "48": weather_forecast.hour_pic("48"), "72": weather_forecast.hour_pic("72") } if text in weather_forecast_list: pic_url = weather_forecast_list.get(text) if pic_url == None: Text("今日还没有{}小时降水量预报图,请6点后再试".format(text)) else: Action(ctx.CurrentQQ).sendGroupPic( ctx.FromGroupId, picUrl = pic_url ) except BaseException as err: Text("执行指令时出错:\n{}\nline {}: {}".format( err.__traceback__.tb_frame.f_globals["__file__"], err.__traceback__.tb_lineno, err))
def receive_group_msg(ctx: GroupMsg): try: if ctx.Content.startswith(const.PREFIX + "mc"): text = ctx.Content[3:].lstrip() if text == "": Text(const.BOTNAME + "指令无效,{}mc <ip地址>".format(const.PREFIX)) return msg_text, pic_base64 = get_server_info(text) if pic_base64 != 0: Action(ctx.CurrentQQ).sendGroupPic(ctx.FromGroupId, content=msg_text, picBase64Buf=pic_base64) else: Text(msg_text) elif ctx.Content.startswith(const.PREFIX + "player"): text = ctx.Content[7:].lstrip() if text == "": Text(const.BOTNAME + "指令无效,{}player <ip地址>".format(const.PREFIX)) return Text(const.BOTNAME + get_server_player(text)) except BaseException as err: Text("执行指令时出错:\n{}\nline {}: {}".format( err.__traceback__.tb_frame.f_globals["__file__"], err.__traceback__.tb_lineno, err))
def receive_group_msg(ctx: GroupMsg): if ctx.FromUserId != ctx.master: # 需要在中间件部分提前设置该参数,也可以自行设置其他判断条件 return action = Action(ctx.CurrentQQ) content = ctx.Content if ctx.MsgType == MsgTypes.TextMsg: # 1. 全体禁言 => 开全体禁言 if content == "全体禁言": action.shutAllUp(ctx.FromGroupId, 1) return # 2. 关全体禁言 => 关全体禁言 if content == "关全体禁言": action.shutAllUp(ctx.FromGroupId, 0) return if ctx.MsgType == MsgTypes.AtMsg: at_data = json.loads(ctx.Content) at_content = at_data['Content'] at_users = at_data['UserID'] # 3. @改名 + <card> => 艾特一个人,发送改名加新名称,将修改他的群名片 card = re.findall(r'改名(.*?)', at_content) if card: action.modifyGroupCard(at_users[0], ctx.FromGroupId, card[0]) return # 4. @禁言 + <time> => 艾特一个人,发送禁言加多少分钟,将禁言对应用户指定分钟 time = re.findall(r'禁言(\d+)', at_content) if time: action.shutUserUp(ctx.FromGroupId, at_users[0], time[0]) return # 5. @取消禁言 => 艾特一个人, 解除禁言 cacel = re.findall(r'取消禁言', at_content) if cacel: action.shutUserUp(ctx.FromGroupId, at_users[0], 0) return
def receive_group_msg(ctx: GroupMsg): ans = whatis(ctx.Content[1:]) if ans: Action(ctx.CurrentQQ).replyGroupMsg( ctx.FromGroupId, ans, ctx.MsgSeq, ctx.MsgTime, ctx.FromUserId, ctx.Content, )
def test_rate_limit(self): action = Action(qq=self.uin, host=self.host, port=self.port) requests = ['getUserList', 'getGroupList'] def send(func: str): c = getattr(action, func) c() i = 0 while i <= 5: threading.Thread(target=send, args=[requests[i % 2]]).start() i += 1
def receive_group_msg(ctx: GroupMsg): if ctx.MsgType == MsgTypes.TextMsg: if ctx.Content.startswith(const.PREFIX + "复读"): text = ctx.Content[3:] while text.startswith(const.PREFIX + "复读"): text = text[3:] if text: Text(text) elif ctx.MsgType == MsgTypes.PicMsg: pic_ctx = refine_pic_group_msg(ctx) Action(ctx.CurrentQQ).sendGroupPic( ctx.FromGroupId, picMd5s=[pic.FileMd5 for pic in pic_ctx.GroupPic])
def receive_group_msg(ctx: GroupMsg): delay = re.findall(_KEYWORD + r"\[(\d+)\]", ctx.Content) if delay: delay = min(int(delay[0]), 90) else: random.seed(os.urandom(30)) delay = random.randint(30, 80) time.sleep(delay) Action(ctx.CurrentQQ).revokeGroupMsg( group=ctx.FromGroupId, msgSeq=ctx.MsgSeq, msgRandom=ctx.MsgRandom, )
def receive_group_msg(ctx: GroupMsg): global action if action is None: action = Action(ctx.CurrentQQ, host=getattr(ctx, "_host"), port=getattr(ctx, "_port")) if ctx.Content == "疫情订阅": cache_data.insert_group(ctx.FromGroupId) action.sendGroupText(ctx.FromGroupId, "ok") elif ctx.Content == "疫情退订": cache_data.delete_group(ctx.FromGroupId) action.sendGroupText(ctx.FromGroupId, "ok")
def receive_events(ctx: EventMsg): revoke_data = ep.group_revoke(ctx) if revoke_data is None: return admin = revoke_data.AdminUserID group_id = revoke_data.GroupID user_id = revoke_data.UserID msg_random = revoke_data.MsgRandom msg_seq = revoke_data.MsgSeq if any([ user_id == ctx.CurrentQQ, # 忽略机器人自己撤回的消息 admin != user_id, # 忽略管理员撤回的消息 ]): return db_name = f"group{group_id}" db: DB = db_map[db_name] db.init(db_name) data = db.find(msg_random=msg_random, msg_seq=msg_seq, user_id=user_id, group_id=group_id) if not data: return data = data[0] ( _, msg_type, _, _, _, user_id, user_name, group_id, content, ) = data action = Action( ctx.CurrentQQ, host=ctx._host, port=ctx._port # type:ignore ) if msg_type == MsgTypes.TextMsg: action.sendGroupText(group_id, f"{user_name}想撤回以下内容: \n{content}") elif msg_type == MsgTypes.PicMsg: pic_data = json.loads(content) action.sendGroupText(group_id, f"{user_name}想撤回以下内容: ") action.sendGroupPic( group_id, picMd5s=[pic["FileMd5"] for pic in pic_data["GroupPic"]])
def receive_group_msg(ctx: GroupMsg): userGroup = ctx.FromGroupId if Tools.commandMatch(userGroup, blockGroupNumber): return if not Tools.atOnly(ctx.MsgType): return msg = ctx.Content bot = Action(ctx.CurrentQQ) match(msg, bot, userGroup)
def receive_events(ctx: EventMsg): join_ctx = refine_group_join_event_msg(ctx) if join_ctx is not None: action = Action(ctx.CurrentQQ) action.sendGroupText( join_ctx.FromUin, '{} 已加入组织~'.format(join_ctx.UserName), ) pic = draw_text('欢迎 {} 入群!'.format(join_ctx.UserName)) pic_base64 = base64.b64encode(pic).decode() action.sendGroupPic( join_ctx.FromUin, picBase64Buf=pic_base64, )
def receive_group_msg(ctx: GroupMsg): userGroup = ctx.FromGroupId if Tools.commandMatch(userGroup, blockGroupNumber): return if not Tools.textOnly(ctx.MsgType): return userQQ = ctx.FromUserId msg = ctx.Content nickname = ctx.FromNickName bot = Action(ctx.CurrentQQ) mainProgram(bot, userQQ, userGroup, msg, nickname)
def receive_group_msg(ctx: GroupMsg): userKey = "{}_{}".format(ctx.FromUserId, ctx.FromGroupId) if userKey not in new_users: return content = ctx.Content with lock: if content.isdigit() and int(content) == new_users[userKey]: new_users.pop(userKey) Action(ctx.CurrentQQ).sendGroupText( ctx.FromGroupId, content="验证成功, 成为正式群员, 欢迎你!", atUser=ctx.FromUserId, ) return if content == "看不清": code, capcha = genCapcha() with lock: new_users[userKey] = code Action(ctx.CurrentQQ).sendGroupPic( ctx.FromGroupId, picBase64Buf=capcha, content="验证码已刷新,请尽快验证! 时间不多啦! \n(验证成功才会回复提示! 发送 看不清 可刷新验证码)", atUser=ctx.FromUserId, )
def manage_plugin(ctx: GroupMsg): if ctx.FromUserId != ctx.master: return action = Action(ctx.CurrentQQ) c = ctx.Content if c == "插件管理": action.sendGroupText( ctx.FromGroupId, ( "py插件 => 发送启用插件列表\n" "已停用py插件 => 发送停用插件列表\n" "刷新py插件 => 刷新所有插件,包括新建文件\n" "重载py插件+插件名 => 重载指定插件\n" "停用py插件+插件名 => 停用指定插件\n" "启用py插件+插件名 => 启用指定插件\n" ), ) return # 发送启用插件列表 if c == "py插件": action.sendGroupText(ctx.FromGroupId, "\n".join(bot.plugins)) return # 发送停用插件列表 if c == "已停用py插件": action.sendGroupText(ctx.FromGroupId, "\n".join(bot.removed_plugins)) return try: if c == "刷新py插件": bot.reload_plugins() # 重载指定插件 重载py插件+[插件名] elif c.startswith("重载py插件"): plugin_name = c[6:] bot.reload_plugin(plugin_name) # 停用指定插件 停用py插件+[插件名] elif c.startswith("停用py插件"): plugin_name = c[6:] bot.remove_plugin(plugin_name) # 启用指定插件 启用py插件+[插件名] elif c.startswith("启用py插件"): plugin_name = c[6:] bot.recover_plugin(plugin_name) except Exception as e: action.sendGroupText(ctx.FromGroupId, "操作失败: %s" % e)
def get_msg(ctx): action = Action(ctx.CurrentQQ) if ctx.MsgType == "ReplayMsg": # Mark the event as completed mark_event() return # Try to add new event parse_ret = parse_input(ctx, action) if parse_ret is None: return # action.sendFriendText(ctx.FromUin, str(parse_ret[0])+'\n'+str(parse_ret[1])) # Insert data to SQL try: insert_data(parse_ret[0], parse_ret[1]) except psycopg2.DatabaseError: action.sendFriendText(ctx.FromUin, "数据库故障了Σ(っ °Д °;)っ") rmsg = "任务收到!\n" + str(parse_ret[0]) + "\n" + parse_ret[1] action.sendFriendText(ctx.FromUin, rmsg)
from botoy import Action, Botoy, GroupMsg from botoy import decorators as deco import os from apscheduler.schedulers.background import BackgroundScheduler import psycopg2 from myRegex import parse_input from sqlFunc import insert_data, select_daily, select_per_hour bot = Botoy() masterQQ = os.environ['targetQQ'] botQQ = os.environ['botQQ'] action = Action(botQQ) def mark_event(): # Mark_event as done # TO DO return @bot.friend_context_use def _(ctx): # Block msg except from masterQQ if str(ctx.FromUin) != masterQQ: return return ctx @bot.on_friend_msg @deco.ignore_botself def get_msg(ctx): action = Action(ctx.CurrentQQ)
except Exception: import json # ========================================== RESOURCES_BASE_PATH = "./resources/vtuber-fortune" # ========================================== # 屏蔽群 例:[12345678, 87654321] blockGroupNumber = [] # 触发命令列表 commandList = ["今日人品", "今日运势", "抽签", "人品", "运势", "小狐狸签", "吹雪签"] # ========================================== bot = Action(int(os.getenv("BOTQQ"))) @ignore_botself def receive_group_msg(ctx: GroupMsg): userGroup = ctx.FromGroupId if Tools.commandMatch(userGroup, blockGroupNumber): return if not Tools.textOnly(ctx.MsgType): return userQQ = ctx.FromUserId msg = ctx.Content
from botoy import Action, Botoy, GroupMsg from botoy.collection import MsgTypes from botoy.decorators import ignore_botself, these_msgtypes from botoy.session import SessionController from botoy.sugar import Text host = None qq = None assert all([host, qq]) bot = Botoy(qq=qq, host=host, log=False) action = Action(qq, host=host) # 功能1, 查询 # 指令查询+关键字 def search(word): return f'已查询{word}' # 新建一个会话控制器,每个功能对应一个控制器(我是避免用这样听起来很高级的名词的,但这里我也不知道用什么描述比较好) # 这里的参数表示生成的session无任何操作该时长后被自动关闭 sc = SessionController(1 * 60) @bot.on_group_msg @ignore_botself @these_msgtypes(MsgTypes.TextMsg) def _(ctx: GroupMsg): if ctx.Content.startswith('查询'): # 取需要查询的内容,如果发送的消息直接包含了需要查询的关键字 # 则直接返回查询结果即可
from botoy import FriendMsg, GroupMsg, Action from modules import bot_config from modules.my_send import Send as send from botoy import decorators as deco action = Action(qq=bot_config.bot_qq, host=bot_config.host, port=bot_config.port) @deco.ignore_botself @deco.in_content("语音") def receive_friend_msg(ctx: FriendMsg): print(ctx.FromUin) action.sendFriendVoice(ctx.FromUin, voiceUrl="http://video.mnsd.xyz/voice/yyw.mp3") @deco.ignore_botself @deco.in_content("晓丹的月牙湾") def receive_group_msg(ctx: GroupMsg): action.sendGroupVoice(ctx.FromGroupId, voiceUrl="http://123.57.155.177/voice/yyw.mp3")
def receive_events(ctx: EventMsg): Action(ctx.CurrentQQ)
import urllib import demjson import requests import base64 # tgbot debug mode #import logging #logger = telebot.logger # telebot.logger.setLevel(logging.DEBUG) # Outputs debug messages to console. from botoy import Action, AsyncBotoy, Botoy, EventMsg, FriendMsg, GroupMsg, AsyncAction qq_num = 000000000 qqbot = Botoy(qq=qq_num) action = Action(qq_num) tg_token = "000000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" tgbot = telebot.TeleBot(tg_token) qq_group_id = 000000000 tg_chat_id = -000000000000 proxy_config = 'socks5://127.0.0.1:1080' telebot.apihelper.proxy = {'https': proxy_config} proxies = { 'http': proxy_config, 'https': proxy_config, }
def receive_friend_msg(ctx: FriendMsg): Action(ctx.CurrentQQ)
def receive_group_msg(ctx: GroupMsg): Action(ctx.CurrentQQ)
import base64 from botoy import Action from .dbs import config action = Action(qq=config['BotQQ']) class Send: @staticmethod def _tobase64(filename): with open(filename, 'rb') as f: coding = base64.b64encode(f.read()) # 读取文件内容,转换为base64编码 # logger.info('本地base64转码~') return coding.decode() @staticmethod def send_text(ctx, text, atUser: bool = False): if ctx.__class__.__name__ == 'GroupMsg': if atUser: action.sendGroupText(ctx.FromGroupId, text, ctx.FromUserId) else: action.sendGroupText(ctx.FromGroupId, text) else: if ctx.TempUin is None: # None为好友会话 action.sendFriendText(ctx.FromUin, text) else: # 临时会话 action.sendPrivateText(ctx.FromUin, text, ctx.TempUin) return
def __init__(self, client_id: str, config: Dict[str, Any], channel): super().__init__(client_id, config) self.client_config = config[self.client_id] self.uin = self.client_config['qq'] self.host = self.client_config.get('host', 'http://127.0.0.1') self.port = self.client_config.get('port', 8888) IOTConfig.configs = self.client_config self.bot = Botoy(qq=self.uin, host=self.host, port=self.port) self.action = Action(qq=self.uin, host=self.host, port=self.port) IOTFactory.bot = self.bot IOTFactory.action = self.action self.channel = channel ChatMgr.slave_channel = channel self.iot_msg = IOTMsgProcessor(self.uin) @self.bot.when_connected def on_ws_connected(): self.logger.info("Connected to OPQBot!") @self.bot.when_disconnected def on_ws_disconnected(): self.logger.info("Disconnected from OPQBot!") @self.bot.on_friend_msg def on_friend_msg(ctx: FriendMsg): self.logger.debug(ctx) if int(ctx.FromUin) == int(self.uin) and not IOTConfig.configs.get( 'receive_self_msg', True): self.logger.info( "Received self message and flag set. Cancel delivering...") return remark_name = self.get_friend_remark(ctx.FromUin) if not remark_name: info = self.get_stranger_info(ctx.FromUin) if info: remark_name = info.get('nickname', '') else: remark_name = str(ctx.FromUin) if ctx.MsgType == 'TempSessionMsg': # Temporary chat chat_uid = f'private_{ctx.FromUin}_{ctx.TempUin}' elif ctx.MsgType == 'PhoneMsg': chat_uid = f'phone_{ctx.FromUin}' else: chat_uid = f'friend_{ctx.FromUin}' chat = ChatMgr.build_efb_chat_as_private( EFBPrivateChat( uid=chat_uid, name=remark_name, )) author = chat.other # Splitting messages messages: List[Message] = [] func = getattr(self.iot_msg, f'iot_{ctx.MsgType}_friend') messages.extend(func(ctx, chat)) # Sending messages one by one message_id = ctx.MsgSeq for idx, val in enumerate(messages): if not isinstance(val, Message): continue val.uid = f"friend_{ctx.FromUin}_{message_id}_{idx}" val.chat = chat val.author = author val.deliver_to = coordinator.master coordinator.send_message(val) if val.file: val.file.close() @self.bot.on_group_msg def on_group_msg(ctx: GroupMsg): # OPQbot has no indicator for anonymous user, so we have to test the uin nickname = ctx.FromNickName if int(ctx.FromUserId) == int( self.uin) and not IOTConfig.configs.get( 'receive_self_msg', True): self.logger.info( "Received self message and flag set. Cancel delivering...") return remark_name = self.get_friend_remark(ctx.FromUserId) if not remark_name: info = self.get_stranger_info(ctx.FromUserId) if info: remark_name = info.get('nickname', '') chat = ChatMgr.build_efb_chat_as_group( EFBGroupChat(uid=f"group_{ctx.FromGroupId}", name=ctx.FromGroupName)) author = ChatMgr.build_efb_chat_as_member( chat, EFBGroupMember(name=nickname, alias=remark_name, uid=str(ctx.FromUserId))) # Splitting messages messages: List[Message] = [] func = getattr(self.iot_msg, f'iot_{ctx.MsgType}_group') messages.extend(func(ctx, chat)) # Sending messages one by one message_id = ctx.MsgSeq for idx, val in enumerate(messages): if not isinstance(val, Message): continue val.uid = f"group_{ctx.FromGroupId}_{message_id}_{idx}" val.chat = chat val.author = author val.deliver_to = coordinator.master coordinator.send_message(val) if val.file: val.file.close() @self.bot.on_event def on_event(ctx: EventMsg): pass # fixme
def receive_group_msg(ctx: GroupMsg): global action # pylint: disable=W0603 if action is None: # pylint: disable=W0212 action = Action(ctx.CurrentQQ, host=ctx._host, port=ctx._port) if ctx.FromUserId == ctx.CurrentQQ: return # 退订UP if ctx.Content.startswith("哔哩视频退订"): try: mid = re.findall(r"(\d+)", ctx.Content)[0] except Exception: msg = "UID应为数字" else: db = DB() if db.unsubscribe_up(ctx.FromGroupId, mid): upinfo = API.get_up_info_by_mid(mid) if upinfo is not None: msg = "成功退订UP主:{}".format(upinfo.name) else: msg = "成功退订UP主:{}".format(mid) else: msg = "本群未订阅该UP主" action.sendGroupText(ctx.FromGroupId, msg) # 查看订阅UP列表 elif ctx.Content == "哔哩视频列表": db = DB() mids = db.get_ups_by_gid(ctx.FromGroupId) if mids: ups = [] for mid in mids: upinfo = API.get_up_info_by_mid(mid) if upinfo is not None: ups.append("{}({})".format(upinfo.mid, upinfo.name)) else: ups.append(str(mid)) msg = "本群已订阅UP主:\n" + "\n".join(ups) else: msg = "本群还没有订阅过一个UP主" action.sendGroupText(ctx.FromGroupId, msg) # 退订番剧 elif ctx.Content.startswith("哔哩番剧退订"): try: mid = re.findall(r"(\d+)", ctx.Content)[0] except Exception: msg = "番剧ID应为数字" else: db = DB() if db.unsubscribe_bangumi(ctx.FromGroupId, mid): # 通过最新集数中的api获取番剧基本信息勉勉强强满足需求 bangumi = API.get_latest_ep_by_media_id(mid) if bangumi is not None: msg = "成功退订番剧:{}".format(bangumi.long_title) else: msg = "成功退订番剧:{}".format(mid) else: msg = "本群未订阅该UP主" action.sendGroupText(ctx.FromGroupId, msg) # 查看订阅番剧列表 elif ctx.Content == "哔哩番剧列表": db = DB() mids = db.get_bangumi_by_gid(ctx.FromGroupId) if mids: msgs = [] for mid in mids: bangumi = API.get_latest_ep_by_media_id(mid) if bangumi is not None: msgs.append("{}({})".format(mid, bangumi.long_title)) else: msgs.append(str(mid)) msg = "本群已订阅番剧:\n" + "\n".join(msgs) else: msg = "本群还没有订阅过一部番剧" action.sendGroupText(ctx.FromGroupId, msg) # 其他操作逻辑转到session操作 else: bilibili_handler.message_receiver(ctx)
from botoy import Action, Botoy, GroupMsg, FriendMsg from botoy import decorators as deco from module import config, database import json bot = Botoy( qq=config.botqq, host=config.host, port=config.port, # log=True, log=False, use_plugins=True) action = Action(qq=config.botqq, host=config.host, port=config.port) @bot.group_context_use def group_ctx_middleware(ctx: GroupMsg): ctx.type = 'group' # 群聊 ctx.QQ = ctx.FromUserId # 这条消息的发送者 ctx.QQG = ctx.FromGroupId # 这条消息的QQ群 ctx.accessLevel = database.BasicOperation.auth(ctx.QQG, ctx.QQ) # 权限等级 if ctx.MsgType == 'AtMsg': # @消息 ctx.AtContentDict = json.loads(ctx.Content) ctx.AtUserID = ctx.AtContentDict['UserID'] ctx.AtTips = ctx.AtContentDict.get('Tips') # 回复消息时才有 ctx.Content = ctx.AtContentDict['Content'] return ctx @bot.friend_context_use