-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconsole_spammer.py
More file actions
400 lines (350 loc) · 18.4 KB
/
console_spammer.py
File metadata and controls
400 lines (350 loc) · 18.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
"""
WhatsApp Spammer - Console Version
This version avoids the Selenium timeout issue by using a completely different approach
"""
import os
import sys
import time
import subprocess
import importlib.util
# Check Python version first
python_version = sys.version.split()[0]
print(f"\n===== WhatsApp Spammer - Console Version =====")
print(f"Using Python {python_version}")
# Function to install required packages if they don't exist
def ensure_package(package_name):
if importlib.util.find_spec(package_name) is None:
print(f"Installing {package_name}...")
subprocess.check_call([sys.executable, "-m", "pip", "install", package_name])
print(f"Successfully installed {package_name}")
else:
print(f"{package_name} is already installed")
# Install alternative packages to avoid the Selenium timeout issue
print("\nChecking required packages...")
ensure_package('undetected_chromedriver')
ensure_package('pyautogui')
# Now import the required packages
print("\nImporting packages...")
import undetected_chromedriver as uc
import pyautogui
from time import sleep
def get_input(prompt, validator=None, error_message=None):
"""Get user input with validation"""
while True:
user_input = input(prompt)
if validator is None or validator(user_input):
return user_input
print(error_message or "Invalid input. Please try again.")
def is_positive_integer(value):
try:
num = int(value)
return num >= 0
except:
return False
def send_whatsapp_messages():
print("\n===== WhatsApp Spammer =====")
print("(Using undetected_chromedriver to avoid Selenium issues)\n")
# Get user inputs
target_name = get_input("Enter target name (must be in your contacts): ")
message = get_input("Enter message to send: ")
num_messages = int(get_input(
"Enter number of messages to send: ",
is_positive_integer,
"Please enter a positive integer."
))
time_interval = int(get_input(
"Enter time interval between messages (seconds): ",
is_positive_integer,
"Please enter a positive integer."
))
print("\nInitializing Chrome browser...")
try:
# Use undetected_chromedriver to avoid detection
driver = uc.Chrome()
# Open WhatsApp Web
print("Opening WhatsApp Web...")
driver.get('https://web.whatsapp.com/')
# Wait for user to scan QR code
print("\nPlease scan the QR code in the browser window to login to WhatsApp")
print("Waiting 30 seconds for QR code scanning...")
sleep(30)
# Find and click on contact search
print(f"Searching for contact: {target_name}")
# Click on search box and type contact name
try:
# Try to find and click the search box
search_box_selector = '//div[@contenteditable="true"][@data-tab="3"]'
try:
search_boxes = driver.find_elements_by_xpath(search_box_selector)
except AttributeError:
# For newer selenium versions
from selenium.webdriver.common.by import By
search_boxes = driver.find_elements(By.XPATH, search_box_selector)
if not search_boxes:
# Fallback to another approach for newer WhatsApp versions
search_box = None
selectors = [
'[data-testid="chat-list-search"]',
'[title="Search input textbox"]',
'[data-testid="search-input"]',
'[aria-label="Search input textbox"]',
'[placeholder="Search or start new chat"]'
]
for selector in selectors:
try:
try:
elements = driver.find_elements_by_css_selector(selector)
except AttributeError:
from selenium.webdriver.common.by import By
elements = driver.find_elements(By.CSS_SELECTOR, selector)
if elements:
search_box = elements[0]
break
except:
continue
if search_box:
search_box.click()
else:
print("Couldn't find the search box using selectors. Trying PyAutoGUI approach...")
# Use PyAutoGUI as a fallback
# Give time for the page to load fully
sleep(5)
# Using PyAutoGUI to click where the search box usually is
screen_width, screen_height = pyautogui.size()
pyautogui.click(screen_width * 0.2, screen_height * 0.1)
else:
search_boxes[0].click()
# Type the contact name in the search box
pyautogui.typewrite(target_name)
sleep(2)
# Try to find and click on the contact in search results
contact_found = False
try:
# Extract first word from contact name (to handle cases with emojis or special characters)
# This helps to find contacts when the name contains emojis or special formatting
name_parts = target_name.split()
first_word = name_parts[0] if name_parts else target_name
print(f"Using '{first_word}' as search term for contact with name: {target_name}")
# Add a delay and press Enter - this often helps select the first match
sleep(2)
pyautogui.press('enter')
sleep(3) # Wait for potential navigation
# Try to find the contact using Selenium first with more flexible matching
contact_selectors = [
# Try exact match first
f'//span[@title="{target_name}"]',
# Try partial match with the first word (good for emoji names)
f'//div[@role="row"]//span[contains(text(),"{first_word}")]',
# WhatsApp Web 2025 selector patterns
'//div[@role="row" and @tabindex="-1"]', # First row that's selectable
'//div[@role="row" and @aria-selected="true"]', # Selected row
# Try broader match with first word
f'//div[contains(@data-testid, "cell-frame")]//span[contains(text(),"{first_word}")]',
# Try with title attribute containing first word
f'//div[contains(@data-testid, "cell-frame")]//span[contains(@title,"{first_word}")]',
# Get first result in different parts of UI
'//div[contains(@data-testid, "chat-list-search-result-item")][1]',
# Very generic - any chat cell - use with caution
'//div[contains(@data-testid, "cell-frame")][1]',
# First row in the chat list
'//div[@role="row"][1]',
# Absolute last resort - any clickable element in the left panel
'//div[@aria-label="Chat list"]//div[@role="button"][1]'
]
for selector in contact_selectors:
try:
try:
# Try to find the element first to check if it exists
elements = driver.find_elements_by_xpath(selector)
if elements:
contact_elem = elements[0] # Take the first match if multiple found
contact_elem.click()
contact_found = True
print(f"Found and clicked on contact using selector: {selector}")
break
except AttributeError:
from selenium.webdriver.common.by import By
elements = driver.find_elements(By.XPATH, selector)
if elements:
contact_elem = elements[0] # Take the first match if multiple found
contact_elem.click()
contact_found = True
print(f"Found and clicked on contact using selector: {selector}")
break
except:
continue
except:
print("Could not find contact using Selenium, trying keyboard approach")
if not contact_found:
# If Selenium approach failed, try pressing Enter to select first search result
pyautogui.press('enter')
print("Selected first search result using keyboard")
# Wait for the chat to load
print(f"Opening chat with {target_name}...")
sleep(5) # Longer wait time
# Try to focus on the chat area using PyAutoGUI
print("Attempting to focus chat area...")
screen_width, screen_height = pyautogui.size()
# Click in the middle of the main chat area
pyautogui.click(screen_width * 0.5, screen_height * 0.5)
sleep(1)
# Click where the message input field should be
pyautogui.click(screen_width * 0.5, screen_height * 0.9)
sleep(1)
# Give more time for the chat to load properly
print("Waiting for chat to fully load...")
sleep(5)
# Find the message input box
print("Finding message input field...")
message_input_found = False
try:
# Try to find the message input field using Selenium
input_selectors = [
'//div[@contenteditable="true"][@data-testid="conversation-compose-box-input"]',
'//*[@id="main"]/footer//div[@contenteditable="true"]',
'//footer//div[@role="textbox"]',
'//div[@title="Type a message"]',
'//div[@data-tab="10"]',
'//footer//div[@contenteditable="true"]',
'//div[@contenteditable="true"]'
]
message_input = None
for selector in input_selectors:
try:
try:
message_input = driver.find_element_by_xpath(selector)
message_input.click()
message_input_found = True
print(f"Found message input field using selector: {selector}")
break
except AttributeError:
from selenium.webdriver.common.by import By
message_input = driver.find_element(By.XPATH, selector)
message_input.click()
message_input_found = True
print(f"Found message input field using selector: {selector} (with By.XPATH)")
break
except Exception as e:
# Just continue to next selector
continue
if not message_input_found:
# Try CSS selectors
css_selectors = [
'[data-testid="conversation-compose-box-input"]',
'footer div[contenteditable="true"]',
'[title="Type a message"]',
'div[data-tab="10"]',
'div[contenteditable="true"]'
]
for selector in css_selectors:
try:
try:
message_input = driver.find_element_by_css_selector(selector)
message_input.click()
message_input_found = True
print(f"Found message input field using CSS selector: {selector}")
break
except AttributeError:
from selenium.webdriver.common.by import By
message_input = driver.find_element(By.CSS_SELECTOR, selector)
message_input.click()
message_input_found = True
print(f"Found message input field using CSS selector: {selector} (with By.CSS_SELECTOR)")
break
except Exception as e:
continue
except Exception as e:
print(f"Error finding message input field using Selenium: {str(e)}")
if not message_input_found:
# Try clicking where the input field usually is using PyAutoGUI
print("Using PyAutoGUI to click on message input area")
screen_width, screen_height = pyautogui.size()
# Click on the bottom part of the screen where the message input usually is
pyautogui.click(screen_width * 0.5, screen_height * 0.9)
sleep(1)
# Try clicking again just to be sure
pyautogui.click(screen_width * 0.5, screen_height * 0.9)
sleep(1)
# Send messages
print(f"Sending {num_messages} messages with {time_interval}s interval...")
for i in range(num_messages):
try:
# Type message with multiple approaches
sent = False
# Method 1: Use Selenium if we found the input field
if message_input and message_input_found:
try:
# Make sure it's focused
message_input.click()
# Clear any existing text
message_input.clear()
# Send message
message_input.send_keys(message)
sleep(0.5)
message_input.send_keys("\n")
sent = True
print(f"Sent message {i+1}/{num_messages} using Selenium")
except Exception as e:
print(f"Selenium method failed: {str(e)}")
# Will try next method
# Method 2: Try JavaScript executor if Selenium failed
if message_input and not sent:
try:
driver.execute_script(f"arguments[0].textContent = '{message}'", message_input)
sleep(0.5)
message_input.send_keys("\n")
sent = True
print(f"Sent message {i+1}/{num_messages} using JavaScript")
except Exception as e:
print(f"JavaScript method failed: {str(e)}")
# Will try next method
# Method 3: Fallback to PyAutoGUI if both Selenium methods failed
if not sent:
# Ensure we're focused on the chat area first
screen_width, screen_height = pyautogui.size()
# Click precisely where the input field should be
pyautogui.click(screen_width * 0.5, screen_height * 0.9)
sleep(0.5)
# Clear any previous text by selecting all and deleting
pyautogui.hotkey('ctrl', 'a')
sleep(0.2)
pyautogui.press('delete')
sleep(0.2)
# Type message carefully with pauses
pyautogui.typewrite(message, interval=0.05) # Slower typing to ensure accuracy
sleep(0.5)
pyautogui.press('enter')
sent = True
print(f"Sent message {i+1}/{num_messages} using PyAutoGUI")
# Wait for the specified interval
if i < num_messages - 1: # Don't wait after the last message
sleep(time_interval)
except Exception as e:
print(f"Error sending message {i+1} with all methods: {str(e)}")
# Try to continue with the next message
print("\nAll messages sent successfully!")
# Keep browser open for a moment
sleep(5)
except Exception as e:
print(f"Error during message sending: {str(e)}")
except Exception as e:
print(f"Error initializing Chrome browser: {str(e)}")
print("\nPossible solutions:")
print("1. Make sure Chrome browser is installed")
print("2. Try running this script with administrator privileges")
finally:
print("\nClosing browser...")
try:
driver.close()
except:
pass
print("\nExiting WhatsApp Spammer. Goodbye!")
if __name__ == "__main__":
try:
send_whatsapp_messages()
except KeyboardInterrupt:
print("\n\nOperation cancelled by user.")
except Exception as e:
print(f"\nAn unexpected error occurred: {str(e)}")
finally:
print("\nExiting WhatsApp Spammer. Goodbye!")