WhatsApp texting using webbrowser module of python - python

import webbrowser
import time
import datetime
name = input('Enter the contact number of a person you want to send message in WhatsApp: ')
message = input('Enter the message: ')
time1 = input('Enter time in {hh:mm:ss} format: ')
print(f'Time entered by user: {time1}')
while True:
current_time = time.ctime()
time_format = current_time[11:19]
time.sleep(1)
print(f'Current time: {time_format}')
if time1 == time_format:
webbrowser.open_new_tab(f'https://web.whatsapp.com/send?phone=+91{name}&text={message}')
break
elif time1 < time_format:
print('Enter correct time')
break
else:
print('waiting..')
I am taking message, contact number and time as a input from the user. whenever, if condition satisfies, WhatsApp is open with the contact number and message you type in before.
Only problem is, I have to manually hit the send button to send message. Everything else is working fine.
Is there any way to do that? It would be great, if you provide solution without using Selenium
Thanks in advance!

This doesn't seem really efficient and not really good to constantly check to see if the time the user gave is the same as the current one. The schedule module can be really helpful with this and it does help to make your code look cleaner. I'll provide 2 answers, one with the schedule library and one without it.
Remember that if the user inputs a time that has passed, that doesn't matter to the program and it will only send the message at the next time that the time the user provided is the current device time. For example if the user inputs 13:10:00 and the current device time is 14:00:00 then the message will be sent the next time the current time is 13:10:00 which is the next day.
import os
import time
import webbrowser
from datetime import datetime
from string import ascii_letters
name = input('Enter the contact number of a person you want to send message in WhatsApp: ')
message = input('Enter the message:\n')
time1 = input('Enter time in {hh:mm:ss} format: ')
# Check if there aren't any ':' in the input time
if ":" not in time1:
print("Please input a correct time format")
os._exit(0)
# Check if there are any letters in the input time
elif ascii_letters in time1:
print("Please input a correct time format")
os._exit(0)
print(f'Time entered by user: {time1}')
# Check every .9 seconds if the current time is the same as the user input time
while True:
current_time = datetime.now().strftime("%H:%M:%S")
print(f'Current time: {current_time}')
if time1 == current_time:
webbrowser.open_new_tab(f'https://web.whatsapp.com/send?phone=+91{name}&text={message}')
break
else:
time.sleep(0.9)
And with the schedule library this is how it would probably look like:
(this is how you would probably do it)
import os
import time
import schedule
import webbrowser
from string import ascii_letters
def send_whatsapp_msg(name, message):
webbrowser.open_new_tab(f'https://web.whatsapp.com/send?phone=+91{name}&text={message}')
return schedule.CancelJob # do this if you want to send this message only once
# or just exit the program entirely if you don't want to run any more tasks
# os._exit(0)
name = input('Enter the contact number of a person you want to send message in WhatsApp: ')
message = input('Enter the message:\n') # Message to be sent
time1 = input('Enter time in {hh:mm:ss} format: ') # Time to sent the message
# Check if there aren't any ':' in the input time
if ":" not in time1:
print("Please input a correct time format")
os._exit(0)
# Check if there are any letters in the input time
elif ascii_letters in time1:
print("Please input a correct time format")
os._exit(0)
print(f'Time entered by user: {time1}')
# Schedule the message to be sent
schedule.every().day.at(time1).do(send_whatsapp_msg, name, message)
# Wait for the tasks to run and check the time every .9 seconds
while True:
schedule.run_pending()
time.sleep(0.9)
To fix the button clicking problem I think I found a "hacky" solution, using selenium and pyautogui. On Windows, you can install the WhatsApp application and scan the QR Code only once and then this solution will probably work for you.
You will also have to install the selenium chrome webdriver and take a screenshot of the "arrow" button to send the message to on the WhatsApp app. Here is the janky solution:
import os
import time
import schedule
import pyautogui
from string import ascii_letters
from selenium import webdriver
from selenium.webdriver.commn.keys import Keys
def send_whatsapp_msg(name, message):
driver = webdriver.Chrome() # you can user different drivers like 'Firefox()' but you will have to install them first
# look at https://selenium-python.readthedocs.io/installation.html for more info
driver.get("https://api.whatsapp.com/send?phone=+91{name}&text={message}")
time.sleep(10) # Wait for everything to set up, can be assigned lower values
# Click on the 'Open WhatsApp' Prompt Button
# Much easier to do it with pyautogui since I couldn't make it work with Selenium
# Look at https://pyautogui.readthedocs.io/en/latest/quickstart.html#screenshot-functions for the '.locateCenterOnScreen' function
coords = pyautogui.locateCenterOnScreen("open_whatsapp.png")
pyautogui.click(coords[0], coords[1]) # read the docs on what '.locateCenterOnScreen' returns
time.sleep(15) # Wait for the WhatsApp dektop app to load up
coords = pyautogui.locateCenterOnScreen("click_send.png") # coordinates for the 'send' button
pyautogui.click(coords[0], coords[1])
# Your message has been sent!
return schedule.CancelJob # do this if you want to send this message only once
# or just exit the program entirely if you don't want to run any more tasks
# os._exit(0)
name = input('Enter the contact number of a person you want to send message in WhatsApp: ')
message = input('Enter the message:\n') # Message to be sent
time1 = input('Enter time in {hh:mm:ss} format: ') # Time to sent the message
# Check if there aren't any ':' in the input time
if ":" not in time1:
print("Please input a correct time format")
os._exit(0)
# Check if there are any letters in the input time
elif ascii_letters in time1:
print("Please input a correct time format")
os._exit(0)
print(f'Time entered by user: {time1}')
# Schedule the message to be sent
schedule.every().day.at(time1).do(send_whatsapp_msg, name, message)
# Wait for the tasks to run and check the time every .9 seconds
while True:
schedule.run_pending()
time.sleep(0.9)
click_send.png looks like this:
and open_whatsapp.png looks like this:
open_whatsapp.png is a screenshot of the "Open WhatsApp" button that the website prompts you, but it was different in my language so I had to edit it out.
Also I don't know how reliable pyautogui will be but it worked every time I tried to run this, so I guess it kinda works.

Related

While Loop No Longer Updating Data when added "Press Enter to Exit"

I am a beginner to Python and recently was making a **Discord Rich Prescense** application. The problem is that I was using a While Loop and added a "*Press Enter to Exit*" feature. This made the Rich Prescense stuck on One Quote. I have attached a screenshot of the problem.
from config import credentials
from data import quotes
from pypresence import Presence
import random
import time
def quotegen():
RPC = Presence(credentials.clientid)
RPC.connect()
while True:
RPC.update(details="Random Quote:", state=random.choice(quotes.quotes))
i = input("Press Enter to Exit")
time.sleep(30)
if not i:
break
Screenshot of what its supposed to do:
Using the keyboard module (https://pypi.org/project/keyboard/)
you can do it all.
I modified your code to fit your requirements:
import keyboard # using module keyboard
from config import credentials
from data import quotes
from pypresence import Presence
import random
import time
def quotegen():
RPC = Presence(credentials.clientid)
RPC.connect()
while True:
RPC.update(details="Random Quote:", state=random.choice(quotes.quotes))
i = input("Press Enter to Exit")
time.sleep(30)
if keyboard.is_pressed('enter'): # if key 'enter' is pressed
break

Displaying desktop notification after getting a new message python tkinter

I wanted to make a notification system for StackOverflow using tkinter, when an item is unread in my inbox i want it to show the notification(but only once), which it does. But its not efficient. In some ways it shows notification once, and when i click on it, it takes some time for the notification to be identified as read by the API, So new notifications keeps on popping up, causing GUI to crash(as im running it inside of a after()). So i wanted to know if the notification part could be made more efficient in some way.
Code:
import tkinter as tk
import add
from time import ctime
import datetime
from stackapi import StackAPI
from win10toast import ToastNotifier
import threading
import webbrowser
root = tk.Tk()
root.title('Stack Notifier')
def authorise():
print('auth')
global end, acc_key, start, inbox, auth_button
if required:
add.run() #selenium for automation
acc_key = add.acc_key_dum #accesskey passed from another module
start = datetime.datetime.now()
hours_added = datetime.timedelta(hours=24)
end = start + hours_added #time for reaunthentication
site.key = add.key #access key from another module
site.access_token = acc_key #access token from another module
site.max_pages = 1
inbox = site.fetch('users/13382000/inbox')
auth_button['state'] = tk.DISABLED
threading.Thread(target=first).start()
else:
inbox = site.fetch('users/13382000/inbox')
threading.Thread(target=first).start()
def first():
global current, required, inbox, auth_button
def popup():
webbrowser.open(link,new=0)
inbox = site.fetch('users/13382000/inbox')
print('chc')
current = datetime.datetime.now()
if start < current < end:
required = False
else:
required = True
auth_button['state'] = tk.NORMAL
if not required:
print('first')
is_unread = inbox['items'][0]['is_unread']
if is_unread:
title = inbox['items'][0]['title']
item_type = inbox['items'][0]['item_type']
link = inbox['items'][0]['link']
creation_date = ctime(inbox['items'][0]['creation_date'])
noti = ToastNotifier()
noti.show_toast(f'StackOveflow - {item_type}',f'{title} - {creation_date}',duration=5,callback_on_click=popup,threaded=True)
print('yes')
else:
threading.Thread(target=authorise).start()
root.after(1000,threading.Thread(target=first).start)
required = True #a reference to whether authentication is required again, after 24 hrs
label_login = tk.Label(root,text='Click To authorise with StackOverflow',font=('helvatica',16))
label_login.grid(row=0,columnspan=3)
auth_button = tk.Button(root,text='Authorise',command=authorise)
auth_button.grid(row=1,column=1)
site = StackAPI('stackoverflow')
root.mainloop()
I know this is not the best of codes, but im open to ideas and suggestions.
PS: Im using selenium for automation and ask for user credentials. and it requires giving permission every 24 hours, so i need to boot up selenium every 24 hours too, which is being finely done, i guess.
Thanks in advance :D

I try to do a threading system in Python but I can't

I'm trying to make a threading system that continuously runs a while cycle but at the same time performs another function that is waiting for a string.
For example, a while cycle to write "Hello World" and a function waiting for something to be typed.
So i try with this code but it's not worked :(
import threading
from time import sleep
import time
data = []
def get_input():
data.append(input()) # Something akin to this
return data
input_thread = threading.Thread(target=get_input)
input_thread.start()
while (True):
print ("Hello World")
time.sleep(1)
input_thread.join()
if data.pop=="a":
print ("This message will be writed, only when user typed something")
A few things.
Check the array length before popping
The input thread must have a loop also
You need to press enter when you input a string
Here is the updated code:
import threading
from time import sleep
import time
data = []
def get_input():
while True:
data.append(input()) # must press enter to submit
input_thread = threading.Thread(target=get_input)
input_thread.start()
while (True):
print ("Hello World")
time.sleep(1)
if (len(data) and data.pop()=="a"):
print ("This message will be writed, only when user typed something")
input_thread.join() # never gets here

how do i make this duplicate the tab and type into the input bar?

I haven't started on the web typing part but I need help with the starting part.
Here is my code
import webbot
import os
import time
import random
os.system('pip3 install pyautogui')
driver = webbot.Browser()
print("")
driver.go_to('https://kahoot.it/')
code = input("The game id: ")
input_elements = driver.find_elements(xpath='//input')
driver.type(driver.Key.TAB,into=input_elements[0].text)
driver.type(code)
driver.type(driver.Key.ENTER,into=input_elements[0].text)
time.sleep(1.5)
username = "test"
input_elements = driver.find_elements(xpath='//input')
driver.type(driver.Key.TAB,into=input_elements[0].text)
driver.type(username)
driver.type(driver.Key.ENTER,into=input_elements[0].text)
time.sleep(2)
driver.execute_script("window.open(' ');")
time.sleep(2)
driver.go_to('https://kahoot.it/')
# keeps the loop running
while True:
time.sleep(1)
I use repl.it's pygame for this
Edit: nvm I fixed the new tab now I need to type and hit enter into the boxes

Checking for an open file with a timed refresh in Python

I'm wondering how I would go about having a function refresh itself every minute, and check if a certain file it open. I don't exactly know how to go about this, but heres an example of what I'm looking for:
def timedcheck():
if thisgame.exe is open:
print("The Program is Open!")
else:
print("The Program is closed!")
*waits 1 minute*
timedcheck()
I would also like the script to refresh the function "def timedcheck():" every minute, so it keeps checking if thisgame.exe is open.
I searched through the site already, all suggestions recommended using "import win32ui", which gives me an error when I do.
To repeat this check every minute:
def timedcheck():
while True:
if is_open("thisgame.exe"):
print("The Program is Open!")
else:
print("The Program is closed!")
sleep(60)
Since it's a .exe file, I assume that by "check if this file is open" you mean "check if thisgame.exe" is running. psutil should be helpful - I haven't tested the below code, so it may need some tweaking, but shows the general principle.
def is_open(proc_name):
import psutil
for process in psutil.process_iter():
if proc_name in process.name:
return True
return False
You can use sleep from the time module with an input of 60 for 1 minute delay between checks. You can open the file temporarily and close it if not needed. An IOError will occur if the file is already opened. Catch the error with an exception and the program will wait for another minute before trying again.
import time
def timedcheck():
try:
f = open('thisgame.exe')
f.close()
print("The Program is Closed!")
except IOError:
print("The Program is Already Open!")
time.sleep(60) #*program waits 1 minute*
timedcheck()
Here's a variation on #rkd91's answer:
import time
thisgame_isrunning = make_is_running("thisgame.exe")
def check():
if thisgame_isrunning():
print("The Program is Open!")
else:
print("The Program is closed!")
while True:
check() # ignore time it takes to run the check itself
time.sleep(60) # may wake up sooner/later than in a minute
where make_is_running():
import psutil # 3rd party module that needs to be installed
def make_is_running(program):
p = [None] # cache running process
def is_running():
if p[0] is None or not p[0].is_running():
# find program in the process list
p[0] = next((p for p in psutil.process_iter()
if p.name == program), None)
return p[0] is not None
return is_running
To install psutil on Windows for Python 2.7, you could run psutil-0.6.1.win32-py2.7.exe.

Categories