ISSUE ===== When using the manual webhook message feature via API, the following error occurred: - 'Timeout context manager should be used inside a task' - 'NoneType' object is not iterable (when sending without files) The error happened because Discord.py's webhook operations were being awaited directly in the FastAPI endpoint context, rather than within a task running in the bot's event loop. SOLUTION ======== Refactored /manual/send-webhook endpoint to properly handle async operations: 1. Moved webhook creation inside task function - get_or_create_webhooks_for_channel() now runs in send_webhook_message() - All Discord operations (webhook selection, sending) happen inside the task - Follows same pattern as working /manual/send endpoint 2. Fixed file parameter handling - Changed from 'files=discord_files if discord_files else None' - To conditional: only pass files parameter when list is non-empty - Discord.py's webhook.send() cannot iterate over None, requires list or omit 3. Maintained proper file reading - File content still read in endpoint context (before form closes) - File data passed to task as pre-read byte arrays - Prevents form closure issues TECHNICAL DETAILS ================= - Discord.py HTTP operations use timeout context managers - Context managers must run inside bot's event loop (via create_task) - FastAPI endpoint context is separate from bot's event loop - Solution: Wrap all Discord API calls in async task function - Pattern: Read files → Create task → Task handles Discord operations TESTING ======= - Manual webhook sending now works without timeout errors - Both personas (Miku/Evil) send correctly - File attachments work properly - Messages without files send correctly
90 KiB
90 KiB