Spaces:
Running
Running
Chandima Prabhath
commited on
Commit
·
1fbbc17
1
Parent(s):
a9740d0
Refactor BotConfig validation to include BOT_JID; improve help text formatting and clarity in command descriptions.
Browse files
app.py
CHANGED
@@ -16,24 +16,28 @@ from polLLM import generate_llm
|
|
16 |
# --- Configuration and Client Classes ---
|
17 |
|
18 |
class BotConfig:
|
19 |
-
GREEN_API_URL
|
20 |
-
GREEN_API_MEDIA_URL
|
21 |
-
GREEN_API_TOKEN
|
22 |
-
GREEN_API_ID_INSTANCE
|
23 |
-
WEBHOOK_AUTH_TOKEN
|
24 |
-
BOT_GROUP_CHAT
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
28 |
|
29 |
@classmethod
|
30 |
def validate(cls):
|
31 |
-
missing = [
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
37 |
if missing:
|
38 |
raise ValueError(f"Environment variables not set: {', '.join(missing)}")
|
39 |
|
@@ -147,14 +151,10 @@ def handle_image_generation(task):
|
|
147 |
prompt = task["prompt"]
|
148 |
count = task.get("num_images", BotConfig.DEFAULT_IMAGE_COUNT)
|
149 |
|
150 |
-
# simple loop: one generate_image call per image
|
151 |
for i in range(1, count + 1):
|
152 |
try:
|
153 |
img, path, ret_prompt, url = generate_image(
|
154 |
-
prompt,
|
155 |
-
message_id,
|
156 |
-
message_id,
|
157 |
-
BotConfig.IMAGE_DIR
|
158 |
)
|
159 |
if not img:
|
160 |
raise RuntimeError("generate_image returned no image")
|
@@ -179,23 +179,22 @@ send_startup_message()
|
|
179 |
# --- FastAPI App & Webhook ---
|
180 |
|
181 |
app = FastAPI()
|
|
|
182 |
help_text = (
|
183 |
"🤖 *Hi there, I'm Eve!* Here are the commands you can use:\n\n"
|
184 |
-
"• */help* –
|
185 |
-
"• */
|
186 |
-
"• */
|
187 |
-
"• */
|
188 |
-
"• */
|
189 |
-
"• */
|
190 |
-
"• */
|
191 |
-
"• */
|
192 |
-
"• */
|
193 |
-
"• */meme <text
|
194 |
-
"• */poll Q
|
195 |
-
"
|
196 |
-
"
|
197 |
-
"• */gen <prompt>|<count>* – _Generate images (default 4)._ \n\n"
|
198 |
-
"Any other text → I'll send you a voice reply!"
|
199 |
)
|
200 |
|
201 |
@app.post("/whatsapp")
|
@@ -207,34 +206,49 @@ async def whatsapp_webhook(request: Request):
|
|
207 |
if request.headers.get("Authorization") != f"Bearer {BotConfig.WEBHOOK_AUTH_TOKEN}":
|
208 |
raise HTTPException(403, "Unauthorized")
|
209 |
|
210 |
-
data
|
211 |
chat_id = data.get("senderData", {}).get("chatId")
|
212 |
if chat_id != BotConfig.BOT_GROUP_CHAT or data.get("typeWebhook") != "incomingMessageReceived":
|
213 |
return {"success": True}
|
214 |
|
215 |
-
md
|
216 |
-
mid
|
217 |
-
|
218 |
-
# Extract text + context
|
219 |
text_data = md.get("textMessageData") or md.get("extendedTextMessageData")
|
220 |
if not text_data:
|
221 |
return {"success": True}
|
|
|
222 |
body = text_data.get("textMessage", text_data.get("text", "")).strip()
|
223 |
ctx = text_data.get("contextInfo", {})
|
224 |
|
225 |
-
#
|
226 |
-
if ctx.get("quotedMessageId")
|
227 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
return {"success": True}
|
229 |
|
230 |
-
# Skip
|
231 |
if ctx.get("mentionedJidList"):
|
232 |
-
logging.debug("Skipping mention")
|
233 |
return {"success": True}
|
234 |
|
235 |
low = body.lower()
|
236 |
|
237 |
-
# --- COMMANDS ---
|
238 |
if low == "/help":
|
239 |
client.send_message(mid, chat_id, help_text)
|
240 |
return {"success": True}
|
|
|
16 |
# --- Configuration and Client Classes ---
|
17 |
|
18 |
class BotConfig:
|
19 |
+
GREEN_API_URL = os.getenv("GREEN_API_URL")
|
20 |
+
GREEN_API_MEDIA_URL = os.getenv("GREEN_API_MEDIA_URL", "https://api.green-api.com")
|
21 |
+
GREEN_API_TOKEN = os.getenv("GREEN_API_TOKEN")
|
22 |
+
GREEN_API_ID_INSTANCE = os.getenv("GREEN_API_ID_INSTANCE")
|
23 |
+
WEBHOOK_AUTH_TOKEN = os.getenv("WEBHOOK_AUTH_TOKEN")
|
24 |
+
BOT_GROUP_CHAT = "[email protected]"
|
25 |
+
BOT_JID = os.getenv("BOT_JID") # e.g. "[email protected]"
|
26 |
+
IMAGE_DIR = "/tmp/images"
|
27 |
+
AUDIO_DIR = "/tmp/audio"
|
28 |
+
DEFAULT_IMAGE_COUNT = 4
|
29 |
|
30 |
@classmethod
|
31 |
def validate(cls):
|
32 |
+
missing = [
|
33 |
+
name for name in (
|
34 |
+
"GREEN_API_URL",
|
35 |
+
"GREEN_API_TOKEN",
|
36 |
+
"GREEN_API_ID_INSTANCE",
|
37 |
+
"WEBHOOK_AUTH_TOKEN",
|
38 |
+
"BOT_JID",
|
39 |
+
) if not getattr(cls, name)
|
40 |
+
]
|
41 |
if missing:
|
42 |
raise ValueError(f"Environment variables not set: {', '.join(missing)}")
|
43 |
|
|
|
151 |
prompt = task["prompt"]
|
152 |
count = task.get("num_images", BotConfig.DEFAULT_IMAGE_COUNT)
|
153 |
|
|
|
154 |
for i in range(1, count + 1):
|
155 |
try:
|
156 |
img, path, ret_prompt, url = generate_image(
|
157 |
+
prompt, message_id, message_id, BotConfig.IMAGE_DIR
|
|
|
|
|
|
|
158 |
)
|
159 |
if not img:
|
160 |
raise RuntimeError("generate_image returned no image")
|
|
|
179 |
# --- FastAPI App & Webhook ---
|
180 |
|
181 |
app = FastAPI()
|
182 |
+
|
183 |
help_text = (
|
184 |
"🤖 *Hi there, I'm Eve!* Here are the commands you can use:\n\n"
|
185 |
+
"• */help* – list commands\n"
|
186 |
+
"• */gen <prompt>|<count>* – generate images (default 4)\n"
|
187 |
+
"• */summarize <text>*\n"
|
188 |
+
"• */translate <lang>|<text>*\n"
|
189 |
+
"• */joke*\n"
|
190 |
+
"• */weather <location>*\n"
|
191 |
+
"• */weatherpoem <location>*\n"
|
192 |
+
"• */inspire*\n"
|
193 |
+
"• */trivia* / *answer*\n"
|
194 |
+
"• */meme <text>*\n"
|
195 |
+
"• */poll <Q>|<opt1>|… / /results / /endpoll*\n\n"
|
196 |
+
"Reply to one of my messages → I'll LLM‑answer it.\n"
|
197 |
+
"Any other text → voice reply."
|
|
|
|
|
198 |
)
|
199 |
|
200 |
@app.post("/whatsapp")
|
|
|
206 |
if request.headers.get("Authorization") != f"Bearer {BotConfig.WEBHOOK_AUTH_TOKEN}":
|
207 |
raise HTTPException(403, "Unauthorized")
|
208 |
|
209 |
+
data = await request.json()
|
210 |
chat_id = data.get("senderData", {}).get("chatId")
|
211 |
if chat_id != BotConfig.BOT_GROUP_CHAT or data.get("typeWebhook") != "incomingMessageReceived":
|
212 |
return {"success": True}
|
213 |
|
214 |
+
md = data.get("messageData", {})
|
215 |
+
mid = data["idMessage"]
|
|
|
|
|
216 |
text_data = md.get("textMessageData") or md.get("extendedTextMessageData")
|
217 |
if not text_data:
|
218 |
return {"success": True}
|
219 |
+
|
220 |
body = text_data.get("textMessage", text_data.get("text", "")).strip()
|
221 |
ctx = text_data.get("contextInfo", {})
|
222 |
|
223 |
+
# --- Quoted‑reply handling ---
|
224 |
+
if ctx.get("quotedMessageId"):
|
225 |
+
# only if the quoted message was sent by our bot
|
226 |
+
quoted_sender = ctx.get("participant") or ctx.get("quotedMessageSender")
|
227 |
+
if quoted_sender == BotConfig.BOT_JID:
|
228 |
+
# extract quoted text
|
229 |
+
qm = ctx.get("quotedMessage", {})
|
230 |
+
if "textMessageData" in qm:
|
231 |
+
quoted_text = qm["textMessageData"].get("textMessage", "")
|
232 |
+
else:
|
233 |
+
quoted_text = qm.get("extendedTextMessageData", {}).get("text", "")
|
234 |
+
# build and send LLM reply
|
235 |
+
prompt = (
|
236 |
+
f"You asked: {quoted_text}\n"
|
237 |
+
f"User replied: {body}\n"
|
238 |
+
"Provide a helpful, concise follow‑up."
|
239 |
+
)
|
240 |
+
reply = generate_llm(prompt)
|
241 |
+
client.send_message(mid, chat_id, reply)
|
242 |
+
# in either case, do not process further
|
243 |
return {"success": True}
|
244 |
|
245 |
+
# --- Skip @‑mentions of others ---
|
246 |
if ctx.get("mentionedJidList"):
|
|
|
247 |
return {"success": True}
|
248 |
|
249 |
low = body.lower()
|
250 |
|
251 |
+
# --- COMMANDS (unchanged) ---
|
252 |
if low == "/help":
|
253 |
client.send_message(mid, chat_id, help_text)
|
254 |
return {"success": True}
|