简介:
我所追求的是当用户注册我的discord.py机器人时:
- 他们会收到一封一次性使用oauth2链接的电子邮件,该链接将要求他们登录discord
- 登录后,我希望它能自动添加他们/邀请他们加入公会,如果他们还没有添加
- 自动加入公会后,自动为他们指定一个注册角色
要点:
- 我有一个HTTPPOST webhook,当用户从我用来处理用户注册的SAAS注册时,它会被触发
- 这个机器人目前只在我的Discord服务器上,所以扩展这个机器人到多个服务器上并不是一个问题
我的尝试:
这是一些使用FastAPI的粗略代码草案。此代码未经测试,无法工作。
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
from cryptography.fernet import Fernet
import base64
import time
app = FastAPI()
key = Fernet.generate_key()
fernet = Fernet(key)
# this would get fired from my HTTP POST webhook once the user sucessfully signs up
@app.post("/generate_link/{user_id}")
def generate_link(user_id: int):
encrypted_id = fernet.encrypt(str(user_id).encode())
timestamp = str(int(time.time()))
data = f"{encrypted_id.decode()}:{timestamp}"
token = base64.urlsafe_b64encode(data.encode()).decode()
# send one time use encrypted url to user via email API
email_api.send("mydomain/validate_link?token={token}")
# this would get fired when user goes to onetime generated link
@app.get("/validate_link")
def validate_link(token: str):
try:
# Decode the token from the query parameter and split the encrypted ID and timestamp
data = base64.urlsafe_b64decode(token.encode()).decode()
encrypted_id, timestamp = data.split(":")
timestamp = int(timestamp)
# Check that the timestamp is within the valid range (for example 10 minutes)
if time.time() - timestamp > 600:
return "Link expired"
# Decrypt the user ID and do something with it
user_id = int(fernet.decrypt(encrypted_id.encode()).decode())
# redirect user to oauth2 link with discord now that we have verified them?
return f"User ID: {user_id}"
except:
return "Invalid link"
我的终极问题:
- 有没有内置的功能,做什么,我想在这里与不和谐oauth2,我可以只发送给用户一个链接后,电子邮件注册?
- 或者我需要像我在这里使用FastAPI尝试的那样进行自定义吗?例如,将步骤分开,让一个步骤生成一次性URL,第二个步骤使用oauth2/adding to guild/adding role登录
感谢任何花时间阅读我的文章的人!
2条答案
按热度按时间wr98u20j1#
这是可能的。多亏了Oath 2,你可以做很多事情,比如添加某人到公会,并在这样的公会中给予他们角色,所有这些都是一次性的。我用Flask来做,因为我最习惯这样做,但这并不重要。
首先,你需要一个discord Application。一旦你有了它,你去OAuth2,URL生成器,并选择至少
identify
和guild.join
。复制该URL并将其粘贴到代码中的变量中。重定向URI应该是你的Flask应用程序的URL到/回调。在代码的开头完成其余的变量(如果你不知道如何获取角色和服务器的ID,请查看Discord开发模式)。
确保机器人在您的服务器上,并且至少具有
CREATE_INSTANT_INVITE
和MANAGE_ROLES
权限。这就是一切,下面的代码应该工作.它所做的是使用OAth 2获取用户ID,然后使用它使其加入公会指定的角色.你现在可以通过电子邮件发送
AUTORISATION_URL
,或者如果你喜欢自己的URL的URL到你的Flask应用程序.我知道Flask可能不适合“生产部署”,所以考虑在代码中添加
waitress
。d8tt03nd2#
如果有人在Google上找到这个:
感谢Clement的回答,我能够得到我的最终解决方案。在做了更多的挖掘之后,我最终确定我可以通过添加
state
参数来使oauth2链接成为一次性使用链接。state
参数可以与oauth2链接一起传递。在用户使用discord登录授权后,oauth2将它们重定向回服务器(在我的例子中是Flask)。然后在他们重定向之后,我们可以检查在url中传递的这个状态令牌是否已经使用或者还没有使用数据库(或者一些简单的东西,比如在磁盘数据库上的小用例)。我想给用户发送一个一次性的链接,这样他们就不能重用这个链接或与他们的朋友分享。生成一个时间状态令牌:
我使用了一个hash来完成这个操作。这段代码是虚拟的模板代码,因为我不想透露我是如何做hash的,但是你可以用你想用什么来填充细节。然后我把它存储在一个数据库中,以便在用户点击aouth2回调端点时引用。
发送onetime oauth2链接给用户:
我使用smptlib在HTTP POST webhook被触发时给他们发了一封电子邮件。我使用了一个电子邮件html模板来使电子邮件看起来很漂亮。这也是虚拟代码,但如果你想使用我的代码,你可以在这里放你自己的信息
Oauth回调端点:
在用户使用链接并使用discord进行授权后,discord将重定向到您的oauth2回调端点。在此端点中,我们可以将用户添加到所需的公会,并为他们提供所需的角色,然后将他们重定向到一个漂亮的“You're all done”成功页面。一个关键注意事项是将他们添加到公会(如果他们还没有进入公会服务器),你需要发送一个put请求。然后要给予他们角色,你需要发送一个patch请求。
Config.py:
回调端点: