You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:51:25