Discord bot, backend, dashboard, and SLM workspace for incoming university student support.
All credentials and local runtime settings live in .env. The file is ignored by Git. Use .env-example as the template for future machines.
cp .env-example .envRequired secret values:
POSTGRES_PASSWORDDISCORD_BOT_TOKEN
The bot also reads BACKEND_URL and defaults to http://localhost:8080. The Discord application ID and server ID are copied from Discord during setup; they are not runtime secrets.
Open the repository in VS Code and reopen it in the devcontainer. The devcontainer starts:
so-workspace: .NET, Git, GitHub CLI, Java, Python, Node/TypeScript, Next.js, React tooling, PostgreSQL client tools, and VS Code extensions.so-db: PostgreSQL 16 Alpine on port5432.
The repository is mounted at /workspaces/friday.
The devcontainer compose publishes service ports directly and connects both services through the so-network bridge network. Named volumes keep backend/bin, webapp/node_modules, and webapp/.next inside Docker volumes. Lifecycle scripts in .devcontainer/scripts install the PostgreSQL client and curl on create, then fix volume permissions on start.
From the repository root:
docker compose --env-file .env -f infra/docker-compose.yml upServices:
db: PostgreSQL 16 Alpine, initialized fromdatabase/schema.sql.app: C# backend and Next.js dashboard.
Default local URLs:
- Backend:
http://localhost:8080 - Webapp:
http://localhost:3000
The Java Discord bot and Python SLM are not services in the runtime Compose file and must be started separately when needed.
Backend:
dotnet run --project backendBot:
mvn -f bot/pom.xml package
BACKEND_URL=http://localhost:8080 java -jar bot/target/friday-bot-0.1.0-SNAPSHOT.jarSLM:
uvicorn slm.main:app --host 0.0.0.0 --port 8090Webapp:
npm install --prefix webapp
npm run dev --prefix webappFriday must know about a server before the bot can synchronize its roles. Complete the steps below in order.
- Create an application in the Discord Developer Portal, open its Bot page, and create or reset the bot token.
- Enable the Server Members Intent and Message Content Intent privileged gateway intents. The bot uses both when handling member and message events.
- In OAuth2 > URL Generator, select the
botandapplications.commandsscopes. Grant these bot permissions:- View Channels
- Send Messages
- Embed Links
- Attach Files
- Read Message History
- Manage Messages
- Manage Roles
- Manage Nicknames
- Open the generated URL and add the bot to the target server.
- Put the token in
.envasDISCORD_BOT_TOKEN. Never commit or share this token.
The bot's Discord role must be above every role Friday will grant. It must also be above the students whose nicknames it will update.
Create the roles before synchronizing the server. Friday uses the exact role names below for administration; roster roles can use any Discord role synchronized from the server.
| Role | Purpose |
|---|---|
Administrator |
Authorizes the first /assistant service:sync command. Give this role to the operator performing setup. |
Bot Developer |
Authorizes later assistant administration commands. |
Moderator |
Required with Bot Developer when publishing the verification prompt. |
| Roster roles | One or more synchronized Discord roles selected for each uploaded group. |
Prepa, INEL, ICOM, INSO, and CIIC roles are not required and are never assigned automatically. To grant one of them, select it explicitly in Team Setup like any other roster role. The Bot Developer lookup accepts spaces, hyphens, or underscores. Keep the bot's role above all roles it needs to assign.
Start the database, backend, and dashboard:
docker compose --env-file .env -f infra/docker-compose.yml upIn a second terminal, build and start the bot:
mvn -f bot/pom.xml package
BACKEND_URL=http://localhost:8080 java -jar bot/target/friday-bot-0.1.0-SNAPSHOT.jarWait for the bot to appear online. On startup it registers the global and server-specific slash commands.
- In Discord, enable User Settings > Advanced > Developer Mode. Right-click the server and select Copy Server ID.
- Open
http://localhost:3000, find Discord servers, and select Add server. - Enter the server name, paste the Discord server ID, select the owning department, and select Add server. New servers are active by default.
- In Discord, run
/assistant service:syncas a member with theAdministratorrole. - Confirm that the private response says
Synchronized N roles.Open View server in the dashboard and verify that the uploaded-group role selector contains the Discord roles.
Run the sync command again whenever Discord roles are added, renamed, deleted, recolored, or reordered. If the bot says the server is not registered, confirm that the dashboard's Discord ID exactly matches the copied server ID.
The dashboard accepts CSV files only and auto-detects these layouts:
| Layout | Expected columns |
|---|---|
Lista_EO.csv |
email, first_name, first_last_name, second_last_name, and initial |
LISTA DE PREPAS |
Father Last Name, Mother Last Name, Name, Initial, and Institutional Account; the older seven-column NOMBRE export is also accepted |
Extra columns are ignored. Rows without a first name, first surname, or usable email are skipped. Check the parsed student count before continuing and treat roster files as sensitive student data.
- In the dashboard, select View server for the synchronized server.
- Under Student list and team setup, upload the roster. The complete roster workflow is on the server page; there is no separate roster page.
- Choose between 2 and 12 teams, select Balanced or Randomized, and select Generate teams.
- Use the pencil button on every team to configure it:
- Keep Create a new team enabled and enter a name, or disable it to update an existing backend team.
- Select at least one synchronized Discord role for the current uploaded group. The roles are assigned directly to those uploaded users; the team does not store roles.
- When updating an existing team, Append members is enabled by default so repeated CSV imports retain current members. Turn it off only to replace that team’s stored membership.
- Select Edit groups to move students between teams. Every student must be assigned before the distribution can be saved.
- Select Save team distribution.
Saving imports the students and assigns only the Discord roles selected for each uploaded group. Teams store membership only. Re-imported users keep their existing roles and gain newly selected roles; users omitted from a later CSV are not changed, even when team membership is replaced.
Roster upload does not immediately change Discord members. It stores direct user-role assignments that Friday grants when each student verifies their email.
- Copy the ID of the text channel that should contain the verification prompt.
- Run
/assistant-verification channel:<channel-id>as a member with theAdministratoror synchronizedBot Developerrole. - Confirm that the bot publishes the verification embed. This command requires synchronized
ModeratorandBot Developerroles and permission to send messages and embeds in the selected channel. - Each student selects verify and enters the email stored from the roster. When the email matches, Friday links the Discord account, updates the student's nickname, and grants every Discord role assigned directly to that user.
If verification succeeds but roles are not granted, confirm that the bot has Manage Roles and that its highest role is above all assigned roles. If a synchronized role is later changed in Discord, run /assistant service:sync again before changing or importing the roster.
| Command | Description |
|---|---|
/calendario |
Links to the academic calendar of UPRM. |
/estudiante-orientador |
Lists all EO's in the server by department. |
/rules |
Lists server rules. |
/guia-prepistica |
Provides a PDF guide on prepas. |
/faculty |
Displays detailed information about faculty members. |
/ls_projects |
Provides information on ongoing projects and research. |
/ls_student_orgs |
Lists student organizations and their activities. |
/salon |
Finds a building on campus based on its code. |
/lab |
Finds a lab on campus based on its code. |
/links |
Provides useful links related to studies and resources. |
/made-web |
Links to the MADE (Media Arts and Digital Entertainment) website. |
/contact-dcsp |
Provides information about the Department of Computer Science and Engineering. |
/contact-department |
Displays information about specific departments at UPRM. |
/contact-decanato-estudiantes |
Provides contact information for the Dean of Students. |
/contact-guardia-univ |
Provides contact information for campus security. |
/contact-asesoria-academica |
Provides guidance on academic matters and advisories. |
/contact-asistencia-economica |
Provides information about financial aid and economic assistance. |
/curriculo |
Provides general information about academic curricula. |
/guia-prepistica |
Provides a guide for incoming freshmen. |
/faq |
Answers frequently asked questions about the Discord server. |
/help |
Displays a comprehensive help menu for navigating the bot's commands. |
/map |
Provides a link to the UPRM campus map. |
/rules |
Displays the rules and guidelines for the Discord server. |