tomer8007 / kik-bot-api-unofficial

Python API for writing unoffical Kik bots that act like humans
MIT License
126 stars 76 forks source link

how to stop user from inputing invalid jid for request_info_of_users #181

Closed aspwil closed 3 years ago

aspwil commented 3 years ago

if you run

client.request_info_of_users(input("enter public jid:"))

if an invalid jid is entered it raises a KikApiException("No jid in user xml {}".format(xml_data)) exception and the program haults

I want to let the user type a jid as input and tell them the info of that jid

is there a way to precheck if the jid is a valid public jid? or a way to catch this error so I can tell the user without the program halting due to the error?

tomer8007 commented 3 years ago

I guess you check if the string you got looks like someuser_abc@talk.kik.com, or just do a try and except.

aspwil commented 3 years ago

I tried doing

        try:
            client.request_info_of_users(jid)
        except:
            return None

but that failed to catch the error it spits out the error

Exception in thread Thread-77:
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.496.0_x64__qbz5n2kfra8p0\lib\threading.py", line 954, in _bootstrap_inner
    self.run()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.496.0_x64__qbz5n2kfra8p0\lib\threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\client.py", line 513, in _on_new_data_received
    self._handle_received_iq_element(xml_element)
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\client.py", line 555, in _handle_received_iq_element
    self._handle_response(xml_namespace, iq_element)
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\client.py", line 572, in _handle_response
    xmlns_handlers.PeersInfoResponseHandler(self.callback, self).handle(iq_element)
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\xmlns_handlers.py", line 173, in handle
    peers_info = PeersInfoResponse(data)
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\datatypes\xmpp\roster.py", line 92, in __init__
    self.users = [User(item) for item in items]
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\datatypes\xmpp\roster.py", line 92, in <listcomp>
    self.users = [User(item) for item in items]
  File "C:\Users\aspwil\PycharmProjects\kik-bot-api-unofficial\kik_unofficial\datatypes\peers.py", line 25, in __init__
    raise KikApiException("No jid in user xml {}".format(xml_data))
kik_unofficial.datatypes.exceptions.KikApiException: No jid in user xml <item username=" a"/>

I think the error is an inaccessible spot, in order to catch it I think I would have to alter the base API itself. which I don't know how to do that. nor do I think it's a good idea to alter the base API cause then I have to deal with each update.

tomer8007 commented 3 years ago

Oh yeah, actually it's not getting caught because it's thrown in a different thread.

It's probably best to either call an on_error generic callback method (instead of throwing the exception), or return a None object. If you only want a workaround you can just check for JID validity before calling request_info_of_users, though.

What do you think?

bluemods commented 3 years ago
import re

valid_jid_pattern = re.compile("^[a-z_0-9\\.]{2,54}$")

def is_valid_jid(jid: str):
    try:
        index = jid.index('@')
        local_part = jid[0:index]
        domain = jid[index + 1:]
    except ValueError:
        return False

    if domain == 'talk.kik.com' or domain == 'groups.kik.com':
        if valid_jid_pattern.fullmatch(local_part):
            return True
    return False

Should work. Always validate your user inputs.

Edit: forgot about checking the domain part of the jid.