表 id为的操作,后端对接了机器人,由后端来解析命令 再进行相应的操作。 新需求:延迟执行命令任务,例如:@机器人 延迟执行 s/m ...
从基础到进阶:实现机器人延迟执行命令任务的全流程指南
在现代后端开发中,机器人命令解析与执行是常见需求。本文将循序渐进地讲解如何实现一个后端机器人系统,并扩展其功能以支持延迟执行命令任务。我们将从基础概念开始,逐步深入到高级实现,涵盖代码示例和完整流程。### 基础概念:表 id 与机器人命令解析在开始之前,我们需要理解几个核心概念。首先,“表 id”通常指数据库中的记录标识符,用于唯一标识数据行。在后端对接机器人时,机器人接收用户消息,后端解析命令并执行相应操作。假设我们有一个简单的机器人接口,用户通过消息(如@机器人 操作)触发后端处理。例如:-@机器人 查询用户 123:查询用户ID为123的信息。-@机器人 发送消息 456 "你好":向用户ID为456发送消息。后端会解析这些命令,提取参数并执行对应函数。这通常涉及命令模式或策略模式,将命令字符串映射到具体处理逻辑。### 新需求:延迟执行命令任务现在,新需求来了:用户希望机器人支持延迟执行命令。例如,用户发送@机器人 延迟执行 5m 发送消息 456 "提醒",表示5分钟后执行“发送消息”操作。我们需要设计一个系统,能够解析这种延迟命令,存储任务,并在指定时间后执行。延迟执行的核心组件包括:1.命令解析器:识别延迟语法,提取延迟时间和子命令。2.任务存储:将延迟任务持久化(如数据库),以防系统重启丢失。3.调度器:定时检查任务是否到期,并执行。### 基础实现:简单的命令解析与执行首先,我们实现一个基础的机器人命令解析系统。假设后端使用Python,通过Webhook接收消息。python# 基础命令解析示例import reclass BotCommandParser: def __init__(self): self.commands = { "查询用户": self.query_user, "发送消息": self.send_message, } def parse(self, message): # 匹配命令格式:@机器人 命令 参数... pattern = r'^@机器人\s+(\w+)\s+(.*)$' match = re.match(pattern, message) if not match: return None, "命令格式错误" cmd = match.group(1) args = match.group(2).split() if cmd not in self.commands: return None, f"未知命令: {cmd}" return cmd, args def execute(self, cmd, args): handler = self.commands[cmd] return handler(args) def query_user(self, args): user_id = args[0] # 模拟查询操作 return f"查询用户 {user_id} 成功" def send_message(self, args): user_id = args[0] content = " ".join(args[1:]) # 模拟发送操作 return f"向用户 {user_id} 发送消息: {content}"# 使用示例parser = BotCommandParser()cmd, args = parser.parse("@机器人 查询用户 123")if cmd: result = parser.execute(cmd, args) print(result) # 输出: 查询用户 123 成功这个基础版本能处理简单命令,但不支持延迟执行。接下来,我们将扩展它。### 进阶实现:集成延迟执行功能为了实现延迟执行,我们需要:- 修改命令解析器,支持延迟执行命令。- 引入任务队列或调度器(这里使用简单的time.sleep模拟,但生产环境应使用Celery或APScheduler)。- 将延迟任务保存到数据库(这里用内存字典模拟)。python# 延迟执行命令的进阶实现import timeimport threadingfrom datetime import datetime, timedeltaclass DelayedBotCommandParser: def __init__(self): self.commands = { "查询用户": self.query_user, "发送消息": self.send_message, "延迟执行": self.delayed_execute, # 新命令 } self.task_store = {} # 模拟数据库,键为任务ID,值为任务详情 self.task_id_counter = 0 self.scheduler_thread = None self.start_scheduler() def parse(self, message): # 支持延迟执行格式:@机器人 延迟执行 <时间> <子命令> <参数> # 时间格式:数字+单位,如5m(分钟)、10s(秒) pattern = r'^@机器人\s+(\w+)\s+(.*)$' match = re.match(pattern, message) if not match: return None, None, "命令格式错误" cmd = match.group(1) rest = match.group(2) if cmd not in self.commands: return None, None, f"未知命令: {cmd}" # 特殊处理延迟执行命令 if cmd == "延迟执行": # 解析时间部分 time_pattern = r'^(\d+)([sm])\s+(.*)$' time_match = re.match(time_pattern, rest) if not time_match: return None, None, "延迟执行格式错误,示例: 5m 发送消息 456 提醒" delay_value = int(time_match.group(1)) delay_unit = time_match.group(2) sub_command_str = time_match.group(3) # 计算延迟秒数 if delay_unit == 's': delay_seconds = delay_value elif delay_unit == 'm': delay_seconds = delay_value * 60 return cmd, (delay_seconds, sub_command_str), None else: args = rest.split() return cmd, args, None def execute(self, cmd, data): if cmd == "延迟执行": delay_seconds, sub_command_str = data # 解析子命令 sub_cmd, sub_args, error = self.parse(sub_command_str) if error: return f"子命令解析失败: {error}" return self.delayed_execute(delay_seconds, sub_cmd, sub_args) else: handler = self.commands[cmd] return handler(data) def delayed_execute(self, delay_seconds, sub_cmd, sub_args): # 创建延迟任务 task_id = self.task_id_counter self.task_id_counter += 1 execute_time = datetime.now() + timedelta(seconds=delay_seconds) task = { "id": task_id, "execute_time": execute_time, "cmd": sub_cmd, "args": sub_args, "status": "pending" } self.task_store[task_id] = task # 启动线程模拟延迟执行(实际应使用调度器) def delayed_task(): time.sleep(delay_seconds) if task["status"] == "pending": handler = self.commands[sub_cmd] result = handler(sub_args) task["status"] = "done" print(f"延迟任务 {task_id} 执行结果: {result}") thread = threading.Thread(target=delayed_task) thread.start() return f"延迟任务已创建,任务ID: {task_id},将在 {delay_seconds} 秒后执行" def start_scheduler(self): # 简单调度器线程(实际应使用定期检查) def check_tasks(): while True: now = datetime.now() for task_id, task in list(self.task_store.items()): if task["status"] == "pending" and now >= task["execute_time"]: handler = self.commands[task["cmd"]] result = handler(task["args"]) task["status"] = "done" print(f"调度器执行任务 {task_id}: {result}") time.sleep(1) self.scheduler_thread = threading.Thread(target=check_tasks, daemon=True) self.scheduler_thread.start() def query_user(self, args): user_id = args[0] return f"查询用户 {user_id} 成功" def send_message(self, args): user_id = args[0] content = " ".join(args[1:]) return f"向用户 {user_id} 发送消息: {content}"# 使用示例parser = DelayedBotCommandParser()print(parser.execute(*parser.parse("@机器人 延迟执行 5s 发送消息 456 提醒")))# 输出: 延迟任务已创建,任务ID: 0,将在 5 秒后执行# 5秒后输出: 延迟任务 0 执行结果: 向用户 456 发送消息: 提醒# 也可以执行普通命令print(parser.execute(*parser.parse("@机器人 查询用户 123")))# 输出: 查询用户 123 成功### 高级优化:使用真实调度器与持久化生产环境中,上述基于线程的延迟执行不可靠(如服务器重启丢失任务)。我们需要使用专业工具。使用APScheduler实现持久化调度:python# 使用APScheduler的示例(需要安装:pip install apscheduler)from apscheduler.schedulers.background import BackgroundSchedulerfrom apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStoreimport datetimeclass ProductionBotCommandParser: def __init__(self): self.commands = { "查询用户": self.query_user, "发送消息": self.send_message, "延迟执行": self.delayed_execute, } # 使用SQLite持久化任务 jobstores = { 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') } self.scheduler = BackgroundScheduler(jobstores=jobstores) self.scheduler.start() def delayed_execute(self, delay_seconds, sub_cmd, sub_args): # 将子命令序列化为字符串(实际需更复杂处理) sub_command_str = f"{sub_cmd} {' '.join(sub_args)}" # 添加延迟任务 run_date = datetime.datetime.now() + datetime.timedelta(seconds=delay_seconds) self.scheduler.add_job( self._execute_sub_command, 'date', run_date=run_date, args=[sub_command_str], id=f"delayed_{int(time.time())}" ) return f"延迟任务已创建,将在 {delay_seconds} 秒后执行" def _execute_sub_command(self, sub_command_str): # 解析并执行子命令 cmd, args, error = self.parse(sub_command_str) if error: print(f"执行延迟任务失败: {error}") else: handler = self.commands[cmd] result = handler(args) print(f"延迟任务执行结果: {result}") def query_user(self, args): user_id = args[0] return f"查询用户 {user_id} 成功" def send_message(self, args): user_id = args[0] content = " ".join(args[1:]) return f"向用户 {user_id} 发送消息: {content}"### 总结通过本文,我们从基础的机器人命令解析起步,逐步扩展至延迟执行功能。关键要点包括:1.命令解析:使用正则表达式提取命令和参数,支持灵活格式。2.延迟执行:通过解析时间单位和数值,计算执行时间。3.任务调度:从简单线程模拟到专业调度器(如APScheduler),确保任务持久化和可靠性。4.生产化考虑:使用数据库存储任务、错误处理、并发控制等。实际项目中,您可以根据需求选择适合的调度方案,并考虑任务取消、重试机制等高级特性。掌握这些技术后,您就能灵活构建功能丰富的机器人系统。
