gpt4 book ai didi

python - 一个应用程序中的 discord bot 和 websocket 服务器

转载 作者:行者123 更新时间:2023-12-05 09:34:52 31 4
gpt4 key购买 nike

我想在 heroku 中制作一个应用程序,它将一些数据作为 websocket 服务器并将其作为 discord bot 发送。

这就是我尝试实现这个想法的方式:

# -*- coding: utf-8 -*-  
import asyncio, websockets, discord

client = discord.Client()
channel = client.get_channel(...)
print(channel)

async def response(websocket, path):
global channel
r = await websocket.recv()
print(r)
await channel.send(str(r))

PORT = os.environ.get('PORT')
start_server = websockets.serve(response, '0.0.0.0', os.environ.get('PORT'))
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

但我不知道如何在这样的代码中启动一个 discord 机器人,以便它与 websocket 服务器并行工作。请告诉我该怎么做。

最佳答案

我的第一个想法是使用 threading在单独的线程中运行 websockets 但它不能在线程中使用 asyncio.get_event_loop()


因为 websockets 使用 asyncio 就像 discord 所以我尝试在 asyncio 中使用相同的循环来启动两者。

在深入了解 discord.run() 的源代码后,我发现它使用了 asyncio.get_event_loop().run_forever() 所以我尝试启动 websockets 没有 asyncio.get_event_loop().run_forever() 并且对我有用。

# --- start ---

# - websockets -

server = websockets.serve(response, '0.0.0.0', '8000')
asyncio.get_event_loop().run_until_complete(server)
# without `run_forever()` because `client.run()` will run `run_forever()`

# - discord -

TOKEN = os.getenv('DISCORD_TOKEN')
client.run(TOKEN) # `client.run()` will run `run_forever()`

我用来测试它的最小工作代码

ma​​in.py(带有 discord 客户端websockets 服务器)

import os
import asyncio
import discord
import websockets

# --- websockets ----

async def response(websocket, path):
message = await websocket.recv()
print(f"[ws server] message < {message}")

#answer = f"[{message}]"

#await websocket.send(answer) # if client expect `response` then server has to send `response`
#print(f"[ws server] answer > {answer}")

# `get_channel()` has to be used after `client.run()`
channel = client.get_channel(MY_CHANNEL_ID) # access to channel

await channel.send(f'websockets: {message}')

# --- discord ---

MY_CHANNEL_ID = 709507681441808388 # you have to use own number

client = discord.Client()

# `get_channel()` has to be used after `client.run()`
#print(client.get_channel(MY_CHANNEL_ID)) # None

@client.event
async def on_message(message):
if message.author != client.user:
print('message.content:', message.content)

# --- start ---

# - websockets -

print('running websockets ws://0.0.0.0:8000')
server = websockets.serve(response, '0.0.0.0', '8000')
asyncio.get_event_loop().run_until_complete(server)
# without `run_forever()` because `client.run()` will run `run_forever()`

# - discord -

print('running discord')
TOKEN = os.getenv('DISCORD_TOKEN')
client.run(TOKEN)

client.py(我用来测试websockets serverwebsockets client)

import asyncio
import websockets

uri = 'ws://0.0.0.0:8000'

async def send_message():
async with websockets.connect(uri) as websocket:
message = input("msg: ")

await websocket.send(message)
print(f"[ws client] message > {message}")

#answer = await websocket.recv()
#print(f"[ws client] answer < {answer}")

asyncio.get_event_loop().run_until_complete(send_message())

顺便说一句:

你不能在 client.run() 之前使用 get_channel() 因为它给出了 None 而我在 中使用它响应()


编辑:

我使用 on_ready() 来使用 get_channel() - 如果我有权访问 ,我还会检查 response() > channel

为了确保我在开始 discord 之前设置了 channel = None

主.py

import os
import asyncio
import discord
import websockets


# --- websockets ----

async def response(websocket, path):
global channel

message = await websocket.recv()
print(f"[ws server] message < {message}")

#answer = f"my answer: [{message}]"

#await websocket.send(answer) # if client expect `response` then server has to send `response`
#print(f"[ws server] answer > {answer}")

# `get_channel()` has to be used after `client.run()`

if not channel:
print('[ws server] getting discord channel:', MY_CHANNEL_ID)
channel = client.get_channel(MY_CHANNEL_ID) # access to channel

if not channel:
print("[ws server] can't access channel:", MY_CHANNEL_ID)
else:
print('[ws server] channel:', channel, 'message:', message)
#await channel.send(f'websockets: {message}')
await channel.send(message)

# --- discord ---

MY_CHANNEL_ID = 709507681441808388 # you have to use own number

client = discord.Client()

# `get_channel()` has to be used after `client.run()`
#print(client.get_channel(MY_CHANNEL_ID)) # None

@client.event
async def on_ready():
global channel

if not channel:
print('[on_ready] getting discord channel:', MY_CHANNEL_ID)
channel = client.get_channel(MY_CHANNEL_ID) # access to channel

if not channel:
print("[on_ready] can't access channel:", MY_CHANNEL_ID)
else:
print('[on_ready] channel:', channel)

@client.event
async def on_message(message):
if message.author != client.user:
print('[on_message] message.content:', message.content)

# --- start ---

# - websockets -

print('running websockets ws://0.0.0.0:8000')
server = websockets.serve(response, '0.0.0.0', '8000')
asyncio.get_event_loop().run_until_complete(server)
# without `run_forever()` because `client.run()` will run `run_forever()`

# - discord -

channel = None # set default value at start

print('running discord')
TOKEN = os.getenv('DISCORD_TOKEN')
client.run(TOKEN)

对于bot

也是如此

ma​​in-bot.py

import os
import asyncio
import discord
from discord.ext import commands
import websockets

# --- websockets ----

async def response(websocket, path):
global channel

message = await websocket.recv()
print(f"[ws server] message < {message}")

#answer = f"my answer: [{message}]"

#await websocket.send(answer) # if client expect `response` then server has to send `response`
#print(f"[ws server] answer > {answer}")

# `get_channel()` has to be used after `client.run()`

if not channel:
print('[ws server] getting discord channel:', MY_CHANNEL_ID)
channel = bot.get_channel(MY_CHANNEL_ID) # access to channel

if not channel:
print("[ws server] can't access channel:", MY_CHANNEL_ID)
else:
print('[ws server] channel:', channel, 'message:', message)
#await channel.send(f'websockets: {message}')
await channel.send(message)

# --- discord ---

MY_CHANNEL_ID = 709507681441808388 # you have to use own number

bot = commands.Bot(command_prefix="!")

# `get_channel()` has to be used after `client.run()`
#print(client.get_channel(MY_CHANNEL_ID)) # None

@bot.event
async def on_ready():
global channel

if not channel:
print('[on_ready] getting discord channel:', MY_CHANNEL_ID)
channel = bot.get_channel(MY_CHANNEL_ID) # access to channel

if not channel:
print("[on_ready] can't access channel:", MY_CHANNEL_ID)
else:
print('[on_ready] channel:', channel)

#@bot.event
#async def on_message(message):
# if message.author != bot.user:
# print('message.content:', message.content)

@bot.command()
async def ping(ctx):
await ctx.send('pong')

# --- start ---

# - websockets -

print('running websockets ws://0.0.0.0:8000')
server = websockets.serve(response, '0.0.0.0', '8000')
asyncio.get_event_loop().run_until_complete(server)
# without `run_forever()` because `client.run()` will run `run_forever()`

# - discord -

channel = None # set default value at start

print('running discord')
TOKEN = os.getenv('DISCORD_TOKEN')
bot.run(TOKEN)

关于python - 一个应用程序中的 discord bot 和 websocket 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66221714/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com