diff --git a/xmpp_tg/xmpp.py b/xmpp_tg/xmpp.py index 09157ca..93ee841 100644 --- a/xmpp_tg/xmpp.py +++ b/xmpp_tg/xmpp.py @@ -99,6 +99,285 @@ class MessageHandler(): reply = trim(method.__doc__) return reply +class GateMessageHandler(MessageHandler): + def configure(hndl, self): + """Get config/set config options""" + config_exclude = ['jid', 'tg_phone'] + + option = hndl.arguments[0] if len(hndl.arguments) >= 1 else None + value = hndl.arguments[1] if len(hndl.arguments) == 2 else None + + if value is not None and option not in config_exclude: + self.db_connection.execute("update accounts set {} = ? where jid = ?".format(option), (value,hndl.jid,) ) + self.accounts[hndl.jid] = self.db_connection.execute("SELECT * FROM accounts where jid = ?", (hndl.jid,) ).fetchone() + + message = "=== Your current configuration ===\n\n" + for param, value in self.accounts[hndl.jid].items(): + message = message + "<%s>: %s" % (param, value) + "\n" + message = message + "\nTo modify some option, please, send !configure param value" + return message + + def login(hndl, self): #1 arg + """Initiates Telegram session + + Usage: !login """ + hndl._min_args(1) + + phone_no = hndl.arguments[0] + + hndl._update("Please wait...") + self.spawn_tg_client(hndl.jid, phone_no) + + if self.tg_connections[hndl.jid].is_user_authorized(): + self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected') + return "You are already authenticated in Telegram" + else: + # remove old sessions for this JID # + self.db_connection.execute("DELETE from accounts where jid = ?", (hndl.jid, ) ) + self.tg_connections[hndl.jid].send_code_request(phone_no) + self._update('Gate is connected. Telegram should send SMS message to you.') + return 'Please enter one-time code via !code 12345.' + + def code(hndl, self): + hndl._min_args(1) + + code = hndl.arguments[0] + jid = hndl.jid + + if not self.tg_connections[jid].is_user_authorized(): + try: + hndl._update('Trying authenticate...') + self.tg_connections[jid].sign_in(self.tg_phones[jid], code) + except SessionPasswordNeededError: + self.gate_reply_message(iq, 'Two-factor authentication detected.') + self.gate_reply_message(iq, 'Please enter your password via !password abc123.') + return + + if self.tg_connections[jid].is_user_authorized(): + self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected') + self.gate_reply_message(iq, 'Authentication successful. Initiating Telegram...') + self.db_connection.execute("INSERT INTO accounts(jid, tg_phone) VALUES(?, ?)", (jid, self.tg_phones[jid],)) + self.accounts[jid] = self.db_connection.execute("SELECT * FROM accounts where jid = ?", (jid,) ).fetchone() + self.init_tg(jid) + + else: + return 'Authentication failed.' + else: + return 'You are already authenticated. Please use !logout before new login.' + + def password(hndl, self): + hndl._min_args(1) + + password = hndl.arguments[1] + jid = self.jid + + if not self.tg_connections[jid].is_user_authorized(): + self.gate_reply_message(iq, 'Checking password...') + self.tg_connections[jid].sign_in(password=password) + + if self.tg_connections[jid].is_user_authorized(): + self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected') + self.gate_reply_message(iq, 'Authentication successful. Initiating Telegram...') + self.db_connection.execute("INSERT INTO accounts(jid, tg_phone) VALUES(?, ?)", (jid, self.tg_phones[jid],)) + self.accounts[jid] = self.db_connection.execute("SELECT * FROM accounts where jid = ?", (jid,) ).fetchone() + self.init_tg(jid) + + else: + self.gate_reply_message(iq, 'Authentication failed.') + else: + self.gate_reply_message(iq, 'You are already authenticated. Please use !logout before new login.') + + def list_sessions(hndl, self): + if not self.tg_connections[hndl.jid].is_user_authorized(): + return "Error" + + sessions = self.tg_connections[hndl.jid].invoke(GetAuthorizationsRequest()) + return str(sessions) + + def reload_dialogs(hndl, self): + if not self.tg_connections[hndl.jid].is_user_authorized(): + return "Error" + + self.tg_process_dialogs(hndl.jid) + return "Dialogs reloadad" + + def logout(hndl, self): + """Deletes current Telegram session at Gateway""" + self.tg_connections[hndl.jid].log_out() + self.db_connection.execute("DELETE FROM accounts WHERE jid = ?", (hndl.jid,)) + return 'Your Telegram session was deleted' + + def add(hndl, self): #1 arg + """Add contact by nickname or t.me link""" + hndl._min_args(1) + + argument = hndl.arguments[0] + jid = hndl.jid + + result = self.tg_connections[jid].get_entity(argument) + if type(result) == User: + tg_peer = InputPeerUser( result.id, result.access_hash ) + result = self.tg_connections[jid].invoke( SendMessageRequest(tg_peer, 'Hello! I just want to add you in my contact list.', generate_random_long() ) ) + elif type(result) == Channel: + tg_peer = InputPeerChannel( result.id, result.access_hash ) + self.tg_connections[jid].invoke(JoinChannelRequest( InputPeerChannel(result.id, result.access_hash) ) ) + else: + self.gate_reply_message(iq, 'Sorry, nothing found.') + return + + self.tg_process_dialogs(jid) + + def join(hndl, self): #1 arg + """Join conference via invite link""" + hndl._min_args(1) + + argument = hndl.arguments[0] + jid = hndl.jid + + link = argument.split('/') # https://t.me/joinchat/HrCmckx_SkMbSGFLhXCvSg + self.tg_connections[jid].invoke(ImportChatInviteRequest(link[4])) + time.sleep(1) + self.tg_process_dialogs(jid) + + def group(hndl, self): #2 args + """Creat a Group""" + hndl._min_args(2) + # group name? # + groupname = parsed[1] + + # group users? # + groupuser = self.tg_connections[jid].get_entity(parsed[2]) + + # we re ready to make group + self.tg_connections[jid].invoke(CreateChatRequest([groupuser], groupname)) + self.tg_process_dialogs(jid) + + + def supergroup(hndl, self): #1 arg + """Create a channel""" + hndl._min_args(1) + + groupname = hndl.arguments[0] + self.tg_connections[hndl.jid].invoke(CreateChannelRequest(groupname, groupname, megagroup = True)) + self.tg_process_dialogs(hndl.jid) + + channel = supergroup + + def username(hndl, self): #1 arg + """Change your Telegram nickname""" + hndl._min_args(1) + + username = hndl.arguments[0] + + self.tg_connections[hndl.jid].invoke(UpdateUsernameRequest(username)) + + def name(hndl, self): #1 or 2 args + """Change your Telegram display name""" + hndl._min_args(1) + + firstname = hndl.arguments[0] + lastname = hndl.arguments[1] if len(hndl.arguments) > 1 else None + + self.tg_connections[hndl.jid].invoke(UpdateProfileRequest(first_name = firstname, last_name = lastname)) + + def about(hndl, self): #>0 args + """Change your Telegram 'about' text""" + hndl._min_args(1) + + about = hndl.msg['body'][7:] + self.tg_connections[hndl.jid].invoke(UpdateProfileRequest(about = about)) + + def import_contact(hndl, self): #2 args + """Add contact by phone number""" + hndl._min_args(2) + + phone = hndl.arguments[0] + firstname = hndl.arguments[1] + lastname = hndl.arguments[2] if len(hndl.arguments) > 2 else None + + contact = InputPhoneContact(client_id=generate_random_long(), phone=phone, first_name=firstname, last_name=lastname) + self.tg_connections[hndl.jid].invoke(ImportContactsRequest([contact])) + self.tg_process_dialogs(jid) + + def roster(hndl, self): + """Send Telegram contact list back, with JIDs""" + response = "Telegram chats:\n" + for jid,tid in self.contact_list[hndl.jid].items(): + response += "{}: {}\n".format(tid, jid) + return response + + def oldhelp(hndl, self): + """Old !help message""" + return ('=== Available gateway commands ===:\n\n' + '!help - Displays this text\n' + '!login +123456789 - Initiates Telegram session\n' + '!code 12345 - Entering one-time code during auth\n' + '!password abc123 - Entering password during two-factor auth\n' + '!configure - Configure transport settings\n' + #'!list_sessions - List all created sessions at Telegram servers\n' + #'!delete_session 123 - Delete session\n' + '!logout - Deletes current Telegram session at gate\n' + '!reload_dialogs - Reloads dialogs list from Telegram\n\n' + + '!add - Find and add Telegram contact. Any formats accepted (nickname or t.me link)\n\n' + + '!join - Join Telegram conference via invite link \n\n' + + '!import phone firstname lastname - Add Telegram contact with phone number \n\n' + + '!group GroupName @InviteContact - Create a normal group\n' + '!supergroup SupergroupName - Create a supergroup\n' + '!channel ChannelName - Create a channel\n\n' + + '!name first last - Change your name in Telegram\n' + '!about text - Change about text in Telegram\n' + '!username - Changes your @username in Telegram\n\n' + + '!roster - Lists yout TG roster\n') + +class ChatCommandHandler(MessageHandler): + + def __init__(self, msg): + super(ChatCommandHandler, self).__init__(msg) + if self._command.startswith("s/"): + self._handler = self._replace + self.tg_id = int(msg['to'].node[1:]) + + def block(hndl, self): + nickname = display_tg_name(self.tg_dialogs[hndl.jid]['users'][hndl.tg_id]) + self.tg_connections[hndl.jid].invoke(BlockRequest( InputPeerUser(hndl.tg_id, self.tg_dialogs[jid]['users'][hndl.tg_id].access_hash) ) ) + self.gate_reply_message(iq, 'User %s blacklisted!' % nickname) + + def unblock(hndl, self): + nickname = display_tg_name(self.tg_dialogs[hndl.jid]['users'][hndl.tg_id]) + self.tg_connections[hndl.jid].invoke(UnblockRequest( InputPeerUser(hndl.tg_id, self.tg_dialogs[jid]['users'][hndl.tg_id].access_hash) ) ) + self.gate_reply_message(iq, 'User %s unblacklisted!' % nickname) + + def remove(hndl, self): + peer = InputPeerUser(hndl.tg_id, self.tg_dialogs[hndl.jid]['users'][hndl.tg_id].access_hash) + c_jid = get_contact_jid(self.tg_dialogs[hndl.jid]['users'][hndl.tg_id], self.boundjid.bare) + + self.tg_connections[hndl.jid].invoke( DeleteContactRequest(peer) ) + self.tg_connections[hndl.jid].invoke( DeleteHistoryRequest( peer, max_id = 0, just_clear = None ) ) + + self.send_presence(pto = hndl.jid, pfrom = c_jid, ptype = 'unavailable') + self.send_presence(pto = hndl.jid, pfrom = c_jid, ptype = 'unsubscribed') + self.send_presence(pto = hndl.jid, pfrom = c_jid, ptype = 'unsubscribe') + + def _replace(hndl, self): + peer = InputPeerUser(hdnl.tg_id, self.tg_dialogs[hndl.jid]['users'][hndl.tg_id].access_hash) + + msg_id, edited = self.edit_message(hdnl.jid, hdnl.tg_id, hndl.msg['body']) + if not edited: return + + # and send it + if edited != '' and edited != ' ': + self.tg_dialogs[hndl.jid]['messages'][hndl.tg_id]["body"] = edited + self.tg_connections[hndl.jid].invoke( EditMessageRequest(peer, msg_id, message = edited) ) + else: + del(self.tg_dialogs[hndl.jid]['messages'][hndl.tg_id]) + self.tg_connections[hndl.jid].invoke( DeleteMessagesRequest([msg_id], revoke = True) ) + class XMPPTelegram(ComponentXMPP): """ Main XMPPTelegram class. @@ -334,244 +613,6 @@ class XMPPTelegram(ComponentXMPP): self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='unavailable') sys.exit(0) - - class GateMessageHandler(MessageHandler): - def configure(hndl, self): - """Get config/set config options""" - config_exclude = ['jid', 'tg_phone'] - - option = hndl.arguments[0] if len(hndl.arguments) >= 1 else None - value = hndl.arguments[1] if len(hndl.arguments) == 2 else None - - if value is not None and option not in config_exclude: - self.db_connection.execute("update accounts set {} = ? where jid = ?".format(option), (value,hndl.jid,) ) - self.accounts[hndl.jid] = self.db_connection.execute("SELECT * FROM accounts where jid = ?", (hndl.jid,) ).fetchone() - - message = "=== Your current configuration ===\n\n" - for param, value in self.accounts[hndl.jid].items(): - message = message + "<%s>: %s" % (param, value) + "\n" - message = message + "\nTo modify some option, please, send !configure param value" - return message - - def login(hndl, self): #1 arg - """Initiates Telegram session - - Usage: !login """ - hndl._min_args(1) - - phone_no = hndl.arguments[0] - - hndl._update("Please wait...") - self.spawn_tg_client(hndl.jid, phone_no) - - if self.tg_connections[hndl.jid].is_user_authorized(): - self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected') - return "You are already authenticated in Telegram" - else: - # remove old sessions for this JID # - self.db_connection.execute("DELETE from accounts where jid = ?", (hndl.jid, ) ) - self.tg_connections[hndl.jid].send_code_request(phone_no) - self._update('Gate is connected. Telegram should send SMS message to you.') - return 'Please enter one-time code via !code 12345.' - - def code(hndl, self): - hndl._min_args(1) - - code = hndl.arguments[0] - jid = hndl.jid - - if not self.tg_connections[jid].is_user_authorized(): - try: - hndl._update('Trying authenticate...') - self.tg_connections[jid].sign_in(self.tg_phones[jid], code) - except SessionPasswordNeededError: - self.gate_reply_message(iq, 'Two-factor authentication detected.') - self.gate_reply_message(iq, 'Please enter your password via !password abc123.') - return - - if self.tg_connections[jid].is_user_authorized(): - self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected') - self.gate_reply_message(iq, 'Authentication successful. Initiating Telegram...') - self.db_connection.execute("INSERT INTO accounts(jid, tg_phone) VALUES(?, ?)", (jid, self.tg_phones[jid],)) - self.accounts[jid] = self.db_connection.execute("SELECT * FROM accounts where jid = ?", (jid,) ).fetchone() - self.init_tg(jid) - - else: - return 'Authentication failed.' - else: - return 'You are already authenticated. Please use !logout before new login.' - - def password(hndl, self): - hndl._min_args(1) - - password = hndl.arguments[1] - jid = self.jid - - if not self.tg_connections[jid].is_user_authorized(): - self.gate_reply_message(iq, 'Checking password...') - self.tg_connections[jid].sign_in(password=password) - - if self.tg_connections[jid].is_user_authorized(): - self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected') - self.gate_reply_message(iq, 'Authentication successful. Initiating Telegram...') - self.db_connection.execute("INSERT INTO accounts(jid, tg_phone) VALUES(?, ?)", (jid, self.tg_phones[jid],)) - self.accounts[jid] = self.db_connection.execute("SELECT * FROM accounts where jid = ?", (jid,) ).fetchone() - self.init_tg(jid) - - else: - self.gate_reply_message(iq, 'Authentication failed.') - else: - self.gate_reply_message(iq, 'You are already authenticated. Please use !logout before new login.') - - def list_sessions(hndl, self): - if not self.tg_connections[hndl.jid].is_user_authorized(): - return "Error" - - sessions = self.tg_connections[hndl.jid].invoke(GetAuthorizationsRequest()) - return str(sessions) - - def reload_dialogs(hndl, self): - if not self.tg_connections[hndl.jid].is_user_authorized(): - return "Error" - - self.tg_process_dialogs(hndl.jid) - return "Dialogs reloadad" - - def logout(hndl, self): - """Deletes current Telegram session at Gateway""" - self.tg_connections[hndl.jid].log_out() - self.db_connection.execute("DELETE FROM accounts WHERE jid = ?", (hndl.jid,)) - return 'Your Telegram session was deleted' - - def add(hndl, self): #1 arg - """Add contact by nickname or t.me link""" - hndl._min_args(1) - - argument = hndl.arguments[0] - jid = hndl.jid - - result = self.tg_connections[jid].get_entity(argument) - if type(result) == User: - tg_peer = InputPeerUser( result.id, result.access_hash ) - result = self.tg_connections[jid].invoke( SendMessageRequest(tg_peer, 'Hello! I just want to add you in my contact list.', generate_random_long() ) ) - elif type(result) == Channel: - tg_peer = InputPeerChannel( result.id, result.access_hash ) - self.tg_connections[jid].invoke(JoinChannelRequest( InputPeerChannel(result.id, result.access_hash) ) ) - else: - self.gate_reply_message(iq, 'Sorry, nothing found.') - return - - self.tg_process_dialogs(jid) - - def join(hndl, self): #1 arg - """Join conference via invite link""" - hndl._min_args(1) - - argument = hndl.arguments[0] - jid = hndl.jid - - link = argument.split('/') # https://t.me/joinchat/HrCmckx_SkMbSGFLhXCvSg - self.tg_connections[jid].invoke(ImportChatInviteRequest(link[4])) - time.sleep(1) - self.tg_process_dialogs(jid) - - def group(hndl, self): #2 args - """Creat a Group""" - hndl._min_args(2) - # group name? # - groupname = parsed[1] - - # group users? # - groupuser = self.tg_connections[jid].get_entity(parsed[2]) - - # we re ready to make group - self.tg_connections[jid].invoke(CreateChatRequest([groupuser], groupname)) - self.tg_process_dialogs(jid) - - - def supergroup(hndl, self): #1 arg - """Create a channel""" - hndl._min_args(1) - - groupname = hndl.arguments[0] - self.tg_connections[hndl.jid].invoke(CreateChannelRequest(groupname, groupname, megagroup = True)) - self.tg_process_dialogs(hndl.jid) - - channel = supergroup - - def username(hndl, self): #1 arg - """Change your Telegram nickname""" - hndl._min_args(1) - - username = hndl.arguments[0] - - self.tg_connections[hndl.jid].invoke(UpdateUsernameRequest(username)) - - def name(hndl, self): #1 or 2 args - """Change your Telegram display name""" - hndl._min_args(1) - - firstname = hndl.arguments[0] - lastname = hndl.arguments[1] if len(hndl.arguments) > 1 else None - - self.tg_connections[hndl.jid].invoke(UpdateProfileRequest(first_name = firstname, last_name = lastname)) - - def about(hndl, self): #>0 args - """Change your Telegram 'about' text""" - hndl._min_args(1) - - about = hndl.msg['body'][7:] - self.tg_connections[hndl.jid].invoke(UpdateProfileRequest(about = about)) - - def import_contact(hndl, self): #2 args - """Add contact by phone number""" - hndl._min_args(2) - - phone = hndl.arguments[0] - firstname = hndl.arguments[1] - lastname = hndl.arguments[2] if len(hndl.arguments) > 2 else None - - contact = InputPhoneContact(client_id=generate_random_long(), phone=phone, first_name=firstname, last_name=lastname) - self.tg_connections[hndl.jid].invoke(ImportContactsRequest([contact])) - self.tg_process_dialogs(jid) - - def roster(hndl, self): - """Send Telegram contact list back, with JIDs""" - response = "Telegram chats:\n" - for jid,tid in self.contact_list[hndl.jid].items(): - response += "{}: {}\n".format(tid, jid) - return response - - def oldhelp(hndl, self): - """Old !help message""" - return ('=== Available gateway commands ===:\n\n' - '!help - Displays this text\n' - '!login +123456789 - Initiates Telegram session\n' - '!code 12345 - Entering one-time code during auth\n' - '!password abc123 - Entering password during two-factor auth\n' - '!configure - Configure transport settings\n' - #'!list_sessions - List all created sessions at Telegram servers\n' - #'!delete_session 123 - Delete session\n' - '!logout - Deletes current Telegram session at gate\n' - '!reload_dialogs - Reloads dialogs list from Telegram\n\n' - - '!add - Find and add Telegram contact. Any formats accepted (nickname or t.me link)\n\n' - - '!join - Join Telegram conference via invite link \n\n' - - '!import phone firstname lastname - Add Telegram contact with phone number \n\n' - - '!group GroupName @InviteContact - Create a normal group\n' - '!supergroup SupergroupName - Create a supergroup\n' - '!channel ChannelName - Create a channel\n\n' - - '!name first last - Change your name in Telegram\n' - '!about text - Change about text in Telegram\n' - '!username - Changes your @username in Telegram\n\n' - - '!roster - Lists yout TG roster\n') - - def process_command(self, msg): """ Commands to gateway, users or chats (starts with !) @@ -583,7 +624,7 @@ class XMPPTelegram(ComponentXMPP): if is_command: command = msg["body"].split(" ")[0][1:] - handler = self.GateMessageHandler(msg)._handler + handler = GateMessageHandler(msg)._handler try: reply = str(handler(self)) except Exception as e: @@ -594,7 +635,7 @@ class XMPPTelegram(ComponentXMPP): else: if isinstance(e, NotAuthorizedError): reply = str(e) - elif isinstance(e, self.MessageHandler.WrongNumberOfArgsError): + elif isinstance(e, MessageHandler.WrongNumberOfArgsError): reply = str(e) else: logging.error("Exception in command from {}, command was '{}'".format(msg["from"],msg["body"])) @@ -604,57 +645,13 @@ class XMPPTelegram(ComponentXMPP): self.gate_reply_message(msg, reply) #msg.reply(reply).send() - class ChatCommandHandler(MessageHandler): - - def __init__(self, msg): - super(ChatCommandHandler, self).__init__(msg) - if self._command.startswith("s/"): - self._handler = self._replace - self.tg_id = int(msg['to'].node[1:]) - - def block(hndl, self): - nickname = display_tg_name(self.tg_dialogs[hndl.jid]['users'][hndl.tg_id]) - self.tg_connections[hndl.jid].invoke(BlockRequest( InputPeerUser(hndl.tg_id, self.tg_dialogs[jid]['users'][hndl.tg_id].access_hash) ) ) - self.gate_reply_message(iq, 'User %s blacklisted!' % nickname) - - def unblock(hndl, self): - nickname = display_tg_name(self.tg_dialogs[hndl.jid]['users'][hndl.tg_id]) - self.tg_connections[hndl.jid].invoke(UnblockRequest( InputPeerUser(hndl.tg_id, self.tg_dialogs[jid]['users'][hndl.tg_id].access_hash) ) ) - self.gate_reply_message(iq, 'User %s unblacklisted!' % nickname) - - def remove(hndl, self): - peer = InputPeerUser(hndl.tg_id, self.tg_dialogs[hndl.jid]['users'][hndl.tg_id].access_hash) - c_jid = get_contact_jid(self.tg_dialogs[hndl.jid]['users'][hndl.tg_id], self.boundjid.bare) - - self.tg_connections[hndl.jid].invoke( DeleteContactRequest(peer) ) - self.tg_connections[hndl.jid].invoke( DeleteHistoryRequest( peer, max_id = 0, just_clear = None ) ) - - self.send_presence(pto = hndl.jid, pfrom = c_jid, ptype = 'unavailable') - self.send_presence(pto = hndl.jid, pfrom = c_jid, ptype = 'unsubscribed') - self.send_presence(pto = hndl.jid, pfrom = c_jid, ptype = 'unsubscribe') - - def _replace(hndl, self): - peer = InputPeerUser(hdnl.tg_id, self.tg_dialogs[hndl.jid]['users'][hndl.tg_id].access_hash) - - msg_id, edited = self.edit_message(hdnl.jid, hdnl.tg_id, hndl.msg['body']) - if not edited: return - - # and send it - if edited != '' and edited != ' ': - self.tg_dialogs[hndl.jid]['messages'][hndl.tg_id]["body"] = edited - self.tg_connections[hndl.jid].invoke( EditMessageRequest(peer, msg_id, message = edited) ) - else: - del(self.tg_dialogs[hndl.jid]['messages'][hndl.tg_id]) - self.tg_connections[hndl.jid].invoke( DeleteMessagesRequest([msg_id], revoke = True) ) - - def process_chat_user_command(self, msg): logging.info("received command "+str(msg["body"])+" from "+str(msg["from"])+" for "+str(msg["to"])) is_command = msg["body"].startswith("!") and msg["body"][1] != "_" if is_command: command = msg["body"].split(" ")[0][1:] - handler = self.ChatCommandHandler(msg)._handler + handler = ChatCommandHandler(msg)._handler try: reply = str(handler(self)) except Exception as e: @@ -665,7 +662,7 @@ class XMPPTelegram(ComponentXMPP): else: if isinstance(e, NotAuthorizedError): reply = str(e) - elif isinstance(e, self.MessageHandler.WrongNumberOfArgsError): + elif isinstance(e, MessageHandler.WrongNumberOfArgsError): reply = str(e) else: logging.error("Exception in command from {}, command was '{}'".format(msg["from"],msg["body"])) @@ -682,9 +679,7 @@ class XMPPTelegram(ComponentXMPP): '!s/find/replace - Edit last message. Use empty `find` to edit whole message and empty `replace` to delete it.\n' '!block - Blacklists current user\n' '!unblock - Unblacklists current user\n' - '!remove - Removes history and contact from your contact list\n' - ) - + '!remove - Removes history and contact from your contact list\n' ) def process_chat_group_command(self, iq): parsed = iq['body'].split(' ')