Version 2: Using Discord Status to Automate Break Detection — n8n & Oracle APEX

APEX n8n Discord Automation

Efficient Time Tracking with Auto Break Room Switcher: Discord Status, n8n & Oracle APEX

How we made breaks fully automatic — no buttons, no commands, just Discord status.

📅 June 2026 👤 Sajjad Hanifa ⏱ ~10 min read 🏢 S&H Software Solutions

In our first article we built a fully automated time tracking system where employees simply join and leave a Discord voice channel — no manual entries, no extra apps. It worked great. But one thing was still missing: breaks.

When someone steps away from their desk, they stay in the voice channel. The system keeps counting those minutes as working time. Over a month, that adds up fast. We needed a smarter solution — and it turned out Discord already had the signal we needed: the user status.

💡
First time here? The initial setup — Docker, n8n, Oracle DB schema, and the APEX dashboard — is fully covered in Part 1. This article focuses on the new break detection layer.

The Idea: Discord Status as a Break Signal

Every Discord user has a status: online, idle, or offline. When someone locks their computer or walks away, Discord automatically switches their status. That's our break trigger — no habit change required.

Here's the full flow:

JOIN — Employee enters any voice channel → work session starts
LEAVE_BREAK — Status changes to idle / offline while in a work channel → bot moves them to Break Room, break timer starts
BREAK_RETURN — Status returns to online while in Break Room → bot moves them back to their last work channel, break ends
LEAVE — Employee leaves the voice channel completely → work session ends
MOVE — Employee switches between work channels → tracked, no session change

The bot remembers which work channel each person was in before their break, and moves them back to exactly that channel when they return.

The Stack

ComponentTechnologyRole
BOT Discord BotNode.js 20 · Discord.js v14Listens to voice & presence events, moves users automatically
N8N Workflown8n · Docker · PortainerReceives webhook events, writes to Oracle DB, sends WhatsApp notifications
DB DatabaseOracle Database · PL/SQLStores all JOIN/LEAVE/BREAK events with timestamps
UI DashboardOracle APEXVisualizes working hours, breaks, and monthly calendar

Step 01
1
Deploy the Bot via Portainer Stack
node:20-alpine · Docker Compose · No separate build needed

The entire bot runs as a single Docker container deployed through a Portainer Stack. The Node.js application is written inline inside the docker-compose.yml — no Dockerfile, no image to push, no extra files. Just deploy the stack and it runs.

Portainer Stack — discord-voice-listener-planora running
Portainer Stack view — the container running with three environment variables

You only need three environment variables:

DISCORD_BOT_TOKEN — your bot token from the Discord Developer Portal
N8N_WEBHOOK_URL — the webhook URL of your n8n workflow
PAUSE_CHANNEL_ID — the Discord channel ID of your Break Room

Download the docker-compose.yml and paste it into your Portainer Stack editor:

📄
docker-compose.yml
Docker Compose Stack — Node.js Discord Bot with inline JS · All credentials as env vars (placeholders)
⚠️
Two things worth understanding in this code:
The autoMovedUsers and autoReturnedUsers sets prevent infinite loops — when the bot moves a user, that triggers a new voiceStateUpdate event. Without these guards, the bot would react to its own moves.

The lastWorkChannelByUser map remembers each user's last work channel so the bot can return them to exactly the right place after a break.

Step 02
2
The n8n Workflow
Webhook · Switch · Oracle DB · WhatsApp Notifications

The n8n workflow receives every event from the bot via a single webhook and routes them through a Switch node based on the event_type field. Each branch handles one event type: JOIN, LEAVE, LEAVE_BREAK, BREAK_RETURN, and MOVE.

n8n Workflow — Switch node routing all Discord events
One webhook, Switch node in the center, each branch handles a different event type

Each branch fetches the user from Oracle DB, looks up their parameters, then calls a PL/SQL stored procedure to persist the event. After that, a WhatsApp notification fires via WaAPI — managers get an instant message every time someone goes on break or returns.

One special node: check_if_go_offline. When a user goes fully offline, Discord fires both a presenceUpdate and a voiceStateUpdate event. This node ensures we don't count that as two separate work events.

n8n Execution History — every event under 2 seconds
Execution history — every event processes in under 2 seconds end-to-end

Import this n8n workflow directly via Workflows → Import from file:

⚙️
01_discord_in_out_status_only_save_db.json
n8n Workflow JSON — Webhook → Switch → Oracle DB → WhatsApp · All credentials sanitized

Step 03
3
Oracle APEX Dashboard — Planora
PL/SQL Dynamic Content · Bar Chart · Year Calendar

Nothing changed on the APEX side — the same dashboard from Part 1 now has cleaner, more accurate data. Break time is properly excluded from working hours, so the numbers actually reflect productive work time.

Oracle APEX Planora Dashboard — working hours with break-aware tracking
The Planora dashboard — bar chart, status cards, and full-year calendar. Break time excluded automatically.
🟢 Green — 8h+ target reached
🟠 Orange — 4–8h partial day
🔴 Red — under 4h
Gray — no login / day off
Result: Working hours are now accurate. AFK time is automatically separated from productive work time — without anyone pressing a single button.

Final Thoughts

The biggest win here isn't the technology — it's the zero behavior change required from employees. They don't click "Start Break." They don't type a command. They just lock their computer when they step away. Discord status does the rest.

For us, this eliminated the biggest data quality problem in our time tracking: inflated working hours from forgotten AFK sessions. The numbers are now reliable, and managers don't need to manually review or adjust anything.

Next up: a manual override slash command for edge cases where status detection isn't accurate enough. We'll cover that in a future post.

SH
Sajjad Hanifa
Software Developer · S&H Software Solutions · Oracle APEX, n8n, Discord Automation
Oracle APEX PL/SQL n8n Discord Automation Time Tracking Docker Node.js

 {fullWidth}

Please Select Embedded Mode To Show The Comment System.*

Previous Post Next Post

نموذج الاتصال