WhatsApp automation using Python

This post is an explainer on how to automate a simple task like sending a WhatsApp message to a contact and then scale it up i.e., sending similar message to multiple contacts.

We will be using Python script to automate the task and WhatsApp web as our delivery method.

Defining the task:

Send a new year’s greeting to 100s of contacts on WhatsApp, the greeting should contain an image with a meaningful message and personally addressed to the recipient.

Deconstructing the tasks into simpler defined and repeatable functions

  1. Open WhatsApp web
  2. Create Customized Image and save at a known location
  3. Select Chat in WhatsApp web
  4. Add image and send
  5. Repeat steps 2, 3 and 4 for all contacts

Let’s work on each to-do:

Open WhatsApp web:

from selenium import webdriver

driver=webdriver.Chrome(chromedriver_path)

driver.get(‘https://web.whatsapp.com/’)

We have used selenium library to open the WhatsApp web, using selenium we can open browser instance interact with different elements and thus automate simple tasks.

Create Customised Image and save at a known location:

from PIL import Image

from PIL import ImageDraw

from PIL import ImageFont

def create_custom_image (source_image_path, text, font_path, size,

                            position, text_color) -> str:

    img = Image.open(source_image_path)

    edit_img = ImageDraw.Draw(img)

    my_font = ImageFont.truetype(font_path,size)

    edit_img.text(xy=(28,60),text,font=my_font, fill=text_color)

    edited_image_name = edited_image_path

    img.save(“edited_pics/” + edited_image_name)

    return current_path + edited_image_name

We are using Python Imaging Library for processing the image. We start by opening the source image using source image path provided into img object. Next we create another object as edit_img which is then used to add text, note that the text added is an input parameter and thus can be customized for each contact. After adding text we save the image to a known location and return the path back.

Select Chat in WhatsApp web:

def select_chat (name = “Hitesh Gulati”):

    search_box = driver.find_element_by_xpath(‘//*[@id=”side”]/div[1]/div/label/div/div[2]’)

    search_box.click()

    search_box.clear()

    search_box.send_keys(name)

    sleep(1)

    chat_table = driver.find_element_by_xpath(‘//*[@id=”pane-side”]/div[1]/div/div’)

    user=chat_table.find_element_by_xpath(‘.//span[@title=”{}”]’.format(name))

    user.click()

Coming back to WhatsApp, we search for the desired contact using the search box and click contact’s box to open contact window. We found the search box using its xpath which can be extracted by inspecting the element in Chrome browser. Once we searched for the contact, we can select the find box in the search results. Note that xpaths are dynamic in nature and might have to be searched again before using the code.

Add Image and Send

def send_image(file_path):

attachment_icon = driver.find_element_by_xpath(‘//*[@id=”main”]/footer/div[1]/div/span[2]/div/div[1]/div[2]’)

    attachment_icon.click()

    sleep(.5)

    image_icon =   driver.find_element_by_xpath(‘//input[@accept=”image/*,video/mp4,video/3gpp,video/quicktime”]’)

    image_icon.send_keys(file_path)

    sleep(1)

    send_button=driver.find_element_by_xpath(‘//span[@data-icon=”send”]’)

    send_button.click()

After selecting the contacts box, we can go ahead and send the customized image. We start by clicking the attachment button and then selecting Photos and videos from there. We will have to provide the saved image path to attach the image and then click the send button. All buttons attachment, photos and send button are referred using xpath and can be extracted using inspect in chrome.

Repeat steps for all contacts:

chat_list = pd.read_csv(“sample_list.csv”)

chat_list[‘sent’] = 0

for idx, each_chat in chat_list.iterrows():

    chat_title = each_chat[‘Title’]

    chat_name = each_chat[‘Name’]

    print(chat_title,chat_name)

    image_address = create_custom_image(text=chat_name)

    sleep(1)

    select_chat(chat_title)

    send_image(file_path=image_address)

    chat_list.iloc[idx,2] = 1

I saved all contacts in a pandas dataframe and created two columns. Title field is how I will search for the contact while Name field determines how the contact will be addressed. We loop through the list, create a customized image using Name field, select the chat using Title field and finally send the image. In the end we also tag the contacts for which the message was sent successfully, this will help us identify the contacts where the message was not sent.

We can use inspect feature within Chrome to get exact location of the search box and copy the full XPath related to it.