Chandima Prabhath commited on
Commit
d8d7161
Β·
1 Parent(s): e371810

Refactor URL construction in generate_llm function for consistency; adjust parameter order for clarity.

Browse files
Files changed (2) hide show
  1. app.py +42 -414
  2. polLLM.py +1 -1
app.py CHANGED
@@ -17,14 +17,14 @@ from polLLM import generate_llm
17
  logging.basicConfig(level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s")
18
 
19
  # Env vars
20
- GREEN_API_URL = os.getenv("GREEN_API_URL")
21
- GREEN_API_MEDIA_URL = os.getenv("GREEN_API_MEDIA_URL", "https://api.green-api.com")
22
- GREEN_API_TOKEN = os.getenv("GREEN_API_TOKEN")
23
- GREEN_API_ID_INSTANCE= os.getenv("GREEN_API_ID_INSTANCE")
24
- WEBHOOK_AUTH_TOKEN = os.getenv("WEBHOOK_AUTH_TOKEN")
25
- BOT_STATUS_CHAT = "[email protected]" # Chat ID for system messages
26
- image_dir = "/tmp/images"
27
- audio_dir = "/tmp/audio"
28
 
29
  if not all([GREEN_API_URL, GREEN_API_TOKEN, GREEN_API_ID_INSTANCE, WEBHOOK_AUTH_TOKEN]):
30
  raise ValueError("Environment variables are not set properly")
@@ -32,7 +32,7 @@ if not all([GREEN_API_URL, GREEN_API_TOKEN, GREEN_API_ID_INSTANCE, WEBHOOK_AUTH_
32
  # Queues & in‑memory stores
33
  task_queue = queue.Queue()
34
  trivia_store = {} # chat_id β†’ {"question":…, "answer":…}
35
- polls = {} # chat_id β†’ {"question":…, "options":[…], "votes":{1:0…}, "voters":{jid:opt}}
36
 
37
  app = FastAPI()
38
 
@@ -83,6 +83,7 @@ def send_message_to_chat(to_number, message, retries=3):
83
  return r.json()
84
  except requests.RequestException as e:
85
  if i == retries - 1:
 
86
  return {"error": str(e)}
87
 
88
  def send_message(message_id, to_number, message, retries=3):
@@ -175,404 +176,15 @@ def handle_image_generation(message_id, chat_id, prompt):
175
  logging.error("Error in handle_image_generation: %s", e)
176
  send_message(message_id, chat_id, "Error generating image.")
177
 
178
- # --- Webhook ---
179
- @app.post("/whatsapp")
180
- async def whatsapp_webhook(request: Request):
181
- global last_message_time
182
- last_message_time = time.time()
183
-
184
- auth = request.headers.get("Authorization", "").strip()
185
- if auth != f"Bearer {WEBHOOK_AUTH_TOKEN}":
186
- raise HTTPException(403, "Unauthorized")
187
- try:
188
- data = await request.json()
189
- except:
190
- return JSONResponse({"error": "Invalid JSON"}, status_code=400)
191
- if data.get("typeWebhook") != "incomingMessageReceived":
192
- return {"success": True}
193
-
194
- logging.debug("recv: %s", data)
195
- sd = data["senderData"]
196
- chat = sd["chatId"]
197
- mid = data["idMessage"]
198
- sender_jid = sd.get("sender")
199
-
200
- md = data.get("messageData", {})
201
- if md.get("typeMessage") == "quotedMessage" or "quotedMessage" in md:
202
- logging.debug("skip native quotedMessage")
203
- return {"success": True}
204
-
205
- if "textMessageData" in md:
206
- body = md["textMessageData"].get("textMessage", "").strip()
207
- ctx = md["textMessageData"].get("contextInfo", {})
208
- elif "extendedTextMessageData" in md:
209
- body = md["extendedTextMessageData"].get("text", "").strip()
210
- ctx = md["extendedTextMessageData"].get("contextInfo", {})
211
  else:
212
- return {"success": True}
213
-
214
- if ctx.get("mentionedJid") or ctx.get("mentionedJidList"):
215
- return {"success": True}
216
- if chat.endswith("@g.us") and re.search(r"@\d+", body):
217
- return {"success": True}
218
-
219
- low = body.lower()
220
-
221
- # --- New Commands ---
222
- if low == "/help":
223
- help_text = (
224
- "πŸ€– *Hi there, I'm Eve!* Here are the commands you can use:\n\n"
225
- "β€’ `/help` – Show this help message.\n"
226
- "β€’ `/summarize <text>` – Get a quick summary of your text.\n"
227
- "β€’ `/translate <language>|<text>` – Translate text to your chosen language.\n"
228
- "β€’ `/joke` – Enjoy a random, funny joke.\n"
229
- "β€’ `/weather <location>` – Get the current weather for a location.\n"
230
- "β€’ `/inspire` – Receive a short inspirational quote.\n"
231
- "β€’ `/trivia` – Start a new trivia question.\n"
232
- "β€’ `/answer` – Reveal the trivia answer.\n"
233
- "β€’ `/meme <text>` – Generate a fun meme image.\n"
234
- "β€’ `/poll <Question>|<Option1>|<Option2>|…` – Create a poll.\n"
235
- "β€’ `/results` – See current poll results.\n"
236
- "β€’ `/endpoll` – End the poll and show final results.\n"
237
- "β€’ `/imagine <prompt>` – Generate an image from your prompt.\n\n"
238
- "Send any other text and I'll reply with a voice message. I'm here to help, so don't hesitate to ask!"
239
- )
240
- send_message(mid, chat, help_text)
241
- return {"success": True}
242
-
243
- if low.startswith("/summarize "):
244
- txt = body[len("/summarize "):].strip()
245
- summary = generate_llm(f"Summarize this text in one short paragraph:\n\n{txt}")
246
- send_message(mid, chat, summary)
247
- return {"success": True}
248
-
249
- if low.startswith("/translate "):
250
- part = body[len("/translate "):]
251
- if "|" not in part:
252
- send_message(mid, chat, "Please use `/translate <language>|<text>`")
253
- else:
254
- lang, txt = part.split("|", 1)
255
- resp = generate_llm(f"Translate the following into {lang.strip()}:\n\n{txt.strip()}")
256
- send_message(mid, chat, resp)
257
- return {"success": True}
258
-
259
- if low == "/joke":
260
- try:
261
- joke = requests.get("https://official-joke-api.appspot.com/random_joke", timeout=5).json()
262
- send_message(mid, chat, f"{joke['setup']}\n\n{joke['punchline']}")
263
- except:
264
- send_message(mid, chat, generate_llm("Tell me a short, funny joke."))
265
- return {"success": True}
266
-
267
- if low.startswith("/weather "):
268
- loc = body[len("/weather "):].strip().replace(" ", "+")
269
- try:
270
- w = requests.get(f"http://sl.wttr.in/{loc}?format=4", timeout=5).text
271
- send_message(mid, chat, w)
272
- except:
273
- send_message(mid, chat, "Could not fetch weather.")
274
- return {"success": True}
275
-
276
- if low == "/inspire":
277
- quote = generate_llm("Give me a short inspirational quote.")
278
- send_message(mid, chat, f"✨ {quote}")
279
- return {"success": True}
280
-
281
- # TRIVIA
282
- if low == "/trivia":
283
- randomSeed = random.randint(0, 9999999)
284
- raw = generate_llm(
285
- (f"Generate a trivia question and answer depening on this randowm seed {randomSeed} to make it unique in JSON format like this: "
286
- "{\"question\": \"What is the capital of France?\", \"answer\": \"Paris\"}")
287
- )
288
- def extract_json(text):
289
- import re
290
- match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", text, re.DOTALL)
291
- if match:
292
- return match.group(1)
293
- return text
294
- try:
295
- json_text = extract_json(raw)
296
- obj = json.loads(json_text)
297
- if "question" in obj and "answer" in obj:
298
- trivia_store[chat] = obj
299
- send_message(mid, chat, f"❓ {obj['question']}\nReply with `/answer` to see the answer.")
300
- else:
301
- raise ValueError("Missing expected keys.")
302
- except Exception as e:
303
- logging.error("Trivia JSON parse error: %s, raw response: %s", e, raw)
304
- send_message(mid, chat, "Failed to generate trivia. Please try again.")
305
- return {"success": True}
306
-
307
- # ANSWER: Accept any message starting with /answer
308
- if low.startswith("/answer"):
309
- if chat in trivia_store:
310
- ans = trivia_store.pop(chat)["answer"]
311
- send_message(mid, chat, f"πŸ’‘ Answer: {ans}")
312
- else:
313
- send_message(mid, chat, "No active trivia. Send `/trivia` to start one.")
314
- return {"success": True}
315
-
316
- if low.startswith("/meme "):
317
- txt = body[len("/meme "):].strip()
318
- send_message(mid, chat, "🎨 Generating your meme...")
319
- task_queue.put({
320
- "type": "image",
321
- "message_id": mid,
322
- "chat_id": chat,
323
- "prompt": f"meme template with text: {txt}"
324
- })
325
- return {"success": True}
326
-
327
- if low.startswith("/poll "):
328
- parts = body[len("/poll "):].split("|")
329
- if len(parts) < 3:
330
- send_message(mid, chat, "Please use `/poll Question|Option1|Option2|...`")
331
- else:
332
- q = parts[0].strip()
333
- opts = [p.strip() for p in parts[1:]]
334
- votes = {i+1: 0 for i in range(len(opts))}
335
- polls[chat] = {"question": q, "options": opts, "votes": votes, "voters": {}}
336
- txt = f"πŸ“Š *Poll:* {q}\n" + "\n".join(
337
- f"{i+1}. {opt}" for i, opt in enumerate(opts)
338
- ) + "\n\nReply with the *option number* to vote."
339
- send_message(mid, chat, txt)
340
- return {"success": True}
341
-
342
- if chat in polls and body.isdigit():
343
- n = int(body)
344
- p = polls[chat]
345
- if 1 <= n <= len(p["options"]):
346
- prev = p["voters"].get(sender_jid)
347
- if prev:
348
- p["votes"][prev] -= 1
349
- p["votes"][n] += 1
350
- p["voters"][sender_jid] = n
351
- send_message(mid, chat, f"βœ… Vote recorded: {p['options'][n-1]}")
352
- return {"success": True}
353
-
354
- if low == "/results":
355
- if chat in polls:
356
- p = polls[chat]
357
- txt = f"πŸ“Š *Results:* {p['question']}\n" + "\n".join(
358
- f"{i}. {opt}: {p['votes'][i]}" for i, opt in enumerate([""] + p["options"]) if i > 0
359
- )
360
- send_message(mid, chat, txt)
361
- else:
362
- send_message(mid, chat, "No active poll.")
363
- return {"success": True}
364
-
365
- if low == "/endpoll":
366
- if chat in polls:
367
- p = polls.pop(chat)
368
- txt = f"πŸ“Š *Final Results:* {p['question']}\n" + "\n".join(
369
- f"{i}. {opt}: {p['votes'][i]}" for i, opt in enumerate([""] + p["options"]) if i > 0
370
- )
371
- send_message(mid, chat, txt)
372
- else:
373
- send_message(mid, chat, "No active poll.")
374
- return {"success": True}
375
-
376
- if low.startswith("/imagine"):
377
- prompt = body[len("/imagine"):].strip()
378
- if not prompt:
379
- send_message(mid, chat, "Please use `/imagine <prompt>` to generate an image.")
380
- else:
381
- send_message(mid, chat, "✨ Your image is being generated. Please wait...")
382
- task_queue.put({
383
- "type": "image",
384
- "message_id": mid,
385
- "chat_id": chat,
386
- "prompt": prompt
387
- })
388
- return {"success": True}
389
-
390
- # Fallback: voice reply for any other text
391
- task_queue.put({
392
- "type": "audio",
393
- "message_id": mid,
394
- "chat_id": chat,
395
- "prompt": body
396
- })
397
- return {"success": True}
398
-
399
- @app.get("/", response_class=PlainTextResponse)
400
- def index():
401
- return "Server is running!"
402
-
403
- if __name__ == "__main__":
404
- # Send startup message on launch
405
- def send_startup_message():
406
- if BOT_STATUS_CHAT:
407
- startup_msg = "🌟 Hi! I'm Eve, your friendly AI assistant. I'm now live and ready to help with images, voice replies, and more!"
408
- send_message("startup", BOT_STATUS_CHAT, startup_msg)
409
- else:
410
- logging.warning("BOT_STATUS_CHAT is not set; startup message not sent.")
411
- send_startup_message()
412
- import uvicorn
413
- uvicorn.run(app, host="0.0.0.0", port=7860)
414
- import os
415
- import threading
416
- import requests
417
- import logging
418
- import queue
419
- import re
420
- import json
421
- import time
422
- from fastapi import FastAPI, Request, HTTPException
423
- from fastapi.responses import PlainTextResponse, JSONResponse
424
- from FLUX import generate_image
425
- from VoiceReply import generate_voice_reply
426
- from polLLM import generate_llm
427
-
428
- # Configure logging
429
- logging.basicConfig(level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s")
430
-
431
- # Env vars
432
- GREEN_API_URL = os.getenv("GREEN_API_URL")
433
- GREEN_API_MEDIA_URL = os.getenv("GREEN_API_MEDIA_URL", "https://api.green-api.com")
434
- GREEN_API_TOKEN = os.getenv("GREEN_API_TOKEN")
435
- GREEN_API_ID_INSTANCE= os.getenv("GREEN_API_ID_INSTANCE")
436
- WEBHOOK_AUTH_TOKEN = os.getenv("WEBHOOK_AUTH_TOKEN")
437
- BOT_STATUS_CHAT = "[email protected]" # Chat ID for system messages
438
- image_dir = "/tmp/images"
439
- audio_dir = "/tmp/audio"
440
-
441
- if not all([GREEN_API_URL, GREEN_API_TOKEN, GREEN_API_ID_INSTANCE, WEBHOOK_AUTH_TOKEN]):
442
- raise ValueError("Environment variables are not set properly")
443
-
444
- # Queues & in‑memory stores
445
- task_queue = queue.Queue()
446
- trivia_store = {} # chat_id β†’ {"question":…, "answer":…}
447
- polls = {} # chat_id β†’ {"question":…, "options":[…], "votes":{1:0…}, "voters":{jid:opt}}
448
-
449
- app = FastAPI()
450
-
451
- # Global inactivity tracker
452
- last_message_time = time.time()
453
-
454
- # --- Inactivity Monitor ---
455
- def inactivity_monitor():
456
- global last_message_time
457
- while True:
458
- time.sleep(60) # check every minute
459
- if time.time() - last_message_time >= 300: # 5 minutes inactivity
460
- if BOT_STATUS_CHAT:
461
- reminder = "⏰ I haven't heard from you in a while! I'm still here if you need anything."
462
- send_message("inactivity", BOT_STATUS_CHAT, reminder)
463
- last_message_time = time.time()
464
-
465
- threading.Thread(target=inactivity_monitor, daemon=True).start()
466
-
467
- # --- Background Worker ---
468
- def worker():
469
- while True:
470
- task = task_queue.get()
471
- try:
472
- typ = task["type"]
473
- mid = task["message_id"]
474
- cid = task["chat_id"]
475
- if typ == "image":
476
- handle_image_generation(mid, cid, task["prompt"])
477
- elif typ == "audio":
478
- response_audio(mid, cid, task["prompt"])
479
- except Exception as e:
480
- logging.error(f"Error processing {task}: {e}")
481
- finally:
482
- task_queue.task_done()
483
-
484
- threading.Thread(target=worker, daemon=True).start()
485
-
486
- # --- send helpers ---
487
- def send_message(message_id, to_number, message, retries=3):
488
- chat_id = to_number if to_number.endswith("@g.us") else to_number
489
- url = f"{GREEN_API_URL}/waInstance{GREEN_API_ID_INSTANCE}/sendMessage/{GREEN_API_TOKEN}"
490
- payload = {"chatId": chat_id, "message": message, "quotedMessageId": message_id}
491
- for i in range(retries):
492
- try:
493
- r = requests.post(url, json=payload)
494
- r.raise_for_status()
495
- return r.json()
496
- except requests.RequestException as e:
497
- if i == retries - 1:
498
- return {"error": str(e)}
499
-
500
- def send_image(message_id, to_number, image_path, caption="Here you go!", retries=3):
501
- chat_id = to_number if to_number.endswith("@g.us") else to_number
502
- url = f"{GREEN_API_MEDIA_URL}/waInstance{GREEN_API_ID_INSTANCE}/sendFileByUpload/{GREEN_API_TOKEN}"
503
- payload = {"chatId": chat_id, "caption": caption, "quotedMessageId": message_id}
504
- files = [("file", ("image.jpg", open(image_path, "rb"), "image/jpeg"))]
505
- for i in range(retries):
506
- try:
507
- r = requests.post(url, data=payload, files=files)
508
- r.raise_for_status()
509
- return r.json()
510
- except requests.RequestException as e:
511
- if i == retries - 1:
512
- return {"error": str(e)}
513
-
514
- def send_audio(message_id, to_number, audio_path, retries=3):
515
- logging.debug("send_audio")
516
- chat_id = to_number if to_number.endswith("@g.us") else to_number
517
- if not os.path.exists(audio_path):
518
- logging.debug(f"Missing audio: {audio_path}")
519
- url = f"{GREEN_API_MEDIA_URL}/waInstance{GREEN_API_ID_INSTANCE}/sendFileByUpload/{GREEN_API_TOKEN}"
520
- payload = {"chatId": chat_id, "caption": "Here is your voice reply!", "quotedMessageId": message_id}
521
- try:
522
- with open(audio_path, "rb") as f:
523
- files = [("file", ("audio.mp3", f, "audio/mpeg"))]
524
- for i in range(retries):
525
- try:
526
- r = requests.post(url, data=payload, files=files)
527
- r.raise_for_status()
528
- return r.json()
529
- except requests.RequestException as e:
530
- if i == retries - 1:
531
- return {"error": str(e)}
532
- except Exception as e:
533
- return {"error": str(e)}
534
-
535
- # --- core response functions ---
536
- def response_text(message_id, chat_id, prompt):
537
- try:
538
- msg = generate_llm(prompt)
539
- send_message(message_id, chat_id, msg)
540
- except Exception:
541
- send_message(message_id, chat_id, "Error processing your request.")
542
-
543
- def response_audio(message_id, chat_id, prompt):
544
- logging.debug("response_audio prompt=%s", prompt)
545
- try:
546
- result = generate_voice_reply(prompt, model="openai-audio", voice="coral", audio_dir=audio_dir)
547
- if result and result[0]:
548
- audio_path, _ = result
549
- send_audio(message_id, chat_id, audio_path)
550
- if os.path.exists(audio_path):
551
- os.remove(audio_path)
552
- else:
553
- response_text(message_id, chat_id, prompt)
554
- except Exception as e:
555
- logging.debug("audio error: %s", e)
556
- send_message(message_id, chat_id, "Error generating audio. Try again later.")
557
-
558
- def handle_image_generation(message_id, chat_id, prompt):
559
- try:
560
- img, path, ret_prompt, url = generate_image(prompt, message_id, message_id, image_dir)
561
- if img:
562
- formatted_ret_prompt = "\n\n".join(
563
- f"_{paragraph.strip()}_" for paragraph in ret_prompt.split("\n\n") if paragraph.strip()
564
- )
565
- send_image(
566
- message_id,
567
- chat_id,
568
- path,
569
- caption=f"✨ Image ready: {url}\n>{chr(8203)} {formatted_ret_prompt}"
570
- )
571
- else:
572
- send_message(message_id, chat_id, "Image generation failed.")
573
- except Exception as e:
574
- logging.error("Error in handle_image_generation: %s", e)
575
- send_message(message_id, chat_id, "Error generating image.")
576
 
577
  # --- Webhook ---
578
  @app.post("/whatsapp")
@@ -630,7 +242,7 @@ async def whatsapp_webhook(request: Request):
630
  "β€’ `/weather <location>` – Get the current weather for a location.\n"
631
  "β€’ `/inspire` – Receive a short inspirational quote.\n"
632
  "β€’ `/trivia` – Start a new trivia question.\n"
633
- "β€’ `/answer` – Reveal the trivia answer.\n"
634
  "β€’ `/meme <text>` – Generate a fun meme image.\n"
635
  "β€’ `/poll <Question>|<Option1>|<Option2>|…` – Create a poll.\n"
636
  "β€’ `/results` – See current poll results.\n"
@@ -681,10 +293,11 @@ async def whatsapp_webhook(request: Request):
681
 
682
  # TRIVIA
683
  if low == "/trivia":
 
684
  raw = generate_llm(
685
- "Generate a unique and random trivia question and answer in JSON format. "
686
- "The output should strictly follow this example format without extra text:\n\n"
687
- "{\"question\": \"What is the capital of France?\", \"answer\": \"Paris\"}"
688
  )
689
  def extract_json(text):
690
  import re
@@ -697,7 +310,7 @@ async def whatsapp_webhook(request: Request):
697
  obj = json.loads(json_text)
698
  if "question" in obj and "answer" in obj:
699
  trivia_store[chat] = obj
700
- send_message(mid, chat, f"❓ {obj['question']}\nReply with `/answer` to see the answer.")
701
  else:
702
  raise ValueError("Missing expected keys.")
703
  except Exception as e:
@@ -705,11 +318,26 @@ async def whatsapp_webhook(request: Request):
705
  send_message(mid, chat, "Failed to generate trivia. Please try again.")
706
  return {"success": True}
707
 
708
- # ANSWER: Accept any message starting with /answer
709
  if low.startswith("/answer"):
 
 
710
  if chat in trivia_store:
711
- ans = trivia_store.pop(chat)["answer"]
712
- send_message(mid, chat, f"πŸ’‘ Answer: {ans}")
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  else:
714
  send_message(mid, chat, "No active trivia. Send `/trivia` to start one.")
715
  return {"success": True}
 
17
  logging.basicConfig(level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s")
18
 
19
  # Env vars
20
+ GREEN_API_URL = os.getenv("GREEN_API_URL")
21
+ GREEN_API_MEDIA_URL = os.getenv("GREEN_API_MEDIA_URL", "https://api.green-api.com")
22
+ GREEN_API_TOKEN = os.getenv("GREEN_API_TOKEN")
23
+ GREEN_API_ID_INSTANCE = os.getenv("GREEN_API_ID_INSTANCE")
24
+ WEBHOOK_AUTH_TOKEN = os.getenv("WEBHOOK_AUTH_TOKEN")
25
+ BOT_STATUS_CHAT = "[email protected]" # Chat ID for system messages
26
+ image_dir = "/tmp/images"
27
+ audio_dir = "/tmp/audio"
28
 
29
  if not all([GREEN_API_URL, GREEN_API_TOKEN, GREEN_API_ID_INSTANCE, WEBHOOK_AUTH_TOKEN]):
30
  raise ValueError("Environment variables are not set properly")
 
32
  # Queues & in‑memory stores
33
  task_queue = queue.Queue()
34
  trivia_store = {} # chat_id β†’ {"question":…, "answer":…}
35
+ polls = {} # chat_id β†’ {"question":…, "options": […], "votes": {1: 0, ...}, "voters": {jid: opt}}
36
 
37
  app = FastAPI()
38
 
 
83
  return r.json()
84
  except requests.RequestException as e:
85
  if i == retries - 1:
86
+ logging.error("send_message_to_chat failed: %s", str(e))
87
  return {"error": str(e)}
88
 
89
  def send_message(message_id, to_number, message, retries=3):
 
176
  logging.error("Error in handle_image_generation: %s", e)
177
  send_message(message_id, chat_id, "Error generating image.")
178
 
179
+ # --- Startup Message ---
180
+ def send_startup_message():
181
+ if BOT_STATUS_CHAT:
182
+ startup_msg = "🌟 Hi! I'm Eve, your friendly AI assistant. I'm now live and ready to help with images, voice replies, and more!"
183
+ resp = send_message_to_chat(BOT_STATUS_CHAT, startup_msg)
184
+ if "error" in resp:
185
+ logging.error("Startup message failed: %s", resp["error"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  else:
187
+ logging.warning("BOT_STATUS_CHAT is not set; startup message not sent.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
  # --- Webhook ---
190
  @app.post("/whatsapp")
 
242
  "β€’ `/weather <location>` – Get the current weather for a location.\n"
243
  "β€’ `/inspire` – Receive a short inspirational quote.\n"
244
  "β€’ `/trivia` – Start a new trivia question.\n"
245
+ "β€’ `/answer [your answer]` – Reveal the trivia answer or check your answer if provided.\n"
246
  "β€’ `/meme <text>` – Generate a fun meme image.\n"
247
  "β€’ `/poll <Question>|<Option1>|<Option2>|…` – Create a poll.\n"
248
  "β€’ `/results` – See current poll results.\n"
 
293
 
294
  # TRIVIA
295
  if low == "/trivia":
296
+ randomSeed = random.randint(0, 9999999)
297
  raw = generate_llm(
298
+ (f"Generate a unique and random trivia question and answer based on this random seed {randomSeed} to make it unique in JSON format. "
299
+ "The output should strictly follow this example format without extra text:\n\n"
300
+ "{\"question\": \"What is the capital of France?\", \"answer\": \"Paris\"}")
301
  )
302
  def extract_json(text):
303
  import re
 
310
  obj = json.loads(json_text)
311
  if "question" in obj and "answer" in obj:
312
  trivia_store[chat] = obj
313
+ send_message(mid, chat, f"❓ {obj['question']}\nReply with `/answer` followed by your answer (if you want to check it) or just `/answer` to reveal the correct answer.")
314
  else:
315
  raise ValueError("Missing expected keys.")
316
  except Exception as e:
 
318
  send_message(mid, chat, "Failed to generate trivia. Please try again.")
319
  return {"success": True}
320
 
321
+ # ANSWER: Accept any message starting with /answer. If additional text is provided, check it.
322
  if low.startswith("/answer"):
323
+ # Remove command and any extra spaces
324
+ user_response = body[len("/answer"):].strip()
325
  if chat in trivia_store:
326
+ correct_answer = trivia_store[chat]["answer"]
327
+ question = trivia_store[chat]["question"]
328
+ # If user provided an answer, evaluate it via LLM; otherwise, just reveal the answer.
329
+ if user_response:
330
+ eval_prompt = (
331
+ f"Question: {question}\n"
332
+ f"Correct Answer: {correct_answer}\n"
333
+ f"User Answer: {user_response}\n"
334
+ "Is the user's answer correct? Respond with 'Correct' if yes, or 'Incorrect' if not, and explain briefly."
335
+ )
336
+ verdict = generate_llm(eval_prompt)
337
+ send_message(mid, chat, f"πŸ’‘ {verdict}")
338
+ else:
339
+ send_message(mid, chat, f"πŸ’‘ Answer: {correct_answer}")
340
+ trivia_store.pop(chat, None)
341
  else:
342
  send_message(mid, chat, "No active trivia. Send `/trivia` to start one.")
343
  return {"success": True}
polLLM.py CHANGED
@@ -22,7 +22,7 @@ def generate_llm(prompt):
22
  # Build the GET request URL for Pollinations' text API
23
  randomSeed = random.randint(0, 9999999)
24
  print(f"DEBUG: Random seed: {randomSeed}")
25
- url = f"https://text.pollinations.ai/{encoded_prompt}?model=openai-large&seed={randomSeed}&private=true&system={encoded_system}"
26
 
27
  try:
28
  response = requests.get(url, timeout=30)
 
22
  # Build the GET request URL for Pollinations' text API
23
  randomSeed = random.randint(0, 9999999)
24
  print(f"DEBUG: Random seed: {randomSeed}")
25
+ url = f"https://text.pollinations.ai/{encoded_prompt}?model=openai-large&private=true&system={encoded_system}&seed={randomSeed}"
26
 
27
  try:
28
  response = requests.get(url, timeout=30)