0

I want to make a command to send a message to a text channel or a user,and the message should be input at console,but input() seems to "block" the program. Although I had tried threading to figure out this problem,the problem still remain unsolve.How can I do to fix the problem?

easy code like this:

import discord
import typing
from discord.ext import commands

class BasicCmd(commands.Cog):

    def __init__(self, client):
        self.client = client

    @commands.command()
    async def test(self, ctx, *, receiver: typing.Union[discord.User, discord.TextChannel]):
        '''
        I want to get input from console
        but input() block the program.
        '''
        content = input('Enter something: ')
        await receiver.send(content)

def setup(client):
    client.add_cog(BasicCmd(client))

If I do it with threading:

import discord
import typing
import threading
from discord.ext import commands

class BasicCmd(commands.Cog):

    def __init__(self, client):
        self.client = client

    @commands.command()
    async def test(self, ctx, *, receiver: typing.Union[discord.User, discord.TextChannel]):
        '''
        I want to do this command with threading to figure out  
        this problem,but the problem still remain unsolve.
        '''
        content = threading.Thread(target=input,args=('Enter something: ',)).start()
        await receiver.send(content)
        '''It will  raise an HTTPException(Cannot send an enpty message,and the bot also "block" by "input")'''

def setup(client):
    client.add_cog(BasicCmd(client))

I have modified my program,but the input still block my program. code(just test):

import discord
import typing
import queue
import threading
from discord.ext import commands

class BasicCmd(commands.Cog):

    def __init__(self, client):
        self.client = client

    @commands.command()
    async def test(self, ctx):
        inputQueue = queue.Queue()

        inputThread = threading.Thread(target=_read_kbd_input, args=(inputQueue,), daemon=True)
        # It still remain "blocking"
        inputThread.start()

        while (True):
            if (inputQueue.qsize() > 0):
                input_str = inputQueue.get()
                print("input_str = {}".format(input_str))
                return

def _read_kbd_input(inputQueue):
    print('Ready for keyboard input:')
    a=True
    while a:
        input_str = input()
        inputQueue.put(input_str)
        a=False
def setup(client):
    client.add_cog(BasicCmd(client))

7
  • I don't think this is a good idea do this using the console and you'll need to create an UI for that... But eventually this could help you: geeksforgeeks.org/simple-chat-room-using-python Commented Aug 28, 2019 at 8:55
  • duplicate with answer on Non-blocking, multi-threaded example; input wait for a newline or EOF Commented Aug 28, 2019 at 9:58
  • @bufh Thank for your help,but the problem still remain unsolve. I have edited my post. Commented Aug 28, 2019 at 12:00
  • 1
    is it good to think about key press listeners instead of using input() blindly? Commented Aug 28, 2019 at 12:06
  • @Kris That is a good idea,but if I want to input Chinese or other language.What should I do with the key press listener? Commented Aug 28, 2019 at 13:01

1 Answer 1

-1

make a new async def for input

async def noinput():
  global inputoutput, askinput
  while True:
    if askinput==True
       inputoutput=input('input: ')
       askinput==False

then, you have to run it before you run your bot at bottom

client.loop.create_task(noinput())
client.run(token)

your input asker should be like this

@client.event
async def on_message(message: discord.Message):
  global askinput, inputoutput
  if message.content.startswith("input"):
    askinput==True
    while askinput==True:
      await asyncio.sleep(1)
    output=inputoutput
    #do something with output

example code

async def noinput():
  global inputoutput, askinput
  while True:
    if askinput==True
       inputoutput=input('input: ')
       askinput==False

client=discord.Client()
async def on_message(message: discord.Message):
  global askinput, inputoutput
  if message.content.lower() == "input":
    askinput==True
    while askinput==True:
      await asyncio.sleep(1)
    message.channel.send(inputoutput)
client.loop.create_task(noinput())
client.run(token)
Sign up to request clarification or add additional context in comments.

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.