""" Medications command handler - bot-side hooks for medication management """ import asyncio from bot.command_registry import register_module import ai.parser as ai_parser async def handle_medication(message, session, parsed): action = parsed.get("action", "unknown") token = session["token"] user_uuid = session["user_uuid"] if action == "list": resp, status = api_request("get", "/api/medications", token) if status == 200: meds = resp if isinstance(resp, list) else [] if not meds: await message.channel.send("You don't have any medications yet.") else: lines = [f"- **{m['name']}**: {m['dosage']} {m['unit']} ({m.get('frequency', 'n/a')})" for m in meds] await message.channel.send("**Your medications:**\n" + "\n".join(lines)) else: await message.channel.send(f"Error: {resp.get('error', 'Failed to fetch medications')}") elif action == "add": name = parsed.get("name") dosage = parsed.get("dosage") unit = parsed.get("unit", "mg") frequency = parsed.get("frequency", "daily") times = parsed.get("times", ["08:00"]) if not name or not dosage: await message.channel.send("Please provide medication name and dosage.") return data = {"name": name, "dosage": dosage, "unit": unit, "frequency": frequency, "times": times} resp, status = api_request("post", "/api/medications", token, data) if status == 201: await message.channel.send(f"Added **{name}** to your medications!") else: await message.channel.send(f"Error: {resp.get('error', 'Failed to add medication')}") elif action == "take": med_id = parsed.get("medication_id") if not med_id: await message.channel.send("Which medication did you take?") return resp, status = api_request("post", f"/api/medications/{med_id}/take", token, {}) if status == 201: await message.channel.send("Logged it! Great job staying on track.") else: await message.channel.send(f"Error: {resp.get('error', 'Failed to log')}") elif action == "skip": med_id = parsed.get("medication_id") reason = parsed.get("reason", "Skipped by user") if not med_id: await message.channel.send("Which medication are you skipping?") return resp, status = api_request("post", f"/api/medications/{med_id}/skip", token, {"reason": reason}) if status == 201: await message.channel.send("OK, noted.") else: await message.channel.send(f"Error: {resp.get('error', 'Failed to log')}") elif action == "adherence": med_id = parsed.get("medication_id") if med_id: resp, status = api_request("get", f"/api/medications/{med_id}/adherence", token) else: resp, status = api_request("get", "/api/medications/adherence", token) if status == 200: if isinstance(resp, list): lines = [f"- {m['name']}: {m['adherence_percent']}% adherence" for m in resp] await message.channel.send("**Adherence:**\n" + "\n".join(lines)) else: await message.channel.send(f"**{resp.get('name')}**: {resp.get('adherence_percent')}% adherence") else: await message.channel.send(f"Error: {resp.get('error', 'Failed to fetch adherence')}") else: await message.channel.send(f"Unknown action: {action}. Try: list, add, take, skip, or adherence.") def api_request(method, endpoint, token, data=None): import requests import os API_URL = os.getenv("API_URL", "http://app:5000") url = f"{API_URL}{endpoint}" headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"} try: resp = getattr(requests, method)(url, headers=headers, json=data, timeout=10) try: return resp.json(), resp.status_code except ValueError: return {}, resp.status_code except requests.RequestException: return {"error": "API unavailable"}, 503 def validate_medication_json(data): errors = [] if not isinstance(data, dict): return ["Response must be a JSON object"] if "error" in data: return [] if "action" not in data: errors.append("Missing required field: action") return errors register_module("medication", handle_medication) ai_parser.register_validator("medication", validate_medication_json)