Skip to content

Instantly share code, notes, and snippets.

@mohit-rathee
Last active July 6, 2024 09:40
Show Gist options
  • Save mohit-rathee/edd10cfabe43381bf7697db877c82a4d to your computer and use it in GitHub Desktop.
Save mohit-rathee/edd10cfabe43381bf7697db877c82a4d to your computer and use it in GitHub Desktop.
Send bulk messages to contact via selenium. NO REDIRECTING TO URLS.
import time
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Instead of redirecting to """https://web.whatsapp.com/send?phone={phone_number}"""
# It search for contacts in within a single tab.
options = webdriver.ChromeOptions()
# FOR LINUX:
options.add_argument('user-data-dir=/home/Arch/.config/google-chrome')
options.add_argument('profile-directory=Profile 1')
# FOR WINDOWS:
#options.add_argument(
# '--user-data-dir=C:/Users/<username>/AppData/Local/Google/Chrome/User Data')
#options.add_argument('--profile-directory=Profile 1')
driver = webdriver.Chrome(options=options)
url = "https://web.whatsapp.com"
driver.get(url)
# TODO prevent sending messages if phone_no is invalid.
# NOTE if phone_no is invalid then messages
# can be sent to wrong person
contacts_data = [
{
'phone_no': '+91XXXXXXXXXX',
'message': 'hello',
'document': '<path_to_document>'
},
{
'phone_no': '+91XXXXXXXXXX',
'media': '<path_to_media>'
},
{
'phone_no': '+92XXXXXXXXXX',
'message': 'hello3',
},
{
'phone_no': '+01XXXXXXXXXX',
'message': 'hello4',
'media': '<path_to_media>'
},
]
wait = WebDriverWait(driver, 10)
time.sleep(15)
for item in contacts_data:
if not item.get('phone_no'):
print('phone_no not found.')
if item.get('media') and item.get('document'):
print('Choose between media or document.')
continue
new_chat = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'div[aria-label="New chat"]'))
)
new_chat.click()
search_number = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "div[contenteditable='true']:nth-of-type(1)"))
)
search_number.send_keys(item['phone_no'])
search_number.send_keys(Keys.ENTER)
time.sleep(1)
try:
#NOTE fail_msg is the div containing msg 'Contact not found'
fail_msg = WebDriverWait(driver, 5).until(
EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'div[aria-live="polite"]'))
)
except:
fail_msg = None
if fail_msg:
back_button = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located(
(By.CSS_SELECTOR, 'div[aria-label="Back"]'))
)[0]
back_button.click()
time.sleep(1)
continue
if item.get('media') or item.get('document'):
try:
attachment_button = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, 'div[aria-label="Attach"]'))
)
attachment_button.click()
if item.get('media'):
media_input = WebDriverWait(driver, 20).until(
EC.presence_of_element_located(
(By.CSS_SELECTOR,
"input[accept='image/*,video/mp4,video/3gpp,video/quicktime']"))
)
media_input.send_keys(item.get('media'))
time.sleep(2)
elif item['document']:
document_input = WebDriverWait(driver, 20).until(
EC.presence_of_element_located(
(By.CSS_SELECTOR,
"input[accept='*']"))
)
document_input.send_keys(item['document'])
time.sleep(2)
# Send caption with media
caption_input = WebDriverWait(driver, 20).until(
EC.presence_of_element_located(
(By.CSS_SELECTOR, 'div[aria-label="Add a caption"]'))
)
caption_input.send_keys(item.get('message',""))
caption_input.send_keys(Keys.ENTER)
except:
print('error')
continue
else:
try:
message_input = WebDriverWait(driver, 20).until(
EC.presence_of_element_located(
(By.CSS_SELECTOR, 'div[aria-label="Type a message"]'))
)
message_input.send_keys(item.get('message',""))
message_input.send_keys(Keys.ENTER)
except:
print('error')
continue
time.sleep(100)
driver.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment