Rapptz / discord.py

An API wrapper for Discord written in Python.
http://discordpy.rtfd.org/en/latest
MIT License
14.84k stars 3.76k forks source link

How to use the api without coroutines #809

Closed jokoast closed 7 years ago

jokoast commented 7 years ago

Hi buddies,

I want to make a "rest" api with Discord-api but with the coroutines i can't fill a class array because of the scopes.

How can i do ? I can ask on SOF but dunno if someone is good enough with Discorp api.

Thank's in advance and sorry for my english.

Jokoast

EDIT : Or how to create my own events that i can trigger ?

Rapptz commented 7 years ago

I'll be honest here, I have no idea what you're asking.

Maybe try to reword your question so it makes more sense?

jokoast commented 7 years ago

No problems, my english is not as great as i'd like.

I'd want to be able to do that :

c = Client(token)
channels = c.getAllChannels()
# a loop to sort my channels of my discord by type 
c.sendMessage(myChannel, "Hi Discord")

But i've to use the onReady event to trigger the sort of my channels so :

def onReady():
    self.channels = c.getAllChannels() # Won't work cause onReady is in a fork (async)

Or maybe it is possible to create my own events but i'm not comfy with asyncio and coroutines ... I'd want to, for example, plug DiscordApi with TwitchApi.

for item in followed_channels:
    if twitch_api.getChannel(item).is_online():
        discord_api.send_message(ANNONCE_CHAN, "Channel {} online".format(item.name))

but if i was able to have my own events something like:

def onChannelOnline(item):
    self.annonces.append({
         'message' : bot.send_message(ANNONCE_CHAN, "Channel {} online".format(item.name))
         'item' : item
    })

def onChannelDisconnection(item):
   # something to find the annonce for the item
   bot.delete_message(theMessageFound)
NotSoSuper commented 7 years ago

To use this wrapper you must use python coroutines and the asyncio syntax. If you have a blocking module such as Twitch API, try learning about threads and running it in a different one, you can even use bot.loop.run_in_executor.

There is another python wrapper for the Discord API that follows a synchronous style but uses gevent, I wouldn't recommend it for beginners: disco

jokoast commented 7 years ago

Yeah i tested it to use commands and events but i want an external trigger ... I think about threading the main bot to be able to get the bot instance and use it out of the main thread and make some calls on it with datas from other sources.

I saw this code on an issue relative to mine :

import asyncio, discord, time, threading, readline

loop = asyncio.new_event_loop()
bot = discord.Client()
token = 'mytoken-thx-henry'
bot_token = True
message_queue = asyncio.Queue()
channel_id = '250346442500079617'

def bot_thread(loop, bot, bot_token, message_queue, channel_id):
    asyncio.set_event_loop(loop)

    @bot.event
    async def on_ready():
        while True:
            data = await message_queue.get()
            event = data[0]
            message = data[1]
            channel_id = data[2]

            try:
                await bot.send_message(bot.get_channel(channel_id), message)
            except:
                pass

            event.set()

    bot.run(token, bot = bot_token)

thread = threading.Thread(target = bot_thread, args = (loop, bot, bot_token, message_queue, channel_id), daemon = True)
thread.start()

def send(channel_id, message):
    event = threading.Event()

    message_queue.put_nowait([event, message, channel_id])

    event.wait()

print('Bot logging in...')

try:
    kek = False
    while not kek:
        time.sleep(0.1)

        if bot._is_ready.is_set(): # wait until the ready event
            while True:
                try:
                    message = input('Message to send > ')
                except:
                    break
                else:
                    send(channel_id, message)

            kek = True
except KeyboardInterrupt:
    pass

But i don't understand how he plugs the queue event and cie ...

henry232323 commented 7 years ago

Oh shit, you leaked your token!

In some way or another, you have just given your token away. This is not a good thing, as it gives anyone access to the user for that token! You can reset your token in a couple of ways: For bot accounts: Go to your app page https://discordapp.com/developers/applications/me and generate a new token there.

For user accounts: Either change your password, or enable/disable 2fa. Either one will change your user token.

jokoast commented 7 years ago

Thank you, i made the change. If you have any solution for me, i'm open. This wrapper is really complicate and changes from the habbits i have about making apis ... I'm in trouble :D.