I'm trying to do something pretty simple. I just want Python to be able to call a quick function that sends a direct message over Discord. Basically a modified version of the FAQ example . I want another Python class to start the Discord client and pass the message string and user id. And I want the Discord client to simply send the string and then close and delete the entire class. After looking through docs I made these modifications:
import discord
class MyClient(discord.Client):
async def on_ready(self):
print('Logged on as {0}!'.format(self.user))
user = await self.fetch_user(self.destination_user)
await user.send(self.message)
await self.close()
def __init__(self, user_id, user_message):
self.destination_user = user_id
self.message = user_message
client = MyClient(desired_id, desired_message)
client.run('My Client ID')
#wait for client to end and then continue
However, I'm running into 2 problems. It looks like discord.Client doesn't allow an __init__()
function, and when I try to do async def __init__()
there's also an error. Are there other ways to pass arguments to it through Python , rather than react to messages in Discord? Also, self.close()
results in "RuntimeError: Cannot close a running event loop"
. What's the proper way to wait for on_ready()
to finish and then close it?
I can get it working by hardcoding the user ID and message, eliminating __init__()
and simply not closing the class. However, for some reason, even then self.get_user()
doesn't work, only self.fetch_user()
. The docs say to use get_user()
, so I'd prefer that, but I don't know what I'm doing wrong. My bot is in the same server as the target user, and I've given it both privileged intents, but get_user()
continues to return "None", whereas fetch_user()
properly messages the user, with the same exact arguments.
I found out what seems the proper way to run discord.Client
in this fashion:
import discord
import nest_asyncio
import asyncio
nest_asyncio.apply()
class DiscordClient(discord.Client):
async def on_ready(self):
user = await self.fetch_user(self.send_user)
await user.send(self.message)
async def on_message(self, message):
#Pause so there's no warning about operations not finishing when class closes
await asyncio.sleep(0.1)
await DiscordClient.close(self)
async def parameters(self, user, message):
self.send_user = user
self.message = message
async def send_discord(user, message):
print("Sending Discord message")
client = DiscordClient()
await client.parameters(user, message)
await client.start('Private Key')
print("Discord message sent")
asyncio.run(send_discord(user_id, "Test message contents"))
on_message
runs even it's the bot that sent the message, so it will quickly close itself. I had to add the wait or there were some race conditions or something causing a warning every time it closed.
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.