Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: Passing local vars between functions,  (Read 7445 times)

0 Members and 1 Guest are viewing this topic.

zask

    Topic Starter


    Intermediate

    • Experience: Experienced
    • OS: Other
    Passing local vars between functions,
    « on: April 28, 2021, 09:41:26 PM »
    Sorry I am kinda new to this. I'm using a python API for Kik Messenger app and I've been struggling to wrap my head around this problem.
    I'm trying to ask the user for a command, that command is a prefix command which calls my bot and is followed by secondary command which does a specific task, in this case the task is asking for an image. Kik is built using XMPP if anyone isn't already aware. "It basically lets you do the same things as the offical Kik app by pretending to be a real smartphone client; It communicates with Kik's servers at talk1110an.kik.com:5223 over a modified version of the XMPP protocol." -tomer8007.

    This is the beginning part of the script.
    Code: [Select]
    # Default modules.
    import logging
    import kik_unofficial.datatypes.xmpp.chatting as chatting
    from kik_unofficial.client import KikClient
    from kik_unofficial.callbacks import KikClientCallback
    from kik_unofficial.datatypes.xmpp.errors import SignUpError, LoginError
    from kik_unofficial.datatypes.xmpp.roster import FetchRosterResponse, PeersInfoResponse
    from kik_unofficial.datatypes.xmpp.sign_up import RegisterResponse, UsernameUniquenessResponse
    from kik_unofficial.datatypes.xmpp.login import LoginResponse, ConnectionFailedResponse

    # For Image sending.
    from pathlib import Path
    import urllib.request
    img = {}

    username = "username"  # Put KIK Username here
    password = "password"  # Put Kik Password here

    def main():
        # create the bot
        bot = EchoBot()

    class EchoBot(KikClientCallback):
        def __init__(self):
            self.client = KikClient(self, username, password)

        def on_authenticated(self):
            print("Now I'm Authenticated, let's request roster")
            self.client.request_roster()

        def on_login_ended(self, response: LoginResponse):
            print("Full name: {} {}".format(response.first_name, response.last_name))

    Blah blah blah,
    now here is the issue.

    This function is called when user sends an image, I want to avoid calling the function unless the secondary command (I.e "mybot img") is called first.
    Code: [Select]
        def on_image_received(self, response: chatting.IncomingImageMessage):
            print("[+] Image message was received from {}".format(response.from_jid))
            global img
            if img[response.group_jid]:
                img_name, img_path = on_group_message_received()
                """Grabs the image's url from "https://platform.kik.com/content/files/etc" and sends it to a location on my computer. """
                urllib.request.urlretrieve(response.image_url, img_path)
                # Sets img[chat_message.group_jid] back to false so there is no future issues.
                img[chat_message.group_jid] = False

    in the above code I cannot pass "img_path" from "on_group_message_received" to "on_image_received".

    Here is the rest of the code.
    Code: [Select]
        # Function for group messages.
        def on_group_message_received(self, chat_message: chatting.IncomingGroupChatMessage):
            print("[+] '{}' from group ID {} says: {}".format(chat_message.from_jid, chat_message.group_jid,
                                                              chat_message.body))

            # If you want to make commands without a prefix start on this line
            if chat_message.body.lower() == "mybot":
                self.client.send_chat_message(chat_message.group_jid, "You called?")

            if chat_message.body.lower() == "ping":
                self.client.send_chat_message(chat_message.group_jid, "Pong")

            # Prefix command for your bot.
            prefix = "mybot"
            if chat_message.body.lower().startswith(prefix):
                # Grabs users input after the prefix.
                body = chat_message.body.lower().split(maxsplit=1)[1]

                # Now "hello" will only be called if I say it like this "mybot hey"
                if body == "hey":
                    self.client.send_chat_message(chat_message.group_jid, "hello")

                # Now this is my secondary command.
                prefix_for_img = "mybot img"
                if chat_message.body.lower().startswith(prefix_for_img):
                    global img
                    # This is prevents on_image_received from being used unless chat_message.group_jid is called first
                    img[chat_message.group_jid] = True
                    # Takes user input from the third position (I.e. mybot test) which is used as a name for the image.
                    img_name = chat_message.body.lower().split(maxsplit=4)[2]
                    # Assuming that \kik-bot-api-unofficial\ (The API) folder is on the desktop, searches inside for \images\ and searches for the image from there.
                    img_path = r"C:\Users\username\Desktop\kik-bot-api-unofficial\Images\""[:-1] + str(img_name) + ".jpg"
                    print(img_path) # for me this prints: C:\Users\username\Desktop\kik-bot-api-unofficial\Images\test.jpg
                    self.client.send_chat_message(chat_message.group_jid, "Waiting for image.")
                    # Now the bot waits for on_image_received to be called, which is called when an image is recieved.

        # Error handling, from here the rest doesn't really matter.

        def on_connection_failed(self, response: ConnectionFailedResponse):
            print("[-] Connection failed: " + response.message)

        def on_login_error(self, login_error: LoginError):
            if login_error.is_captcha():
                login_error.solve_captcha_wizard(self.client)

        def on_register_error(self, response: SignUpError):
            print("[-] Register error: {}".format(response.message))


    if __name__ == '__main__':
        main()

    Now that I have mostly everything figured out, I now have issues getting the variables "img_name" and "img_path" to pass from "on_group_message_received" to "on_image_received" as stated above. I have tried looking everywhere for a solution and either I do not fully comprehend it or its not even specific to my situation. You might be wondering why I want to do this, the answer is simple. I'm trying to store users images as a trigger by saving the image's name as a call back. Similar to how a text based trigger works except in this case I can save the image on my computer and call it back by name via app/group chat.

    To make things easier I placed the full script here.
    Code: [Select]
    # Default modules.
    import logging
    import kik_unofficial.datatypes.xmpp.chatting as chatting
    from kik_unofficial.client import KikClient
    from kik_unofficial.callbacks import KikClientCallback
    from kik_unofficial.datatypes.xmpp.errors import SignUpError, LoginError
    from kik_unofficial.datatypes.xmpp.roster import FetchRosterResponse, PeersInfoResponse
    from kik_unofficial.datatypes.xmpp.sign_up import RegisterResponse, UsernameUniquenessResponse
    from kik_unofficial.datatypes.xmpp.login import LoginResponse, ConnectionFailedResponse

    # For Image sending.
    from pathlib import Path
    import urllib.request
    img = {}

    username = "username"  # Put KIK Username here
    password = "password"  # Put Kik Password here

    def main():
        # create the bot
        bot = EchoBot()

    class EchoBot(KikClientCallback):
        def __init__(self):
            self.client = KikClient(self, username, password)

        def on_authenticated(self):
            print("Now I'm Authenticated, let's request roster")
            self.client.request_roster()

        def on_login_ended(self, response: LoginResponse):
            print("Full name: {} {}".format(response.first_name, response.last_name))


        def on_image_received(self, response: chatting.IncomingImageMessage):
            print("[+] Image message was received from {}".format(response.from_jid))
            global img
            if img[response.group_jid]:
                img_name, img_path = on_group_message_received()
                """Grabs the image's url from "https://platform.kik.com/content/files/etc" and sends it to a location on my computer. """
                urllib.request.urlretrieve(response.image_url, img_path)
                # Sets img[chat_message.group_jid] back to false so there is no future issues.
                img[chat_message.group_jid] = False

        # Function for group messages.
        def on_group_message_received(self, chat_message: chatting.IncomingGroupChatMessage):
            print("[+] '{}' from group ID {} says: {}".format(chat_message.from_jid, chat_message.group_jid,
                                                              chat_message.body))

            # If you want to make commands without a prefix start on this line
            if chat_message.body.lower() == "mybot":
                self.client.send_chat_message(chat_message.group_jid, "You called?")

            if chat_message.body.lower() == "ping":
                self.client.send_chat_message(chat_message.group_jid, "Pong")

            # Prefix command for your bot.
            prefix = "mybot"
            if chat_message.body.lower().startswith(prefix):
                # Grabs users input after the prefix.
                body = chat_message.body.lower().split(maxsplit=1)[1]

                # Now "hello" will only be called if I say it like this "mybot hey"
                if body == "hey":
                    self.client.send_chat_message(chat_message.group_jid, "hello")

                # Now this is my secondary command.
                prefix_for_img = "mybot img"
                if chat_message.body.lower().startswith(prefix_for_img):
                    global img
                    # This is prevents on_image_received from being used unless chat_message.group_jid is called first
                    img[chat_message.group_jid] = True
                    # Takes user input from the third position (I.e. mybot test) which is used as a name for the image.
                    img_name = chat_message.body.lower().split(maxsplit=4)[2]
                    # Assuming that \kik-bot-api-unofficial\ (The API) folder is on the desktop, searches inside for \images\ and searches for the image from there.
                    img_path = r"C:\Users\username\Desktop\kik-bot-api-unofficial\Images\""[:-1] + str(img_name) + ".jpg"
                    print(img_path) # for me this prints: C:\Users\username\Desktop\kik-bot-api-unofficial\Images\test.jpg
                    self.client.send_chat_message(chat_message.group_jid, "Waiting for image.")
                    # Now the bot waits for on_image_received to be called, which is called when an image is recieved.

        # Error handling, from here the rest doesn't really matter.

        def on_connection_failed(self, response: ConnectionFailedResponse):
            print("[-] Connection failed: " + response.message)

        def on_login_error(self, login_error: LoginError):
            if login_error.is_captcha():
                login_error.solve_captcha_wizard(self.client)

        def on_register_error(self, response: SignUpError):
            print("[-] Register error: {}".format(response.message))


    if __name__ == '__main__':
        main()

    zask

      Topic Starter


      Intermediate

      • Experience: Experienced
      • OS: Other
      Re: Passing local vars between functions,
      « Reply #1 on: April 29, 2021, 10:31:59 AM »
      No need to help I figured out my issue.

      Code: [Select]
          def on_image_received(self, response: chatting.IncomingImageMessage):
              print("[+] Image message was received from {}".format(response.from_jid))
              global img
              if img[response.group_jid][0]:
                  urllib.request.urlretrieve(response.image_url, img[response.group_jid][1])
                  img[response.group_jid] = [False, ""]

      Code: [Select]
                  prefix_for_img = "lettucebot img"
                  if chat_message.body.lower().startswith(prefix_for_img):
                      img_name = chat_message.body.lower().split(maxsplit=4)[2]
                      global img
                      img[chat_message.group_jid] = [True, r"C:\Users\User\Desktop\kik-bot-api-unofficial\Images\""[:-1] + str(img_name) + ".jpg"]
                      self.client.send_chat_message(chat_message.group_jid, "Waiting for image.")

        :)