Closed Jeck-Liu-Create closed 5 months ago
I'm experiencing an issue where messageSenderLayer class are timing out, possibly due to high bandwidtself.state property is set toOPENING for an extended period without transitioning to CONNECTED, prompting a proactive
Here's a potential method I've drafted forSenderLayer class:
def reload(self):
return self.ThreadsafeBrowser.sync_page_evaluate("() => location.reload()",None)
Would this method be effective in ensuring that the page is refreshed in situations where the self.state remains in the OPENING state for too long without establishing a connection?
Create
take autoClose
Automatically closes the wppconnect only when scanning the QR code
timeout for send message, may be not related to it please send your code and error
After initializing SetWhatsApp normally, since I am using tkinter, the create_web_send function is used normally. The check_state function is queried every 10 seconds, and the send_image_message function is called approximately every 2 seconds. An error that is not outdated is reported under OPENING, but it is difficult to reproduce. However, most errors are due to Timeout.
Below is a simple modification made to run_threadsafe in threadsafe_browser.py:
def run_threadsafe(self, func, *args, timeout_=120, **kwargs):
future = asyncio.run_coroutine_threadsafe(
func(*args, **kwargs), self.loop
)
try:
result = future.result(timeout=timeout_)
return result
except TimeoutError:
print(f"Function {func.__name__} timed out after {timeout_} seconds.")
return None
# WhatsApp Sending Class
class SetWhatsApp:
def __init__(self, session_name):
self.session_name = session_name
self.creator = None
self.client = None
self.browser_open = False
# Start WhatsApp session
async def create_web_send(self, headless=False):
if headless:
self.creator = Create(session=self.session_name, browser="firefox", headless=headless)
else:
self.creator = Create(session=self.session_name, browser="firefox")
self.client = self.creator.start()
self.browser_open = True
# Send a text message
def send_text_message(self, to, message_data):
if self.browser_open and self.client:
try:
result = self.client.sendText(to=to, content=message_data)
if result is None:
print(f"Failed to send message to {to} with data {message_data}: Timeout")
return False
elif result.get('sendMsgResult') == {}:
return True
else:
return False
except Exception as e:
print(f"Failed to send message to {to} with data {message_data}: {e.__class__.__name__}: {e}")
return False
else:
print("Browser is not open.")
return False
# Send an image message
def send_image_message(self, to, image_path):
print(to, image_path)
if self.browser_open and self.client:
try:
result = self.client.sendImage(to=to, filePath=image_path)
if result is None:
print(f"Failed to send image to {to} with path {image_path}: Timeout")
return False
elif result.get('sendMsgResult', {}).get('messageSendResult') == 'OK':
return True
else:
return False
except Exception as e:
print(f"Failed to send image to {to} with path {image_path}: {e.__class__.__name__}: {e}")
return False
else:
print("Browser is not open.")
return False
def send_video_message(self, to, video_path):
try:
result = self.client.sendFile(
to=to,
pathOrBase64=video_path, # Pass in the file path here
nameOrOptions='video.mp4', # Pass in the file name here
caption=None # Pass in the title here
)
if result is None:
print(f"Failed to send video to {to} with path {video_path}: Timeout")
return False
elif result.get('sendMsgResult', {}).get('messageSendResult') == 'OK':
print("Video File sent successfully:", result)
return True
else:
print("Video File sent failed:", result)
return False
except Exception as e:
print(f"An error occurred: {e.__class__.__name__}: {e}")
return False
# Check if WhatsApp session is connected
def check_state(self):
try:
if self.creator.state != 'CONNECTED' and self.creator.state != 'CLOSED':
print(f"Loading state:{self.creator.state}")
self.creator_reload()
time.sleep(5)
return False
elif self.creator.state != 'CONNECTED':
print(f"Connection interrupted state:{self.creator.state}")
return False
else:
return True
except Exception as e:
print("check_state error:", e)
return False
# Close WhatsApp session
def creator_close(self):
if self.creator:
self.creator.sync_close()
print("Closing browser")
# Actively refresh
def creator_reload(self):
if self.creator:
self.client.reload()
print("Refreshing browser")
Exception in thread Thread-8:
Traceback (most recent call last):
File "threading.py", line 932, in _bootstrap_inner
File "threading.py", line 870, in run
File "WPP_Whatsapp\api\Whatsapp.py", line 54, in _loop_
func()
File "WPP_Whatsapp\api\Whatsapp.py", line 63, in __intervalHandel
newConnected = self.ThreadsafeBrowser.sync_page_evaluate("() => window.WPP && window.WPP.conn.isRegistered()")
File "WPP_Whatsapp\PlaywrightSafeThread\browser\threadsafe_browser.py", line 352, in sync_page_evaluate
return self.run_threadsafe(self.page.evaluate, expression, arg, timeout_=timeout_)
File "WPP_Whatsapp\PlaywrightSafeThread\browser\threadsafe_browser.py", line 403, in run_threadsafe
result = future.result(timeout=timeout_)
File "concurrent\futures\_base.py", line 446, in result
concurrent.futures._base.TimeoutError
After initializing SetWhatsApp normally, since I am using tkinter, the create_web_send function is used normally. The check_state function is queried every 10 seconds, and the send_image_message function is called approximately every 2 seconds. An error that is not outdated is reported under OPENING, but it is difficult to reproduce. However, most errors are due to Timeout.
Below is a simple modification made to run_threadsafe in threadsafe_browser.py:
def run_threadsafe(self, func, *args, timeout_=120, **kwargs): future = asyncio.run_coroutine_threadsafe( func(*args, **kwargs), self.loop ) try: result = future.result(timeout=timeout_) return result except TimeoutError: print(f"Function {func.__name__} timed out after {timeout_} seconds.") return None
# WhatsApp Sending Class class SetWhatsApp: def __init__(self, session_name): self.session_name = session_name self.creator = None self.client = None self.browser_open = False # Start WhatsApp session async def create_web_send(self, headless=False): if headless: self.creator = Create(session=self.session_name, browser="firefox", headless=headless) else: self.creator = Create(session=self.session_name, browser="firefox") self.client = self.creator.start() self.browser_open = True # Send a text message def send_text_message(self, to, message_data): if self.browser_open and self.client: try: result = self.client.sendText(to=to, content=message_data) if result is None: print(f"Failed to send message to {to} with data {message_data}: Timeout") return False elif result.get('sendMsgResult') == {}: return True else: return False except Exception as e: print(f"Failed to send message to {to} with data {message_data}: {e.__class__.__name__}: {e}") return False else: print("Browser is not open.") return False # Send an image message def send_image_message(self, to, image_path): print(to, image_path) if self.browser_open and self.client: try: result = self.client.sendImage(to=to, filePath=image_path) if result is None: print(f"Failed to send image to {to} with path {image_path}: Timeout") return False elif result.get('sendMsgResult', {}).get('messageSendResult') == 'OK': return True else: return False except Exception as e: print(f"Failed to send image to {to} with path {image_path}: {e.__class__.__name__}: {e}") return False else: print("Browser is not open.") return False def send_video_message(self, to, video_path): try: result = self.client.sendFile( to=to, pathOrBase64=video_path, # Pass in the file path here nameOrOptions='video.mp4', # Pass in the file name here caption=None # Pass in the title here ) if result is None: print(f"Failed to send video to {to} with path {video_path}: Timeout") return False elif result.get('sendMsgResult', {}).get('messageSendResult') == 'OK': print("Video File sent successfully:", result) return True else: print("Video File sent failed:", result) return False except Exception as e: print(f"An error occurred: {e.__class__.__name__}: {e}") return False # Check if WhatsApp session is connected def check_state(self): try: if self.creator.state != 'CONNECTED' and self.creator.state != 'CLOSED': print(f"Loading state:{self.creator.state}") self.creator_reload() time.sleep(5) return False elif self.creator.state != 'CONNECTED': print(f"Connection interrupted state:{self.creator.state}") return False else: return True except Exception as e: print("check_state error:", e) return False # Close WhatsApp session def creator_close(self): if self.creator: self.creator.sync_close() print("Closing browser") # Actively refresh def creator_reload(self): if self.creator: self.client.reload() print("Refreshing browser")
Exception in thread Thread-8: Traceback (most recent call last): File "threading.py", line 932, in _bootstrap_inner File "threading.py", line 870, in run File "WPP_Whatsapp\api\Whatsapp.py", line 54, in _loop_ func() File "WPP_Whatsapp\api\Whatsapp.py", line 63, in __intervalHandel newConnected = self.ThreadsafeBrowser.sync_page_evaluate("() => window.WPP && window.WPP.conn.isRegistered()") File "WPP_Whatsapp\PlaywrightSafeThread\browser\threadsafe_browser.py", line 352, in sync_page_evaluate return self.run_threadsafe(self.page.evaluate, expression, arg, timeout_=timeout_) File "WPP_Whatsapp\PlaywrightSafeThread\browser\threadsafe_browser.py", line 403, in run_threadsafe result = future.result(timeout=timeout_) File "concurrent\futures\_base.py", line 446, in result concurrent.futures._base.TimeoutError
creator_reload is something I added later and can be ignored.
to create custom Create
follow custom_create
# Start Whatsapp
client = Whatsapp(session, ThreadsafeBrowser)
client.start()
# after start client you need
# wait for scan qrcode and login
is_logged = client.waitForLogin()
when use async method, you dont need run_threadsafe any more for example:
async def sendText_(self, to, content, options=None):
if not options:
options = {}
to = self.valid_chatId(to)
send_result = await self.ThreadsafeBrowser.page_evaluate("""({ to, content, options }) =>
WPP.chat.sendTextMessage(to, content, {
...options,
waitForAck: true,
})""", {"to": to, "content": content, "options": options})
self.logger.debug(f'{self.session}: Send Message {send_result=}')
return send_result
I'm verifying self.state before sending a message, and I don't understand what self.state=OPENING means.