FELIPE WINSCHFull Stack Developer
Back to projects

Automation · Asynchronous messaging

Moodle Messaging Bot

A Python service processing a PostgreSQL queue to send messages to UFSC Moodle. It coordinates authentication, session recovery and optional Gemini replies.

Prototype

  • Python
  • asyncio
  • HTTPX
  • PostgreSQL
  • asyncpg
  • Gemini

My contribution

A project maintained by felpzw: the reviewed scope combines CAS authentication, asynchronous workers, queue persistence and optional AI integration. Public history also records a Copilot contribution, so it does not support an exclusive-authorship claim.

Problem

Separate message creation from Moodle delivery with a persistent queue and recovery from authenticated-session expiry. Optionally, a monitored conversation can trigger AI replies.

Context and scope

The service targets UFSC’s in-person Moodle installation and its CAS flow. It is not a generic connector for all Moodle installations. Without a configured conversation, it processes the existing queue and maintains the session; automatic replies require additional configuration.

Architecture

bot.py organizes authentication and dispatch, reader and keep-alive workers with asyncio. HTTPX maintains the HTTP session; asyncpg accesses a queue with PENDING, SENT and FAILED states.

The reader polls the latest message in the configured conversation. When enabled, AI.py calls Gemini and places the reply into the same outgoing queue. The dispatcher splits long text into chunks before sending it through Moodle AJAX endpoints.

  1. PostgreSQL · pending-message queue
  2. asyncio dispatcher · CAS / Moodle session
  3. AJAX endpoints · delivery and status update
The optional Gemini reader also writes to the queue; delivery is not guaranteed to be exactly once.

Decisions and trade-offs

The relational queue preserves content and delivery status across restarts, but selecting pending messages neither locks nor claims rows for concurrent workers. The current design assumes one process per queue.

Using the web session follows the target Moodle implementation at the cost of depending on cookies, sesskey and CAS details. These consequences are inferred from the code and documented boundaries.

Tests and evidence

Review covered workers, the SQL schema and documentation. No automated suite was found in the reviewed inventory. Future tests should simulate session expiry, failure after partial delivery and concurrent messages; no login, Gemini calls or real message delivery occurred in this review.

Limitations

There is no exactly-once delivery guarantee or automatic retry of FAILED rows. The reader fetches only the latest message per cycle and can miss messages in a busy conversation.

Python dependency versions are not pinned. With AI enabled, incoming text is sent to Gemini; the queue stores content, and logs can include message excerpts. The project requires authorized conversation access and environment-specific configuration.

Explore the project

Start with the queue schema, then follow dispatcher_loop, reader_loop and send_message in bot.py. The guide explains local configuration and session recovery.

The commands below only prepare the Python environment and check syntax. For an authorized run, the README covers PostgreSQL, environment variables and python bot.py. TEST_CONTENT can enqueue a message on every startup; leave it unset when only preparing the environment.

python3 -m venv .venv
. .venv/bin/activate
python -m pip install httpx asyncpg beautifulsoup4 python-dotenv google-genai
python -m py_compile bot.py AI.py

Sources checked on 2026-09-27 · Content v1 · Revision 36f3358.