如何优化Discord bot接收webhook消息并推送至指定频道的延迟问题
解决方案
延迟根因
你当前方案延迟高的核心原因是异步Discord Bot的事件循环和多线程HTTP服务的调度冲突:手写的BaseHTTPRequestHandler运行在独立线程,调用client.loop.create_task提交的发消息任务,需要等待Discord Bot的事件循环空闲才能被执行,队列积压就会出现数秒到半分钟的延迟。
最优实现方案(毫秒级延迟)
完全不需要自建Discord Bot,直接用Discord原生频道Webhook实现,是性能最高、延迟最低的方案,可完美匹配你要求的http://localhost:8000/post/category/channel/encoded-message请求格式:
- 提前在Discord每个目标频道创建Webhook:打开频道设置→集成→Webhooks→新建Webhook,复制对应Webhook URL,按分类、频道维度存储为映射表
- 用轻量HTTP框架搭建转发服务,收到请求后直接调用对应频道的Webhook发送消息即可
代码示例
依赖安装:pip install fastapi uvicorn requests
from fastapi import FastAPI import requests from urllib.parse import unquote app = FastAPI() # 按分类→频道维度预配置Discord Webhook映射 WEBHOOK_CONFIG = { "ops": { "error_log": "https://discord.com/api/webhooks/替换为对应频道的Webhook地址", "notify": "https://discord.com/api/webhooks/替换为对应频道的Webhook地址" }, "dev": { "debug": "https://discord.com/api/webhooks/替换为对应频道的Webhook地址" } } @app.get("/post/{category}/{channel}/{encoded_msg}") def forward_message(category: str, channel: str, encoded_msg: str): # 解码URL编码的消息内容 message = unquote(encoded_msg) # 校验分类、频道是否存在 if category not in WEBHOOK_CONFIG or channel not in WEBHOOK_CONFIG[category]: return {"code": 404, "msg": "分类或频道不存在"} # 调用Discord Webhook发送消息 requests.post( WEBHOOK_CONFIG[category][channel], json={"content": message} ) return {"code": 200, "msg": "发送成功"}
服务启动命令:uvicorn main:app --port 8000
保留Discord Bot的优化方案
如果必须保留Bot实现,需要将HTTP服务和Discord Bot共用同一个异步事件循环,避免跨线程调度开销:
import discord from aiohttp import web from urllib.parse import unquote # 初始化Discord Bot bot = discord.Client(intents=discord.Intents.default()) async def handle_webhook_request(request): category = request.match_info["category"] channel_name = request.match_info["channel"] encoded_msg = request.match_info["encoded_msg"] message = unquote(encoded_msg) # 匹配目标频道 target_channel = discord.utils.get( bot.get_all_channels(), name=channel_name, category__name=category ) if not target_channel: return web.Response(status=404, text="频道不存在") # 直接在同事件循环内发送消息 await target_channel.send(message) return web.Response(status=200, text="发送成功") async def main(): # 启动HTTP服务 app = web.Application() app.add_routes([web.get("/post/{category}/{channel}/{encoded_msg}", handle_webhook_request)]) runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, "localhost", 8000) await site.start() # 启动Discord Bot await bot.start("替换为你的Bot Token") if __name__ == "__main__": import asyncio asyncio.run(main())
内容的提问来源于stack exchange,提问作者charles strauss
相关产品推荐
相关产品推荐

