使用requests调用Discord API发送消息受限问题求助
问题原因与解决方案
1. 核心原因:Discord官方速率限制机制
这是Discord的反滥用速率限制,不是代码问题。官方对不同场景的消息发送有明确限制:
- 服务器频道:常规限制为每5秒5条消息,但新账号、低活跃度账号或触发风控时,会触发临时冷却(即你遇到的2-3分钟间隔)
- 用户私信频道:限制更严格,常规为每10秒1条,触发风控后冷却会延长至4-5分钟
- 跨不同频道发送时,限制按频道维度独立计算,因此可以连续发送,同一频道则会触发单频道的速率限制
2. 你的代码存在的细节问题
虽然核心是官方限制,但代码里的几个细节可能加剧限制触发:
- 固定nonce值:你使用了固定的
nonce,这个字段要求每次请求唯一,重复值会被Discord判定为异常请求,加重限制 - 未处理速率限制响应:Discord返回429状态码时会附带
Retry-After头部,你的代码未处理该字段,继续发送请求会触发更严格的临时冷却 - 拼写错误:请求URL中的
channal_id应为channel_id(虽你说返回正确响应,大概率是笔误)
3. 优化建议
- 生成随机nonce:每次请求生成唯一的随机字符串,比如用
str(random.randint(10**18, 10**19-1)) - 处理速率限制:检测响应状态码,若为429则读取
Retry-After值,等待对应时间后重试 - 使用官方推荐库:避免直接用requests调用API,建议用
discord.py或nextcord,这类库内置了速率限制处理,自动遵守官方规则
优化后的示例代码(含速率限制处理+随机nonce)
import requests import random import time token = "" channel_id = "" cookies = { ... } headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0', 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', 'Authorization': token, 'X-Super-Properties': 'eyJvcyI6IldpbmRvd3MiLCJicm93c2VyIjoiRmlyZWZveCIsImRldmljZSI6IiIsInN5c3RlbV9sb2NhbGUiOiJlbi1VUyIsImJyb3dzZXJfdXNlcl9hZ2VudCI6Ik1vemlsbGEvNS4wIChXaW5kb3dzIE5UIDEwLjA7IFdpbjY0OyB4NjQ7IHJ2OjEwMi4wKSBHZWNrby8yMDEwMDEwMSBGaXJlZm94LzEwMi4wIiwiYnJvd3Nlcl92ZXJzaW9uIjoiMTAyLjAiLCJvc192ZXJzaW9uIjoiMTAiLCJyZWZlcnJlciI6IiIsInJlZmVycmluZ19kb21haW4iOiIiLCJyZWZlcnJlcl9jdXJyZW50IjoiIiwicmVmZXJyaW5nX2RvbWFpbl9jdXJyZW50IjoiIiwicmVsZWFzZV9jaGFubmVsIjoic3RhYmxlIiwiY2xpZW50X2J1aWxkX251bWJlciI6MTM4MjU0LCJjbGllbnRfZXZlbnRfc291cmNlIjpudWxsfQ==', 'X-Discord-Locale': 'en-US', 'X-Debug-Options': 'bugReporterEnabled', 'Origin': 'https://discord.com', 'Alt-Used': 'discord.com', 'Connection': 'keep-alive', 'Referer': f'https://discord.com/channels/@me/{channel_id}', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'same-origin', } def send_message(content): json_data = { 'content': content, 'nonce': str(random.randint(10**18, 10**19 - 1)), 'tts': False, } while True: response = requests.post( f'https://discord.com/api/v9/channels/{channel_id}/messages', cookies=cookies, headers=headers, json=json_data ) if response.status_code == 429: retry_after = int(response.headers.get('Retry-After', 60)) print(f"触发速率限制,等待{retry_after}秒后重试") time.sleep(retry_after) else: print(response.json()) break # 示例调用 send_message("测试消息1") send_message("测试消息2")
4. 额外注意事项
- 不要尝试绕过速率限制,这违反Discord服务条款,可能导致账号封禁
- 若为机器人账号,使用机器人令牌(Bot Token)而非用户令牌,机器人的速率限制更宽松且官方支持
内容的提问来源于stack exchange,提问作者farhan jatt
相关产品推荐
相关产品推荐

