Command Cooldown for a Python Twitch Bot

倾然丶 夕夏残阳落幕 提交于 2019-12-25 09:18:49

问题


I'm making a Twitch Bot using Pthon. I want to create a cooldown on the commands so you can only call the command once every (x) seconds. Eg:

Rustie: test
Bot: Testing command
*Imediately after*
Rustie: test
*5 seconds later*
Rustie: test
Bot: Testing command

I have tried this code but it doesn't work (Also I want to get rid of time.sleep as during that time I can't use other commands):

used = []
if "test" in message:
    if "test" in used:
        time.sleep(5)
        del(used[:])
    else:
        sendMessage(s, "Testing command")
        used.append("test")

    break

回答1:


My advice would be to restructure your code to use modular MessageHandler classes that can each handle a particular type of message (i.e. have a single responsibility), with the bot's overall behaviour being determined by the type and order of these message handlers within a chain of responsibility:

Among several other benefits, this makes it easy to implement cooldowns between command invocations (in the implementation below, you can customise different duration cooldowns for different types of message).

from abc import ABC, abstractmethod

from datetime import datetime, timedelta
from time import sleep


class MessageHandler(ABC):
    def __init__(self, command_cooldown):
        self._command_cooldown = command_cooldown
        self._last_command_usage = datetime.min

    def try_handle_message(self, message):
        if self._can_handle_message(message) and not self.__on_cooldown:
            self._last_command_usage = datetime.now()
            return self._handle_message(message)
        else:
            return None

    @property
    def __on_cooldown(self):
        return datetime.now() - self._last_command_usage <= self._command_cooldown

    @abstractmethod
    def _can_handle_message(self, s):
        pass

    @abstractmethod
    def _handle_message(self, s):
        pass


class TestMessageHandler(MessageHandler):
    def __init__(self):
        super().__init__(timedelta(seconds=5))

    def _can_handle_message(self, s):
        return 'test' in s

    def _handle_message(self, s):
        return 'Testing command'


class Bot(object):
    def __init__(self):
        self._message_handlers = [TestMessageHandler()]

    def receive_message(self, message):
        print('Received:', message)
        for message_handler in self._message_handlers:
            response = message_handler.try_handle_message(message)
            if response:
                self.send_response(response)

    def send_response(self, response):
        print('Responding:', response)


if __name__ == '__main__':
    bot = Bot()
    bot.receive_message('test')

    for i in range(6):
        bot.receive_message('test')
        print('Sleep 1 second...')
        sleep(1)

Output

Received: test
Responding: Testing command
Received: test
Sleep 1 second...
Received: test
Sleep 1 second...
Received: test
Sleep 1 second...
Received: test
Sleep 1 second...
Received: test
Sleep 1 second...
Received: test
Responding: Testing command
Sleep 1 second...



回答2:


You need to keep track of the time passed since the last invocation of each command. You can do it with the time module.

import time

min_call_freq = 5
used = {}

def call_command(command):
    print('Calling command `%s`.' % command)
    # do whatever

def cooldown(command):
    print('You have used command `%s` in the last %u seconds.' % (command, min_call_freq))

def process_command(command):
    if (
        command not in used or
        time.time() - used[command] > min_call_freq
    ):
        used[command] = time.time()
        call_command(command)
    else:
        cooldown(command)


来源:https://stackoverflow.com/questions/41902252/command-cooldown-for-a-python-twitch-bot

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!