Issue
In discord.py, you can initialize a Client
, and run it with client.run()
. But the function never returns.
What if I just want to just retrieve some message history then use it in jupyter notebook?
@bot.command()
async def history(ctx):
counter = 0
messageList=[]
async for message in ctx.channel.history(limit = 100):
print(message.author, message.content)
counter += 1
messageList.append(message)
await ctx.send(f'total **{counter}** messages in this channel.')
# How to return the messageList to my jupyter notebook cell and I start playing with the messageList?
How to return the messageList
?
Solution
There isn't a good way to do this. discord.py is designed to be started once and run until your program terminates since all of the internal objects are destroyed upon closure of the bot, which makes starting the bot back up again nearly impossible. And it is not possible to "pause" discord.py and run your code then resumes discord.py afterwards, because Discord API communicates via web sockets, which relies on a constant stream of heartbeats and acks.
A possible workaround would be to:
- Use a single event loop through out the code.
- Use
loop.run_until_complete()
to start the bot's internal loop. - Create a new
Client
every time you need to run the bot. - Create an
on_ready
event handle that fetches the information. - Downside is that you won't be able to interact with the
Message
objects (ie. delete, edit, etc), they will be view only.
Example:
import asyncio
import discord
TOKEN = "YOURBOTTOKEN"
loop = asyncio.get_event_loop()
def get_message_list(token, channel_id):
client = discord.Client(loop=loop)
message_list = []
@client.event
async def on_ready():
nonlocal message_list
channel = client.get_channel(channel_id)
if not channel: # incase the channel cache isn't fully populated yet
channel = await client.fetch_channel(channel_id)
async for message in channel.history(limit=100):
message_list.append(message)
await client.close()
async def runner():
try:
await client.start(token)
finally:
if not client.is_closed():
# Incase the bot was terminated abruptly (ie. KeyboardInterrupt)
await client.close()
loop.run_until_complete(runner())
return message_list
message_list = get_message_list(TOKEN, channel_id=747699344911712345)
print("Message list for channel #1:", message_list)
# ... do stuff with message_list
message_list = get_message_list(TOKEN, channel_id=747699344911754321)
print("Message list for channel #2:", message_list)
# ... do more stuff with message_list
# Finally closes the event loop when everything's done
loop.close()
Instead of doing this, I'd recommend you to find another solution to the task you're trying to accomplish.
Answered By - Taku
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.