diff --git a/simplematrixbotlib/match.py b/simplematrixbotlib/match.py
index b5886b6..d2e8dfd 100644
--- a/simplematrixbotlib/match.py
+++ b/simplematrixbotlib/match.py
@@ -82,17 +82,27 @@ def __init__(self, room, event, bot, prefix="") -> None:
"""
super().__init__(room, event, bot)
self._prefix = prefix
- bot_user = self.room.users[self.room.own_user_id]
- # in case another user uses the same display name, we need to regard the disambiguation if present
- self._disambiguated_name = bot_user.disambiguated_name
- # still we allow to mention without disambiguation if typing manually for now
- self._display_name = bot_user.display_name
- # element generates a "pill" from formatted (HTML) links to matrix.to/#/@matrix:id
- # this isn't really specced but still the status quo
- self._pill = f''
- self._body_without_prefix = None
-
- def command(self, command=None):
+
+ """Forms of identification"""
+ self._own_user_id = f"@{self._bot.creds.username}:{self._bot.creds.homeserver.replace("https://","").replace("http://","")}"
+ self._own_nio_user = self.room.users[own_user_id]
+ self._own_disambiguated_name = own_nio_user.disambiguated_name
+ self._own_display_name = own_nio_user.display_name
+ self._own_pill = f""
+
+ self.mention() # Set self._mention_id_length
+ self._body_without_prefix = self.event.body[len(self._prefix):]
+ self._body_without_mention = self.event.body[len(self._mention_id_length):]
+
+ if self.mention():
+ body = self._body_without_mention
+ elif self.prefix():
+ body = self._body_without_prefix
+ else:
+ body = self.event.body
+ self._split_body = body.split()
+
+ def command(self, command="") -> Union[bool, str]:
"""
Parameters
----------
@@ -108,22 +118,16 @@ def command(self, command=None):
Returns the string after the prefix and before the first space if no arg is passed to this method.
"""
- # we cache this part
- if self._body_without_prefix is None:
- if not self.mention():
- if self._prefix == self.event.body[0:len(self._prefix)]:
- self._body_without_prefix = self.event.body[len(self._prefix):]
- else:
- self._body_without_prefix = self.event.body
-
- split_body = self._body_without_prefix.split()
- if len(split_body) < 1:
- split_body = [""]
+ if not (self._body_without_prefix and self._body_without_mention):
+ if command:
+ return False
+ else:
+ return ""
- if command is not None:
- return split_body[0] == command
+ if command:
+ return self._split_body[0] == command
else:
- return split_body[0]
+ return self._split_body[0]
def prefix(self):
"""
@@ -134,7 +138,7 @@ def prefix(self):
Returns True if the message begins with the prefix, and False otherwise. If there is no prefix specified during the creation of this MessageMatch object, then return True.
"""
- return self.event.body.startswith(self._prefix)
+ return self.event.body[self._mention_id_length:].startswith(self._prefix)
def mention(self):
"""
@@ -145,25 +149,11 @@ def mention(self):
Returns True if the message begins with the bot's username, MXID, or pill targeting the MXID, and False otherwise.
"""
- body = self.event.body
- for id in [self._disambiguated_name, self._display_name, self.room.own_user_id]:
- if body.startswith(id):
- body_ = body[len(id):]
- # the match needs to end here, otherwise someone else is mentioned
- # this isn't perfect but probably the best effort
- if body_[0] in [' ', ':']:
- self._body_without_prefix = body_[1:].strip()
- return True
-
- # pills on the other hand are a clearer case thanks to HTML tags which include delimiters
- body = self.event.formatted_body
- if body is not None and body.startswith(self._pill):
- # remove the first half of the pill
- body = body[len(self._pill):]
- # find pill end + trailing delimiter + maybe whitespace
- self._body_without_prefix = body[body.index('')+5:].strip()
- return True
-
+ for id in [self._own_disambiguated_name, self._own_display_name, self._own_user_id]:
+ if self.event.body.startswith(id):
+ self._mention_id_length = len(id)
+ return True
+
return False
def args(self):
@@ -172,12 +162,10 @@ def args(self):
Returns
-------
list
- Returns a list of strings that are the "words" of the message, except for the first "word", which would be the command.
+ Returns a list of strings that are the "words" of the message, except for the first "word", which would be the prefix/mention + command.
"""
- if self._body_without_prefix is None:
- self.command() # calculate _body_without_prefix
- return self._body_without_prefix.split()[1:]
+ return self._split_body[1:]
def contains(self, string):
"""