Files changed (1) hide show
  1. app.py +18 -10
app.py CHANGED
@@ -14,34 +14,41 @@ class GeminiBot:
14
 
15
  async def start(self):
16
  self.playwright = await async_playwright().start()
17
- # Launch browser once.
18
- self.browser = await self.playwright.chromium.launch(headless=True, args=["--no-sandbox"])
 
 
 
19
  print("--- Gemini Bot (Stateless) Ready ---")
20
 
21
  async def process_chat(self, message: str):
22
- # Every request gets a fresh, isolated, ephemeral context
23
- context = await self.browser.new_context()
 
 
24
  page = await context.new_page()
25
 
26
  try:
27
- # BLOCK assets to ensure faster loading
28
  await page.route("**/*", lambda route: route.abort() if route.request.resource_type in
29
  ["image", "font", "media", "stylesheet"] else route.continue_())
30
 
31
- await page.goto("https://gemini.google.com", wait_until="domcontentloaded")
 
32
 
33
- # Interact
34
- chat_box = page.locator("div[contenteditable='true']").first
 
35
  await chat_box.fill(message)
36
  await page.keyboard.press("Enter")
37
 
38
- # Wait for response
39
  await page.wait_for_selector("message-content", timeout=45000)
40
 
41
  # Extract Text
42
  current_text = await page.evaluate("""() => {
43
  const msgs = document.querySelectorAll('message-content');
44
- return msgs.length > 0 ? msgs[msgs.length - 1].innerText : "";
45
  }""")
46
 
47
  return {"text": current_text}
@@ -75,6 +82,7 @@ def health_check():
75
 
76
  @app.post("/chat")
77
  async def chat_api(request: ChatRequest):
 
78
  return await bot.process_chat(request.message)
79
 
80
  if __name__ == "__main__":
 
14
 
15
  async def start(self):
16
  self.playwright = await async_playwright().start()
17
+ # Launch browser with flags to help avoid detection
18
+ self.browser = await self.playwright.chromium.launch(
19
+ headless=True,
20
+ args=["--no-sandbox", "--disable-blink-features=AutomationControlled"]
21
+ )
22
  print("--- Gemini Bot (Stateless) Ready ---")
23
 
24
  async def process_chat(self, message: str):
25
+ # Create context with a realistic User Agent
26
+ context = await self.browser.new_context(
27
+ user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
28
+ )
29
  page = await context.new_page()
30
 
31
  try:
32
+ # BLOCK unnecessary assets to speed up loading
33
  await page.route("**/*", lambda route: route.abort() if route.request.resource_type in
34
  ["image", "font", "media", "stylesheet"] else route.continue_())
35
 
36
+ # Navigate and wait for network idle to ensure JS loads
37
+ await page.goto("https://gemini.google.com", wait_until="networkidle")
38
 
39
+ # Interact with the chat box
40
+ chat_box = page.locator("div[contenteditable='true']")
41
+ await chat_box.wait_for(timeout=20000)
42
  await chat_box.fill(message)
43
  await page.keyboard.press("Enter")
44
 
45
+ # Wait for the response container
46
  await page.wait_for_selector("message-content", timeout=45000)
47
 
48
  # Extract Text
49
  current_text = await page.evaluate("""() => {
50
  const msgs = document.querySelectorAll('message-content');
51
+ return msgs.length > 0 ? msgs[msgs.length - 1].innerText : "Error: No message content found";
52
  }""")
53
 
54
  return {"text": current_text}
 
82
 
83
  @app.post("/chat")
84
  async def chat_api(request: ChatRequest):
85
+ # This now handles the Pydantic model correctly, resolving 422 errors
86
  return await bot.process_chat(request.message)
87
 
88
  if __name__ == "__main__":