Skip to main content

Usage & Setup

How It Works​

The Job Time Tracker monitors player job changes and automatically:

  1. Tracks when a player switches to a tracked job
  2. Logs the session duration in the database
  3. Sends webhooks to Discord with player and time information
  4. Generates reports at configured times (daily/weekly)

Getting Started​

Step 1: Enable Debug Mode (Optional)​

While setting up, enable debug mode in shared/config.lua:

Config.Debug = true

This shows detailed console logs to help verify the system is working.

Step 2: Configure Your Jobs​

Edit shared/config.lua and add the jobs you want to track:

Config.TrackedJobs = {
ambulance = "EMS",
police = "POLICE",
mechanic = "MECHANIC",
}

Make sure the keys match your database job names exactly (case-sensitive).

Step 3: Set Up Webhooks​

For each tracked job, add webhook URLs in shared/webhook.lua:

Webhooks.join = {
ambulance = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN",
police = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN",
mechanic = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN",
}

Webhooks.daily = {
ambulance = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN",
police = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN",
mechanic = "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN",
}

Step 4: Test​

  1. Restart the resource:

    refresh
    start cfx_job_time_tracker
  2. Check console for startup messages:

    [Vice JobTime] ESX LOADED
    [JobTime] Config and Webhooks loaded
  3. In-game test:

    • Have a test player change to a tracked job
    • Check Discord for a join notification
    • Have the player leave the job
    • Verify the webhook is sent with the correct time

Webhook Messages​

Join/Leave Format​

When a player starts or stops working:

đŸŸĸ Started Work - Ambulance

Player: TestPlayer
Status: Started working

When stopping:

🔴 Ended Work - Ambulance

Player: TestPlayer
Work Time: 15 minutes 30 seconds

Daily Report Format​

At the configured daily time:

📊 Daily Report - Ambulance

Period: 2024-01-15 → 2024-01-15

Player | Time
TestPlayer | 1 hour 30 minutes
OtherPlayer | 2 hours 15 minutes

Weekly Report Format​

At the configured weekly time:

📊 Weekly Report - Ambulance

Period: 2024-01-08 → 2024-01-14

Player | Time
TestPlayer | 8 hours 30 minutes
OtherPlayer | 7 hours 45 minutes
AnotherPlayer | 5 hours 10 minutes

Features in Detail​

Real-Time Tracking​

The system tracks active jobs using framework events:

  • ESX: esx:playerLoaded, esx:setJob, esx:updateJob
  • QBCore: QBCore:Client:OnPlayerLoaded, QBCore:Client:OnJobUpdate

Changes are detected within seconds.

info

A polling fallback also runs every 5 seconds to catch missed job changes.

State Persistence​

On resource restart, the system:

  1. Checks if the player is in a tracked job
  2. Restores tracking state without sending a webhook
  3. Continues normal operation

This prevents duplicate notifications on server restarts.

Network Resilience​

If a player disconnects:

  • Tracking stops automatically
  • Webhook is sent with final time
  • Session is logged to database

If they reconnect:

  • System detects the new job
  • Tracking resumes normally
tip

The system monitors network connection status continuously. If it detects a lost session, it cleans up automatically.


Language Support​

Switching Languages​

Change the language in shared/config.lua:

Config.Locale = "en" -- English
Config.Locale = "sl" -- Slovenian

Adding New Languages​

  1. Create a new file in locales/ folder (e.g., de.lua for German)
  2. Copy the structure from locales/en.lua
  3. Translate all strings
  4. Reference it in fxmanifest.lua:
server_scripts {
'locales/en.lua',
'locales/sl.lua',
'locales/de.lua', -- Add your language
}
  1. Set it in config:
Config.Locale = "de"

Debugging Tips​

Enable Debug Mode​

Config.Debug = true

Watch the console for messages like:

[JobTime DEBUG] Starting tracking for job: ambulance
[JobTime DEBUG] Stopping tracking for job: ambulance
[JobTime DEBUG] Job changed from: police to: ambulance

Check if Job is Tracked​

Add this to debug output:

-- Job not being tracked?
-- Verify: Config.TrackedJobs contains the exact job name (case-sensitive)
-- Compare database job name with config

Verify Webhooks​

  1. Make sure webhook URLs are correct and accessible
  2. Check Discord channel permissions (bot should have write access)
  3. In debug mode, webhooks will print status to console
  4. Test by manually changing jobs in-game

Database Issues​

If reports aren't generating:

  1. Verify oxmysql is running
  2. Check database connection
  3. Ensure the job is in Config.TrackedJobs
  4. Look for SQL errors in console
tip

If you need more help, enable Config.Debug = true and check the full console output. Most issues are configuration-related.


Common Issues​

"Job not being tracked"​

Solution: Verify the job name in Config.TrackedJobs matches your database exactly (including capitalization).

"Webhooks not sending"​

Solution:

  1. Check webhook URL format
  2. Verify Discord bot has permissions on the target channel
  3. Enable debug mode and check for error messages
  4. Test with a fresh job change

"Reports not generating at configured time"​

Solution:

  1. Verify Config.ReportTimes is set correctly (24-hour format)
  2. Check server is running at report time
  3. Verify at least one tracked job session exists for the period
  4. Check Discord webhook permissions

"State not syncing after restart"​

Solution: This is normal behavior. The system intentionally skips webhooks on restart to avoid duplicates. Check console with debug enabled to verify state was restored.


Performance​

The system is optimized for low resource usage:

  • Minimal database queries (only on job changes)
  • Efficient event handling (no polling unless necessary)
  • Lightweight webhook processing
  • Network-aware disconnection handling

Suitable for servers with hundreds of concurrent players.

success

You're all set! The Job Time Tracker is ready for production use.