如何通过Discord API根据用户名获取用户snowflake ID
问题核心限制
首先明确Discord API的硬性规则:
- 普通Bot令牌没有全局按用户名查询用户Snowflake ID的接口权限,这是平台为防范批量爬取、骚扰用户设置的隐私限制,不存在直接传入用户名就返回对应ID的公开API。
- 你能搜到的ID反查用户名方案,前提是你已经持有用户ID、且用户和Bot存在共同服务器/历史交互,反向查询的路径走不通。
- 即使用户和Bot在同一个服务器内,你也无法通过API直接传用户名精准查询,只能拉取全服务器成员列表做本地匹配,效率极低,且用户不在Bot所在服务器时这个方法完全失效。
推荐实现方案(合规、零错误率)
不要让用户手动输入用户名,接入Discord OAuth2授权流是体验最好、完全符合平台规则的方案:
- 在Discord开发者后台为你的应用配置OAuth2重定向地址,勾选
identify权限范围 - 在表单页添加「绑定Discord账号」按钮,用户点击后跳转到Discord官方授权页
- 用户完成授权后,Discord会将授权码回调到你的站点,你通过授权码换取用户访问令牌,即可直接拿到用户的Snowflake ID、用户名等信息,全程不需要用户手动输入,不会出现输错、匹配不到的问题
- 将拿到的用户ID存入数据库,后续发通知直接调用即可
核心实现代码(适配discord.py生态):
import aiohttp async def fetch_discord_user_info(auth_code: str) -> tuple[str, str]: token_endpoint = "https://discord.com/api/oauth2/token" token_payload = { "client_id": "你的应用Client ID", "client_secret": "你的应用Client Secret", "grant_type": "authorization_code", "code": auth_code, "redirect_uri": "你后台配置的回调地址" } async with aiohttp.ClientSession() as session: # 换取访问令牌 async with session.post(token_endpoint, data=token_payload) as resp: token_res = await resp.json() # 拉取用户信息 user_endpoint = "https://discord.com/api/users/@me" headers = {"Authorization": f"Bearer {token_res['access_token']}"} async with session.get(user_endpoint, headers=headers) as resp: user_res = await resp.json() # 返回(用户Snowflake ID,用户名) return user_res["id"], user_res["username"]
你原来的发信逻辑不要写在on_ready事件里,避免每次Bot重启都触发推送,建议封装成独立函数按需调用:
async def push_product_update(user_id: str, update_content: str): target_user = await client.fetch_user(user_id) await target_user.send(update_content)
不推荐的兜底方案
如果你坚持要让用户手动输入用户名,仅有一种合规的兜底路径,缺陷非常明显:
- 提前将Bot拉入一个公共服务器,要求所有提交表单的用户必须加入该服务器。Bot启动后缓存该服务器的全量成员列表,用户输入用户名后在本地缓存中匹配对应ID。这个方案的问题是强制要求用户加群、用户修改用户名后需要实时同步缓存,匹配失败率很高。
注意:严禁使用用户自助令牌(User Token)调用非公开接口做全局用户搜索,这类行为违反Discord开发者服务条款,会直接导致你的Bot、应用被封禁。
内容的提问来源于stack exchange,提问作者Olney1
相关产品推荐
相关产品推荐

