我正在开发一个名为 Indigo 的 Discord 机器人。它是一个具有多种功能并使用 SQLite 的机器人。我正在开发仪表板。我将提供该机器人的一些代码,仅提供相关的内容,因为该机器人有 600 多行长。
import discord
from discord import app_commands
from discord.ext import ipc
import aiosqlite
from discord.ext import commands, tasks
import psutil
import aiohttp
import random
from io import BytesIO
from itertools import cycle
import datetime
import re
from typing import Optional
data = {}
async def create_users_table():
async with aiosqlite.connect('users.db') as db:
await db.execute('''
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
balance INTEGER DEFAULT 0,
experience INTEGER DEFAULT 0,
level INTEGER DEFAULT 1
)
''')
await db.commit()
us = 0
um = 0
uh = 0
ud = 0
TOKEN = 'no token for you'
VERIFIED_ROLE_ID = 1180692059707953215
class MyBot(commands.Bot):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ipc = ipc.Server(self, secret_key=b"thisisakey")
async def on_ready(self):
print("Ready!")
async def on_ipc_ready(self):
print("IPC server is ready.")
async def on_ipc_error(self, endpoint, error):
print(f"Endpoint {endpoint} raised an error: {error}")
async def update_balance(self, user_id, amount):
async with aiosqlite.connect('users.db') as db:
cursor = await db.execute('SELECT * FROM economy WHERE user_id = ?', (user_id,))
data = await cursor.fetchone()
if not data:
await db.execute('INSERT INTO economy (user_id, balance) VALUES (?, ?)', (user_id, amount))
else:
new_balance = data['balance'] + amount
await db.execute('UPDATE economy SET balance = ? WHERE user_id = ?', (new_balance, user_id))
await db.commit()
async def get_balance(self, user_id):
print(f"Getting balance for user_id: {user_id}")
try:
async with aiosqlite.connect('users.db') as db:
cursor = await db.cursor()
await cursor.execute('SELECT balance FROM users WHERE user_id = ?', (user_id,))
result = await cursor.fetchone()
print(f"Result of db operation: {result}")
if result is None:
return 0 # return default balance if user_id not found
else:
return result[0] # return the balance
except Exception as e:
print(f"An error occurred: {e}")
bot = MyBot(intents=discord.Intents.all(), command_prefix='i!')
bot.remove_command('help')
# fast forward to the end (just commands)
bot.run(TOKEN)
bot.ipc.start()
仪表板:
import os
from quart import Quart, render_template, redirect, url_for
from quart_discord import DiscordOAuth2Session, requires_authorization, Unauthorized
from discord.ext import ipc
import discord
from dotenv import load_dotenv
load_dotenv()
app = Quart(__name__)
app.secret_key = b"thisisakey"
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "true"
app.config["DISCORD_CLIENT_ID"] = os.getenv("DISCORD_CLIENT_ID")
app.config["DISCORD_CLIENT_SECRET"] = os.getenv("DISCORD_CLIENT_SECRET")
app.config["DISCORD_REDIRECT_URI"] = os.getenv("DISCORD_REDIRECT_URI")
app.config["DISCORD_BOT_TOKEN"] = os.getenv("DISCORD_BOT_TOKEN")
discord = DiscordOAuth2Session(app)
ipcClient = ipc.Client(secret_key=os.getenv("IPC_SECRET_KEY"))
@app.route("/login")
async def login():
return await discord.create_session()
@app.route("/callback")
async def callback():
try:
await discord.callback()
return redirect(url_for("dashboard"))
except Unauthorized:
return redirect(url_for("login"))
except Exception as e:
# Log other exceptions for debugging
print(f"Exception during callback: {e}")
return redirect(url_for("login"))
@app.route("/")
async def home():
return await render_template("home.html")
@app.route("/dashboard/")
async def dashboard():
user = await discord.fetch_user()
guildCount = await ipcClient.request("get_guild_count")
guildIds = await ipcClient.request("get_guild_ids")
try:
userGuilds = await discord.fetch_guilds()
except Unauthorized:
return await redirect(url_for("login"))
guilds = []
for guild in userGuilds:
if guild.permission.manage_guild:
guilds.classColor = "greenBorder" if guild.id in guildIds else "redBorder"
guilds.append(guild)
guilds.sort(key=lambda x: x.classColor == "redBorder")
return await render_template("dashboard.html", user=user, guilds=guilds)
if __name__ == "__main__":
app.run(debug=True, port=5001)
我用来将东西连接在一起的小批处理文件:
@ECHO OFF
START python.exe "C:/Users/no name for you :)/discord bot/backend/followtutorial/bot.py"
ECHO Bot has started running
START python "C:/Users/no name for you :)/discord bot/backend/followtutorial/dashboard.py"
ECHO Dashboard has started running
START http://localhost:5000/
PAUSE
现在,这是尝试登录后的仪表板输出:
* Serving Quart app 'dashboard'
* Debug mode: True
* Please use an ASGI server (e.g. Hypercorn) directly in production
* Running on http://127.0.0.1:5001 (CTRL + C to quit)
[2023-12-19 09:50:48 -0600] [49028] [INFO] Running on http://127.0.0.1:5001 (CTRL + C to quit)
[2023-12-19 09:50:55 -0600] [49028] [INFO] 127.0.0.1:51735 GET / 1.1 200 352 7178
[2023-12-19 09:50:55 -0600] [49028] [INFO] 127.0.0.1:51735 GET / 1.1 - - 7178
[2023-12-19 09:50:56 -0600] [49028] [INFO] 127.0.0.1:51735 GET /login 1.1 302 939 8295
[2023-12-19 09:50:56 -0600] [49028] [INFO] 127.0.0.1:51735 GET /login 1.1 - - 9301
Exception during callback: (mismatching_state) CSRF Warning! State not equal in request and response.
[2023-12-19 09:51:05 -0600] [49028] [INFO] 127.0.0.1:51754 GET /callback 1.1 302 199 5259
[2023-12-19 09:51:05 -0600] [49028] [INFO] 127.0.0.1:51754 GET /callback 1.1 - - 5259
[2023-12-19 09:51:05 -0600] [49028] [INFO] 127.0.0.1:51754 GET /login 1.1 302 939 5155
[2023-12-19 09:51:05 -0600] [49028] [INFO] 127.0.0.1:51754 GET /login 1.1 - - 5155
[2023-12-19 09:51:07 -0600] [49028] [INFO] 127.0.0.1:51754 GET /callback 1.1 302 209 293931
[2023-12-19 09:51:07 -0600] [49028] [INFO] 127.0.0.1:51754 GET /callback 1.1 - - 293931
[2023-12-19 09:51:09 -0600] [49028] [ERROR] Error in ASGI Framework
Traceback (most recent call last):
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 992, in _wrap_create_connection
return await self._loop.create_connection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 1099, in create_connection
raise exceptions[0]
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 1081, in create_connection
sock = await self._connect_sock(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 984, in _connect_sock
await self.sock_connect(sock, address)
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\asyncio\proactor_events.py", line 727, in sock_connect
return await self._proactor.connect(sock, address)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", line 798, in _poll
value = callback(transferred, key, ov)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", line 594, in finish_connect
ov.getresult()
ConnectionRefusedError: [WinError 1225] The remote computer refused the network connection
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\hypercorn\asyncio\task_group.py", line 27, in _handle
await app(scope, receive, send, sync_spawn, call_soon)
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\hypercorn\app_wrappers.py", line 33, in __call__
await self.app(scope, receive, send)
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1638, in __call__
await self.asgi_app(scope, receive, send)
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1664, in asgi_app
await asgi_handler(receive, send)
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\asgi.py", line 52, in __call__
raise_task_exceptions(done)
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\utils.py", line 180, in raise_task_exceptions
raise task.exception()
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\asgi.py", line 100, in handle_request
response = await _handle_exception(self.app, error)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\asgi.py", line 357, in _handle_exception
raise error
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\asgi.py", line 98, in handle_request
response = await self.app.handle_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1380, in handle_request
return await self.handle_exception(error)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1376, in handle_request
return await self.full_dispatch_request(request_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1414, in full_dispatch_request
result = await self.handle_user_exception(error)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1007, in handle_user_exception
raise error
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1412, in full_dispatch_request
result = await self.dispatch_request(request_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\quart\app.py", line 1506, in dispatch_request
return await self.ensure_async(handler)(**request_.view_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\discord bot\backend\followtutorial\dashboard.py", line 51, in dashboard
guildCount = await ipcClient.request("get_guild_count")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\ipc\client.py", line 97, in request
await self.init_sock()
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\discord\ext\ipc\client.py", line 61, in init_sock
self.multicast = await self.session.ws_connect(self.url, autoping=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\client.py", line 825, in _ws_connect
resp = await self.request(
^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\client.py", line 574, in _request
conn = await self._connector.connect(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 544, in connect
proto = await self._create_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 911, in _create_connection
_, proto = await self._create_direct_connection(req, traces, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1235, in _create_direct_connection
raise last_exc
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1204, in _create_direct_connection
transp, proto = await self._wrap_create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\No name for you :)\AppData\Local\Programs\Python\Python312\Lib\site-packages\aiohttp\connector.py", line 1000, in _wrap_create_connection
raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host localhost:20000 ssl:default [The remote computer refused the network connection]
[2023-12-19 09:51:09 -0600] [49028] [INFO] 127.0.0.1:51754 GET /dashboard/ 1.1 500 - 2257904
[2023-12-19 09:51:09 -0600] [49028] [INFO] 127.0.0.1:51754 GET /dashboard/ 1.1 - - 2257904
[2023-12-19 09:51:09 -0600] [49028] [INFO] 127.0.0.1:51763 GET /favicon.ico 1.1 - - 1017
[2023-12-19 09:51:09 -0600] [49028] [INFO] 127.0.0.1:51763 GET /favicon.ico 1.1 404 207 6134
现在,我登录,然后它将我重定向到 /callback,在那里我被发送回 /login!然后,我再试一次,它只是吐出这个错误,并且几乎没有给我的浏览器提供任何信息!
我尝试一次启动它们,寻找我的 ipc 和 bot 方法中的错误,但无济于事。
我期待它只是将我的仪表板发回。
注意:机器人在这一切过程中只有正常输出
使用discord-ext-ipcx代替discord-ext-ipc修复了这个问题(discord-ext-ipc不再维护)