SOBotics / Botpy

A python framework for creating chatbots on the StackExchange network.
Other
5 stars 1 forks source link

Is it possible to use a BackgroundTask to run a command with output? #28

Closed AWegnerGitHub closed 5 years ago

AWegnerGitHub commented 5 years ago

I'd like to be able to execute one of my commands that requires elevated privileges, via a background task and post that to chat.

Documentation is lacking on the backgroundtasks, and the examples I see in the code base all calling non-command functions without output.

Is this type of use case possible?

double-fault commented 5 years ago

Uh, sorry, I didn't quite get what you're trying to do. Are you specifically trying to invoke commands (which were designed with the case of chat invocation in mind), or do you want to post messages to a chat room through a BackgroundTask?

If you're trying to do the latter, you can just define your custom function (which posts the message), which also takes the Bot class as an argument. Since the Bot class includes all the room objects, you should be able to easily post messages. Then, you can add your function as a BackgroundTask, and for the arguments, you could use a lambda.

Invoking commands should also be possible, but will probably be quite messy.

AWegnerGitHub commented 5 years ago

Yup, still confused.

Don't I need to define BackgroundTasks at bot initialization time? I don't have a bot class yet, right?

background_tasks = []
background_tasks.append(bp.BackgroundTask(lambda: auto_run(bot), interval=60))
bot = bp.Bot(bot_name, commands, room_ids, background_tasks, host, email, password)

If I have auto_run defined like this:

def auto_run(bot):
    bot.post("Auto-ran. YAY!")

I get this error:

AttributeError: 'Bot' object has no attribute 'post'

Can I add a task once the bot is defined?

double-fault commented 5 years ago

Hmm, yeah. Apologies.

To add a background task after the bot has been initialized, you could do something like

bot = bp.Bot(bot_name, commands, room_ids, [], host, email, password)
bot._background_task_manager.add_background_task(bp.BackgroundTask(lambda: auto_run(bot), interval=60))
bot.start()

If you'd like to add a background task after the bot has been started as well, you need to restart the BackgroundTaskManager, as can be seen in another bot of mine.

There should be a function in the Bot class to do all of this stuff, and to wrap it up neatly; I'll create a ticket for that.

For your second issue, the bot contains multiple room objects, in which the post method is present. If you'd like to post a global message, to all rooms the bot is present in, use

def auto_run(bot):
    bot.post_global_message("Auto-ran. YAY!")

which is defined here.

Else, should it be that you need to access a single room, you'll have to access a specific index in the rooms list, and use the post function defined in CE. The order of the room objects in the list will be the same as the order of the room_ids passed during Bot initialisation. That is, if you pass a list with the ids [1, 68, 2], the bot._rooms list will have the rooms in the same order.

Sorry 'bout the poor documentation; I just haven't found sufficient time to finish it.

double-fault commented 5 years ago

The wrapper function, add_background_task, has been added. You can call it anytime after bot initialisation, irrespective of whether the bot has been started or not. The example has also been edited. Running the example will get you something like this.

Do note that you need to install version 0.7.9 from PyPi. Let me know if you face any more issues.