如何检测API状态变化实现Discord Bot在楼宇开放时发消息
实现方案
核心逻辑是定时轮询API对比状态变化,你现有API是被动返回查询结果的类型,没有主动推送能力的话,轮询是成本最低、最稳定的实现方式,具体操作如下:
前置准备
- 提前准备好Discord Bot的Token、要发送通知的目标频道ID,确认Bot已经加入对应服务器,且拥有目标频道的发消息权限
- 选你熟悉的开发语言即可,下面以Python生态最常用的
discord.py库举例
实现逻辑
- 启动Bot时先拉取一次当前楼宇状态,存在本地变量里作为初始基准值,避免刚上线就误发通知
- 开启固定间隔的定时轮询任务,间隔根据你的需求设就行,建议1-5分钟,别太频繁打挂API
- 每次轮询调用楼宇状态API,解析返回值拿到当前
state.open字段的布尔值 - 做状态判断:只有当本地存储的上一次状态为关闭、当前拉取到的状态为开放时,才触发发消息逻辑,其余情况只更新本地存储的状态值,避免重复发消息
- 消息发完后,把本地存储的状态更新为当前最新值
核心代码示例
先安装依赖:pip install discord.py requests
核心逻辑代码:
import discord import requests import asyncio # 配置项 替换成你自己的参数 BOT_TOKEN = "你的Discord Bot Token" NOTIFY_CHANNEL_ID = 1234567890 # 替换成目标通知频道的数字ID BUILDING_API_URL = "你的楼宇查询API完整地址" POLL_INTERVAL = 60 # 轮询间隔 单位秒 示例为1分钟查一次 intents = discord.Intents.default() bot = discord.Client(intents=intents) last_open_state = None # 用来存上一次查询到的楼宇开放状态 @bot.event async def on_ready(): global last_open_state print(f"Bot登录成功,账号:{bot.user}") # 启动时先拉取初始状态 try: resp = requests.get(BUILDING_API_URL, timeout=10) resp.raise_for_status() init_data = resp.json() last_open_state = init_data["state"]["open"] print(f"初始状态加载完成,当前楼宇开放状态:{last_open_state}") except Exception as e: print(f"初始状态拉取失败,将在第一次轮询时重试,错误信息:{str(e)}") last_open_state = None # 启动轮询循环 while True: await asyncio.sleep(POLL_INTERVAL) try: resp = requests.get(BUILDING_API_URL, timeout=10) resp.raise_for_status() current_data = resp.json() current_open = current_data["state"]["open"] # 仅当状态从关闭变为开放时发通知 if last_open_state is False and current_open is True: target_channel = bot.get_channel(NOTIFY_CHANNEL_ID) if target_channel: await target_channel.send("通知:楼宇现已开放,可以进入") # 如果要带当前楼内人数,直接从API返回值里取对应字段拼到消息内容里即可 # 更新本地存储的状态 last_open_state = current_open except Exception as e: print(f"本次轮询出错,将在下个间隔重试,错误信息:{str(e)}") bot.run(BOT_TOKEN)
注意事项
- 轮询间隔不要设太短,小于10秒很容易触发API限流,对于楼宇开放通知这类场景,1-5分钟的延迟完全可以接受
- 一定要加异常捕获,API偶尔超时、返回服务错误的时候不要让Bot直接崩溃
- 如果API有鉴权要求,在
requests.get里加headers参数传对应的鉴权字段即可 - 如果怕Bot重启丢失内存里的状态导致误发,可以把
last_open_state存在本地文本文件或者轻量数据库里,不用存在内存中
如果你用其他语言的Discord Bot库(比如discord.js、JDA等),逻辑完全一致,只是语法对应调整即可,核心都是「存旧状态→定时拉新状态→检测到关转开的边缘变化→发消息→更新旧状态」
内容的提问来源于stack exchange,提问作者B0urg
相关产品推荐
相关产品推荐

