echo_bot: implement basic commands
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
ba028d98c8
commit
59e82ec9ee
1 changed files with 56 additions and 2 deletions
|
@ -11,6 +11,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
@ -27,6 +28,10 @@ from omemo.exceptions import MissingBundleException
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Used by the EchoBot
|
||||||
|
LEVEL_DEBUG = 0
|
||||||
|
LEVEL_ERROR = 1
|
||||||
|
|
||||||
|
|
||||||
class EchoBot(ClientXMPP):
|
class EchoBot(ClientXMPP):
|
||||||
|
|
||||||
|
@ -39,10 +44,15 @@ class EchoBot(ClientXMPP):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
eme_ns = 'eu.siacs.conversations.axolotl'
|
eme_ns = 'eu.siacs.conversations.axolotl'
|
||||||
|
cmd_prefix = '!'
|
||||||
|
debug_level: int = LEVEL_DEBUG # or LEVEL_ERROR
|
||||||
|
|
||||||
def __init__(self, jid, password):
|
def __init__(self, jid, password):
|
||||||
ClientXMPP.__init__(self, jid, password)
|
ClientXMPP.__init__(self, jid, password)
|
||||||
|
|
||||||
|
self.prefix_re: re.Pattern = re.compile('^%s' % self.cmd_prefix)
|
||||||
|
self.cmd_re: re.Pattern = re.compile('^%s(?P<command>\w+)(?:\s+(?P<args>.*))?' % self.cmd_prefix)
|
||||||
|
|
||||||
self.add_event_handler("session_start", self.start)
|
self.add_event_handler("session_start", self.start)
|
||||||
self.add_event_handler("message", self.message_handler)
|
self.add_event_handler("message", self.message_handler)
|
||||||
|
|
||||||
|
@ -62,6 +72,46 @@ class EchoBot(ClientXMPP):
|
||||||
self.send_presence()
|
self.send_presence()
|
||||||
self.get_roster()
|
self.get_roster()
|
||||||
|
|
||||||
|
def is_command(self, body: str) -> bool:
|
||||||
|
return self.prefix_re.match(body) is not None
|
||||||
|
|
||||||
|
async def handle_command(self, mto: JID, mtype: str, body: str) -> None:
|
||||||
|
match = self.cmd_re.match(body)
|
||||||
|
if match is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
groups = match.groupdict()
|
||||||
|
cmd = groups['command']
|
||||||
|
# args = groups['args']
|
||||||
|
|
||||||
|
if cmd == 'help':
|
||||||
|
await self.cmd_help(mto, mtype)
|
||||||
|
elif cmd == 'verbose':
|
||||||
|
await self.cmd_verbose(mto, mtype)
|
||||||
|
elif cmd == 'error':
|
||||||
|
await self.cmd_error(mto, mtype)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def cmd_help(self, mto: JID, mtype: str) -> None:
|
||||||
|
body = (
|
||||||
|
'I\'m the slixmpp-omemo echo bot! '
|
||||||
|
'The following commands are available:\n'
|
||||||
|
'{prefix}verbose Send message or reply with log messages\n'
|
||||||
|
'{prefix}error Send message or reply only on error\n'
|
||||||
|
).format(prefix=self.cmd_prefix)
|
||||||
|
return await self.encrypted_reply(mto, mtype, body)
|
||||||
|
|
||||||
|
async def cmd_verbose(self, mto: JID, mtype: str) -> None:
|
||||||
|
self.debug_level = LEVEL_DEBUG
|
||||||
|
body = '''Debug level set to 'verbose'.'''
|
||||||
|
return await self.encrypted_reply(mto, mtype, body)
|
||||||
|
|
||||||
|
async def cmd_error(self, mto: JID, mtype: str) -> None:
|
||||||
|
self.debug_level = LEVEL_ERROR
|
||||||
|
body = '''Debug level set to 'error'.'''
|
||||||
|
return await self.encrypted_reply(mto, mtype, body)
|
||||||
|
|
||||||
def message_handler(self, msg: Message) -> None:
|
def message_handler(self, msg: Message) -> None:
|
||||||
asyncio.ensure_future(self.message(msg))
|
asyncio.ensure_future(self.message(msg))
|
||||||
|
|
||||||
|
@ -84,14 +134,18 @@ class EchoBot(ClientXMPP):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not self['xep_0384'].is_encrypted(msg):
|
if not self['xep_0384'].is_encrypted(msg):
|
||||||
await self.plain_reply(mto, mtype, 'Echo unencrypted message:%(body)s' % msg)
|
if self.debug_level == LEVEL_DEBUG:
|
||||||
|
await self.plain_reply(mto, mtype, 'Echo unencrypted message:%(body)s' % msg)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
encrypted = msg['omemo_encrypted']
|
encrypted = msg['omemo_encrypted']
|
||||||
body = self['xep_0384'].decrypt_message(encrypted, mfrom, allow_untrusted)
|
body = self['xep_0384'].decrypt_message(encrypted, mfrom, allow_untrusted)
|
||||||
decoded = body.decode('utf8')
|
decoded = body.decode('utf8')
|
||||||
await self.encrypted_reply(mto, mtype, 'Echo: %s' % decoded)
|
if self.is_command(decoded):
|
||||||
|
await self.handle_command(mto, mtype, decoded)
|
||||||
|
elif self.debug_level == LEVEL_DEBUG:
|
||||||
|
await self.encrypted_reply(mto, mtype, 'Echo: %s' % decoded)
|
||||||
return None
|
return None
|
||||||
except (MissingOwnKey,):
|
except (MissingOwnKey,):
|
||||||
# The message is missing our own key, it was not encrypted for
|
# The message is missing our own key, it was not encrypted for
|
||||||
|
|
Loading…
Reference in a new issue