Clubmate AI is a Discord bot + dashboard for student clubs.
It provides:
- Discord slash-command assistant powered by Gemini
- Google Calendar / Docs / Sheets / Forms actions via MCP tools
- RAG knowledge base (file + Google Doc ingestion)
- Meeting voice recording, transcription, and summary posting
- Web dashboard for admin configuration and Google connection
This repo runs 3 services:
bot: Discord bot (python -m bot.main)api: FastAPI backend (http://localhost:8000)frontend: Next.js dashboard (http://localhost:3000)
The recommended way to run is Docker Compose.
Install:
- Docker Desktop + Docker Compose
- A Discord application + bot token
- A Gemini API key
- A Google Cloud project (for Calendar/Docs/Sheets/Forms OAuth)
From project root:
cp .env.example .env
cp frontend/.env.local.example frontend/.env.localSet values in .env:
DISCORD_TOKENDISCORD_CLIENT_IDDISCORD_CLIENT_SECRETDISCORD_GUILD_IDGEMINI_API_KEYAPI_SECRET_KEY(generate a strong random value)
Optional but recommended:
EXEC_ROLE_NAME(defaultExecutive)MEETING_SUMMARY_CHANNEL_IDWHISPER_MODE(localorapi)OPENAI_API_KEY(only ifWHISPER_MODE=api)
Set values in frontend/.env.local:
NEXTAUTH_SECRETNEXTAUTH_URL=http://localhost:3000DISCORD_CLIENT_ID(same as root.env)DISCORD_CLIENT_SECRET(same as root.env)NEXT_PUBLIC_API_URL=http://localhost:8000
In Discord Developer Portal:
- Open your application.
- Add OAuth redirect URI:
http://localhost:3000/api/auth/callback/discord
- Enable required bot permissions in your server.
- Invite the bot to the target server (
DISCORD_GUILD_ID).
In Google Cloud Console for the same project:
- Enable APIs:
- Google Calendar API
- Google Docs API
- Google Sheets API
- Google Forms API
- Google Drive API
- Configure OAuth consent screen:
- User type: External (or Internal for Workspace)
- Publishing status: Testing is fine for development
- Add your account as a Test User
- Create OAuth Client ID:
- Application type: Web application
- Authorized redirect URI:
http://localhost:8000/google/callback
- Authorized JavaScript origins: optional for this backend callback flow
- Use the dashboard Google page to upload credentials JSON and complete auth.
docker compose up -d --buildCheck health:
curl http://localhost:8000/healthOpen dashboard:
http://localhost:3000
- Sign in with Discord (must have Manage Server/Admin in target guild).
- Go to Settings and verify API keys/config.
- Go to Google page:
- Upload OAuth credentials JSON
- Click connect and finish OAuth
- Go to Knowledge Base:
- Upload files or sync Google Doc
/ask/events(today by default, or pass date)/rooms/clear/help
/schedule,/cancel-meeting,/reschedule,/invite/day-schedule,/cancel-day,/reschedule-day,/invite-day/create-doc,/create-form,/form-responses,/read-sheet/ingest,/kb-reset/meeting start,/meeting end
- Database path:
data/chroma_db - Google Doc ingestion requires Google account connection and Docs API enabled
- If chunk count is
0, document may be empty, inaccessible, or too short
WHISPER_MODE=local: uses local Whisper model in containerWHISPER_MODE=api: uses OpenAI Whisper API- Summaries are posted to the meeting summary channel
Your Gemini key was revoked. Create a new key and update GEMINI_API_KEY.
Add your account under OAuth consent screen Test Users.
Restart OAuth from dashboard and complete in one browser session.
Enable Google Docs API in the same Google Cloud project used by OAuth credentials.
Check:
- API is healthy:
curl http://localhost:8000/health NEXT_PUBLIC_API_URLpoints tohttp://localhost:8000- Discord OAuth vars are set in
frontend/.env.local
docker compose restart api bot frontenddocker compose downNever commit:
.envdata/google_credentials.jsondata/google_token.json
If any secret was exposed, rotate it immediately.