diff --git a/sopel/bot.py b/sopel/bot.py index 8f7632b5b6..87480da995 100644 --- a/sopel/bot.py +++ b/sopel/bot.py @@ -484,6 +484,9 @@ def dispatch(self, pretrigger): if (hasattr(func, 'intents') and trigger.tags.get('intent') not in func.intents): continue + if (not (hasattr(func, 'echo') and func.echo is True) and + trigger.nick.lower() == self.nick.lower()): + continue if func.thread: targs = (func, wrapper, trigger) t = threading.Thread(target=self.call, args=targs) diff --git a/sopel/irc.py b/sopel/irc.py index 0782d8e4c8..20a89d03cd 100644 --- a/sopel/irc.py +++ b/sopel/irc.py @@ -148,6 +148,16 @@ def write(self, args, text=None): self.send(temp.encode('utf-8')) finally: self.writing_lock.release() + # Simulate echo-message + if 'echo-message' not in self.enabled_capabilities: + # Since we have no way of knowing the hostmask the IRC server uses + # for us, we'll just use something reasonable + host = 'localhost' + if self.config.core.bind_host: + host = self.config.core.bind_host + pretrigger = PreTrigger(self.nick, ':{0}!{1}@{2} {3}' + .format(self.nick, self.user, host, temp)) + self.dispatch(pretrigger) def run(self, host, port=6667): try: diff --git a/sopel/module.py b/sopel/module.py index 5aa4101ea9..2bb7491434 100644 --- a/sopel/module.py +++ b/sopel/module.py @@ -115,6 +115,23 @@ def add_attribute(function): return add_attribute +def echo(value): + """Decorate a function to specify if it should receive echo messages. + + This decorator can be used to listen in on the messages that Sopel is + sending and react accordingly. + + Args: + value: Either True or False. If True the function will receive echo + messages, and if False only messages received from other users. + + """ + def add_attribute(function): + function.echo = value + return function + return add_attribute + + def commands(*command_list): """Decorate a function to set one or more commands to trigger it. diff --git a/test/test_module.py b/test/test_module.py index 5214d75251..e55a2d5677 100644 --- a/test/test_module.py +++ b/test/test_module.py @@ -82,6 +82,13 @@ def mock(bot, trigger, match): assert mock.thread is True +def test_echo(): + @module.echo(False) + def mock(bot, trigger, match): + return True + assert mock.echo is False + + def test_commands(): @module.commands('sopel') def mock(bot, trigger, match):