tolgatasci / whatsapp-api-appium

Whatsapp api for android, sending, receiving and managing messages
3 stars 1 forks source link

How to send files, pictures and emoticons #3

Open huangpd opened 2 years ago

huangpd commented 2 years ago

Now it seems that only text messages can be sent

tolgatasci commented 2 years ago

it makes sense to treat images and similar messages as sequential processing. When distributing in bulk, the message was id cloning and distributing. I will be working on this soon.

I'll try to find another method including.

self.driver.execute_script('mobile: shell', {
                        'command': 'su root am start -a android.intent.action.VIEW -d "https://wa.me/'+self.mobile_number.replace("+", "")+'?text=" com.whatsapp',
                        'args': [],
                        'includeStderr': True,
                        'timeout': 5000
})
            message_body_xpath = '//android.widget.EditText[contains(@resource-id,"entry") and contains(@text,"Type a message")]'
            wait = WebDriverWait(self.driver, 10)
            message_body_element = wait.until(EC.element_to_be_clickable((By.XPATH,message_body_xpath)))
            message_body_element.click()
            sleep(0.5)
            message_body_element.send_keys(self.message_body)
            send_element_xpath = '//android.widget.ImageButton[contains(@resource-id,"send") and contains(@content-desc,"Send")]'
            wait = WebDriverWait(self.driver, 10)
            send_element = wait.until(EC.element_to_be_clickable((By.XPATH,send_element_xpath)))
            send_element.click()
            database_update_set(database.messages,{'_id' : self.message_id },{"status":1})
            self.driver.back()
            self.driver.back()
            self.driver.back()
huangpd commented 2 years ago

this is send media mesaages func

    def _build_am_start(self, data: dict, app_distinct: bool = True, app_name: str = None) -> str:
        """
        "adb am start" command builder
        :param data: Command dict
        :type data: dict
        :return: Command string
        :rtype: str
        """
        commands = []
        for key in data.keys():

            if isinstance(data[key], list):
                for item in data[key]:
                    value = item["value"]
                    extra = item.get("extra", None)

                    if callable(value):
                        value = value()

                    commands.append(f"-{key} {value} {extra}")

            elif isinstance(data[key], dict):
                extra = data[key].get("extra", None)
                value = data[key]["value"]

                if callable(value):
                    value = value()

                commands.append(f"-{key} {value} {extra}")
            else:
                value = data[key]

                if callable(value):
                    value = value()

                commands.append(f"-{key} {value}")

        return f"am start {' '.join(commands)} {'-p ' + 'com.whatsapp' if not app_name else '-p ' + app_name if app_distinct else ''}"

    def build_send_media(self, jid: str, file_name: str):
        print("Building command for send media")

        return self._build_am_start({
            IntentFlags.COMPONENT: "com.whatsapp/com.whatsapp.ContactPicker",
            IntentFlags.ACTION: "android.intent.action.SEND",
            IntentFlags.MIME_TYPE: "text/plain",
            IntentFlags.EXTRA_STRING_VALUE: [
                {
                    "value": "jid",
                    "extra": f"'{jid}'"
                }
            ],
            IntentFlags.EXTRA_URI_VALUE: [
                {
                    "value": "android.intent.extra.STREAM",
                    "extra": f"'file:///data/local/{file_name}'"
                }
            ]

        }, app_distinct=True)

    def build_apo_send(self,phone):
        print("Command for opening contact via browser successfully built!")
        return self._build_am_start(
            {
                ActivityFlags.WAIT_COMPLETE_LAUNCH: "",
                IntentFlags.ACTION: "android.intent.action.VIEW",
                IntentFlags.DATA_URI: f"https://api.whatsapp.com/send?phone={phone}"
            },
            app_distinct=True
        )

    def send_media_message(self,phone,file_path):
        self.driver = u2.connect(self.config.dev)
        self.driver.app_start("com.whatsapp", ".ContactPicker")
        file_name = os.path.basename(file_path)
        print(file_path)
        self.driver.push(file_path, f"/data/local/{file_name}")
        # self.driver.push(file_path, f"/sdcard/DCIM/{file_name}")
        print('file_name:%s'%file_name)
        logging.info(phone)
        logging.info(file_path)

        self.add_phone(phone)
        # phone = self.helper.convert_phone(phone=phone)
        # jid = phone['remote_jid']
        jid = f"{phone}@s.whatsapp.net".replace('+', '')
        command_phone = self.build_apo_send(phone)
        print(phone)
        self.driver.shell(command_phone)

        command = self.build_send_media(jid, file_name)
        print('command: {}'.format(command))
        command_output = self.driver.shell(command)
        print(command_output)
        time.sleep(2)
        # try:
        #     self.driver(resourceId='android:id/button1',).click()
        # except:
        #     pass
        self.driver(resourceId='com.whatsapp:id/send').click()
        self.driver(resourceId='com.whatsapp:id/send').click()
tolgatasci commented 2 years ago

yes. It can then copy it to the media's messages table and do it for other numbers. I can try soon