简体   繁体   中英

How to know when Flask has received data?

This is a long one, so let me explain. I'm trying to write a discord bot in python using oauth2 in flask. Here is what I am trying to achieve in pseudocode: 1: user sends command in channel, 2: the bot then sends an embed with a link to the user that contains the oauth2 authorization, 3: the user clicks on the oauth2 and authorizes which gives the program their email address linked to their discord, 4: that data is then saved as a variable to be used later, and a dm is sent to the user containing their email address. Sounds simple.

Due to discord.py being in 2.0 so I can use views and buttons and things I'm not using cogs as they were unreliable and finicky so this is all one big code. I do have flask and the discord bot running on separate threads (discord bot being on 1, and flask being on 2).

#imports
import discord
from discord.ext import commands
from decouple import config
import sqlite3
from flask import Flask, request, redirect, render_template
import requests
from waitress import serve
import threading
#discord oauth things
CLIENT_ID = ''
CLIENT_SECRET = ''
REDIRECT_URI = "http://127.0.0.1:5000/success"
SCOPE = "identify%20email"
DISCORD_LOGIN = f"https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope={SCOPE}&prompt=consent"
DISCORD_TOKEN = "https://discord.com/api/oauth2/token"
DISCORD_API = "https://discord.com/api"
#bot init
CLIENTTOKEN = config('CLIENTTOKEN')
class Bot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.default()
        intents.message_content = True
        super().__init__(command_prefix=commands.when_mentioned_or('>'), intents=intents)
    async def on_ready(self):
        print(f'Logged in as {self.user} (ID: {self.user.id})')
        print('------')
client = Bot()
#all flask
app = Flask(__name__)
@app.route("/", methods = ["get"])
def index():
    return render_template('index.html')
@app.route("/login", methods = ["get"])
def login():
    return redirect(DISCORD_LOGIN)
@app.route("/success", methods = ["get"])
def success():
    code = request.args.get("code")
    useraccesstoken = getaccesstoken(code)
    useremail = getuseremail(useraccesstoken)
    return render_template('success.html'), useremail
def getaccesstoken(code):
    payload = {
       "client_id": CLIENT_ID,
       "client_secret": CLIENT_SECRET,
       "grant_type": "authorization_code",
       "code": code,
       "redirect_uri": REDIRECT_URI,
       "scope": SCOPE
    }
    headers = {
        "Content-Type": "application/x-www-form-urlencoded"
    }
    accesstoken = requests.post(url = DISCORD_TOKEN, data = payload, headers = headers)
    json = accesstoken.json()
    return json.get("access_token")
def getuseremail(useraccesstoken):
    url = DISCORD_API+"/users/@me"
    headers = {
        "Authorization": f"Bearer {useraccesstoken}"
    }
    userdata = requests.get(url = url, headers = headers)
    userjson = userdata.json()
    return userjson.get("email")
def web():
    serve(app, host="127.0.0.1", port=5000)
#command
@client.command()
    async def getemail(ctx):
            firstmessageembed = discord.Embed(title = "Link your Plex and your Discord", color= 
            discord.Color.from_rgb(160,131,196), description="🔗 Please click [HERE](http://127.0.0.1:5000/login) to get started.")
            firstmessageembed.set_author(name = ctx.message.author, icon_url = ctx.author.avatar.url)
            firstmessageembed.set_footer(text=f'You have 30 seconds to authorize.')
            await ctx.send(embed = firstmessageembed)
            await client.wait_for(????????????????)

threading.Thread(target=web, daemon=True).start()
client.run(CLIENTTOKEN)

As you can see I have no idea what I am waiting for and I have no idea how to know when the user has submitted the oauth2.

I made this concept that you can try to use

  1. Bot sends a link to the Oauth2 page
  2. Then it redirects to your web server
  3. On your web server JavaScript sends HTTP request to Discord API and makes a message to the user

Okay so I did a lot of experimenting. Basically you will need to thread the discord bot and then use QUART to use await async to get the data from it. Because there is really no way to send data between, you need to use a database, store the data that you get from Quart into the database, then just access it from the discord bot when you need to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM