WhatsApp automatic messaging (development)

Good day to all!

This post inspired me to write this article.

Unfortunately, in this article there was no way to send files to Whatsapp and I decided to fix it.

So, it is necessary:

  • Python (I have 3.10.10)

  • libraries for it (full list of them below)

  • registered phone number in Whatsapp

  • windows computer

  • … well, desire

Now the promised requrements.txt

async-generator==1.10
attrs==23.1.0
certifi==2023.5.7
cffi==1.15.1
charset-normalizer==3.1.0
colorama==0.4.6
exceptiongroup==1.1.1
h11==0.14.0
idna==3.4
outcome==1.2.0
packaging==23.1
PyAutoIt==0.6.5
pycparser==2.21
PySocks==1.7.1
python-dotenv==1.0.0
requests==2.30.0
selenium==4.9.1
sniffio==1.3.0
sortedcontainers==2.4.0
tqdm==4.65.0
trio==0.22.0
trio-websocket==0.10.2
urllib3==2.0.2
webdriver-manager==3.8.6
wsproto==1.2.0

Installing the above packages, with the exception of PyAutoItproduced through

pip install -r requrements.txt 

and won’t cause problems.

Installing PyAutoit is necessary because Selenium, at the time of writing, cannot send text and commands outside the browser. And you need to tell Windows Explorer what kind of file is to be sent. By the way, AutoIt is a great scripting language for those who want to automate work with applications that do not have an API. He can easily find, enter text and press buttons in windows applications.

Therefore, we install it separately.

  1. Downloading the distribution from here

  2. We open the archive if it was not dragged through git clone

  3. Go to the pyautoit-master folder

  4. And run python setup.py install… but in README.md this package is written more;).

Well, now we are ready to run the file whatsapp.py. Here he is

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from time import sleep
import argparse
import autoit

options = webdriver.ChromeOptions()
# если у вас другой браузер, например FireFox, мы просто пишем options = webdriver.FirefoxOptions() .
# if you have the Mozilla Fifefox just write                   options = webdriver.FirefoxOptions()
options.add_argument('--allow-profiles-outside-user-dir')
options.add_argument('--enable-profile-shortcut-manager')
# УКАЖИТЕ ПУТЬ ГДЕ ЛЕЖИТ ВАШ python ФАЙЛ. Советую создать отдельную папку для него
# Specify the path to where your python file is located. I suggest you create a separate folder for it
options.add_argument(r'user-data-dir=x:\\yyyyyy\\zzzzzz\\') 
options.add_argument('--profile-directory=Profile 1')
options.add_argument('--profiling-flush=n')
options.add_argument('--enable-aggressive-domstorage-flushing')

# эти опции нужны чтобы подавить любые сообщения об ошибках  SSL, сертификатов и т.п. Но работает только последняя :(
# these options need to disabled any messages about bad ssl, certification & etc 
options.add_argument('--ignore-certificate-errors-spki-list')
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
options.add_argument('log-level=3')
# INFO = 0, 
# WARNING = 1, 
# LOG_ERROR = 2, 
# LOG_FATAL = 3.
# default is 0.

# Константы для Selenium
# Constants for Selenium
xpath = "//button[@data-testid='compose-btn-send']"
xpathAttach = "//div[@data-testid='conversation-clip']"
# xpathFile = "//button[@data-testid='attach-document']"
#xpathSendButton = "//div[@data-testid='send']" # data-testid = "send"
cssIdOfDocument = "[aria-label="Документ"]"
cssIdOfSendButton = "[aria-label="Отправить"]"

# Константы для AutoIt
# Constant for Autoit
idExplorerOpen = "[CLASS:#32770]"
idInputLine = "[CLASS:Edit; INSTANCE:1]"
idOpenButton = "Button1"

# номера телефонов для отправки
# numbers of  phones to send
numbers = ["+7xxxxxxxxxx", "+7xxxxxxxxxx", "+7xxxxxxxxxx"]

# текст по умолчанию
# default text
text = "Ничего нет"

# Мы запускаем браузер
# We are starting a browser
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# ждём его загрузки
# it takes some time to load it
wait = WebDriverWait(driver, 30)


def main(args):
    for number in numbers:
# создаём url страницы с телефонныи номером и текстом для отправки
# create a url page with a phone number and text to send
        url = f"https://web.whatsapp.com/send?phone={number}&text={args.text}"
# идём туда
# go to there
        driver.get(url)
# ждём загрузки страницы Whatsapp
# we are waiting for Whatsapp page to load
        wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))

        if not (args.file is None) :
# нужно отправить файл
# ищем кнопку Attach
# need to send file
# now we look for the Attach Button and click on it
           driver.find_element(By.XPATH, xpathAttach).click()
# затем ищем кнопку "Документ" и щелкаем на ней. Используется атрибут CCS, потому что у него нет ID
# then  we look for the Document Button and click on it. Used CCS attribute because it doesn't have any ID
           driver.find_element(By.CSS_SELECTOR, cssIdOfDocument).click()

# подождать, когда активируется окно проводника Windows
# wait when the Windows's explorer window to activate
           autoit.win_wait_active(idExplorerOpen, 5)
# затем отправляем путь к файлу в строку ввода
# then we are sending the path of the file to input line
           autoit.control_send(idExplorerOpen, idInputLine, args.file)
# и нажимаем кнопку "Открыть" 
# and are clicking the Open Button 
           autoit.control_click(idExplorerOpen, idOpenButton)
# немного ждём загрузки файла
# it takes some time to load a file
           sleep(5)
# ищем кнопку "Отправить" и нажимаем на нее. Используется атрибут CCS, потому что у него нет ID
# we look for the Send Button and click on it. Used CCS attribute because it doesn't have any ID
           driver.find_element(By.CSS_SELECTOR, cssIdOfSendButton).click()
           
        else:
# теперь ищем кнопку "Отправить" и нажимаем на нее
# now we look for the Send Button and click on it
           driver.find_element(By.XPATH, xpath).click()
# требуется некоторое время для отправки файла или сообщения
# it takes some time to send a file or a message
        sleep(5)
# закрыть все
# close all
    driver.quit()


if __name__ == '__main__':
# мы разбираем параметры командной строки
# we are parsing command line parameters
     parser = argparse.ArgumentParser(description='Send information by Whatsapp')
     parser.add_argument('--text', help='Text for send', required=False, default = text)
     parser.add_argument('--file', help='File for send', required=False)
     args = parser.parse_args()
# начать отправку
# start sending
     main(args)

  

I tried to document in the comments almost all the important points of this application, and in two languages: in Russian and in English, if someone suddenly does not speak Russian;). Therefore, I will not separately paint its parts, but if something is not clear, then write in the comments. I’ll try to answer.

The app starts like this

python whatsapp.py --text "Я посылаю тебе ... или тебя ;)" 

if you want to send text

or so

python --text "Это очень важный файл" --file "x:\yyyyy\zzzzz\fileToSend.ext"

if you need to send a file with an explanation

The first launch of the application will require downloading drivers, be sure to agree with this. You will also need to register a whatsapp client on this computer.

Then it usually starts up and fixes everything without question.

I agree with the author of the post that inspired me and I will quote him:

that this article was not created to teach you how to spam, flood and ruin people’s lives in other ways. This material is for informational purposes only. Think before you do something.

Good luck to all!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *