A feature-rich Discord bot that tracks and displays Arc Raiders map rotation conditions across all five maps (Dam, Buried City, Spaceport, Blue Gate, and Stella Montis) with automatic hourly updates, interactive navigation, and visual map generation.
You can invite Arc Raiders Discord Bot to any Discord server using this link:
Add Arc Raiders Bot to your server
How to use after inviting:
- Invite the bot using the link above and authorize it for your server.
- Run the setup wizard by using the
/setupslash command. This guided wizard will help you configure:- Your preferred language
- The channel for map rotation updates
- Notification method (pin & edit, hourly post, etc.)
- Display format (desktop or mobile-optimized)
- The bot will automatically post and update the Arc Raiders map rotation status every hour in the designated channel.
Alternative setup: You can also use individual commands:
/set-channel- Set the update channel/settings- Configure locale, mobile-friendly mode, and notification method
- Automatic Map Rotation Tracking: Updates every hour with current and next map conditions
- Pinned Status Message: Creates and maintains a pinned message with rich embed formatting
- UTC Schedule: Follows the official Arc Raiders 24-hour UTC rotation schedule
- Visual Map Generation: Generates beautiful map images with event overlays using Puppeteer
- Persistent State: Remembers message IDs and settings across bot restarts
- Interactive Navigation: Navigate through maps and events using button controls
- Event Filtering: View all maps, filter by major events, or filter by minor events
- Interaction Priority System: 15-second exclusive interaction locks to prevent conflicts
- Mobile-Friendly Mode: Optimized single-column layout for mobile devices
- Live Countdown: Real-time countdown to next rotation
Tracks conditions across all 5 maps:
- Dam
- Buried City
- Spaceport
- Blue Gate
- Stella Montis
The bot tracks these condition types across all maps:
- Harvester - High-value target
- Night - Darkness conditions
- Husks - Enemy encounters
- Blooms - Lush vegetation
- Storm - Electrical hazards
- Tower - Space tower loot
- Bunker - Bunker access
- Matriarch - Boss encounter
- Caches - Loot caches
- Probes - Probe spawns
- None - No active events
- Docker and Docker Compose (for Docker installation)
- OR Node.js 24.x or higher (for manual installation)
- A Discord Bot Token from Discord Developer Portal
- Supabase project URL and Service Role key (used for persisting server/message metadata)
The easiest way to run the bot is using Docker. Pre-built multi-architecture images are available on GitHub Container Registry.
-
Create a
.envfile with your configuration:DISCORD_TOKEN=your_bot_token_here CLIENT_ID=your_client_id_here SUPABASE_URL=https://your-project.supabase.co SUPABASE_SERVICE_ROLE_KEY=your_service_role_key LOG_LEVEL=info PORT=6767
-
Create a
docker-compose.ymlfile:version: '3.8' services: arc-raiders-bot: image: ghcr.io/zfael/arc-raiders-discord-bot:latest container_name: arc-raiders-discord-bot restart: unless-stopped env_file: - .env ports: - "6767:6767" environment: - TZ=UTC
-
Start the bot:
docker-compose up -d
-
View logs:
docker-compose logs -f
-
Stop the bot:
docker-compose down
Alternatively, run directly with Docker:
docker run -d \
--name arc-raiders-discord-bot \
--restart unless-stopped \
-p 6767:6767 \
--env-file .env \
ghcr.io/zfael/arc-raiders-discord-bot:latestlatest- Latest stable release from main branchv1.0.0- Specific version tagsmain- Latest commit on main branch (may be unstable)
Images are built for both:
linux/amd64(x86_64 / Intel/AMD)linux/arm64(ARM64 / Apple Silicon / Raspberry Pi)
Docker will automatically pull the correct architecture for your system.
If you prefer to run without Docker:
-
Clone the repository
git clone <repository-url> cd arc-raiders-discord-bot
-
Install dependencies
npm install
-
Configure environment variables
Copy
.env.exampleto.env:cp .env.example .env
Edit
.envand fill in your values:DISCORD_TOKEN=your_bot_token_here CLIENT_ID=your_client_id_here SUPABASE_URL=https://your-project.supabase.co SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
- Go to Discord Developer Portal
- Click "New Application" and give it a name
- Go to the "Bot" section and click "Add Bot"
- Copy the bot token (this is your
DISCORD_TOKEN) - Enable these Privileged Gateway Intents:
- Presence Intent
- Server Members Intent
- Message Content Intent
- Go to your application's "Emojis" section in the Developer Portal
- Upload the emoji images from
src/assets/directory:harvester.pngnightraid.pnghusks.pnglush.png(for Blooms)electro.png(for Storm)cache.pngprobe.pngspacetower_loot.png(for Tower)bunker.pngmatriarch.png
- Copy each emoji ID and update
CONDITION_EMOJISinsrc/config/mapRotation.ts
The bot requires these permissions (permission integer: 274877925376):
- ✅ Send Messages
- ✅ Embed Links
- ✅ Manage Messages (for pinning)
- ✅ Read Message History
- ✅ Attach Files (for map images)
- Go to OAuth2 > URL Generator in the Developer Portal
- Select scopes:
botandapplications.commands - Select the permissions listed above
- Copy the generated URL and open it in your browser
- Select your server and authorize the bot
- Client ID: Found in the "General Information" section of your application.
Run the bot with hot reloading using ts-node:
npm run devBefore first run or after adding new commands, deploy them:
npm run deploy-commandsThis registers commands globally, which can take up to an hour to propagate to all servers.
-
Build the TypeScript code:
npm run build
-
Start the bot:
npm start
/ping- Check bot latency and responsiveness/setup- (Admin-only) Guided setup wizard to configure the bot for your server/set-channel- (Admin-only) Sets the channel where map rotation updates are posted/settings- (Admin-only) Configure locale, mobile-friendly mode, and notification method
The bot's map rotation message includes interactive buttons:
- 🏠 Home - Return to overview of all maps
- 🗺️ View Map - See visual map with event overlays
- ⚔️ Major Events - Filter to show only major events
- 📦 Minor Events - Filter to show only minor events
- When you click a button, you gain exclusive control for 15 seconds
- Other users will see an ephemeral message if they try to interact during this time
- After 15 seconds of inactivity, the message automatically returns to the home screen
- The message becomes available for anyone to interact with again
All persistent state is stored in Supabase:
| Column | Type | Description |
|---|---|---|
guild_id |
text (PK) | Discord server ID |
channel_id |
text | Channel for map updates |
server_name |
text | Server name for logging |
message_id |
text | ID of pinned message |
last_updated |
text | Last update timestamp |
mobile_friendly |
boolean | Mobile-friendly mode setting |
created_at |
timestamptz | Row creation time |
updated_at |
timestamptz | Last modification time |
The bot automatically manages this table. You can back up or inspect it directly in the Supabase dashboard. Deleting rows is safe; the bot will recreate them as needed.
-
Create the required table (run once in the Supabase SQL editor):
create table if not exists public.servers ( guild_id text primary key, channel_id text not null, server_name text, message_id text, last_updated text, mobile_friendly boolean default false, locale text default 'en', created_at timestamptz default timezone('utc', now()), updated_at timestamptz default timezone('utc', now()) );
-
(Optional) Enable Row Level Security and add permissive policies if you plan to use the anon key. The bot uses the
SUPABASE_SERVICE_ROLE_KEY, so it can bypass policies by default. -
Add
SUPABASE_URLandSUPABASE_SERVICE_ROLE_KEYto your.env, matching the values in the Supabase dashboard.
- Startup: Bot logs in and immediately posts/updates the map rotation status
- Scheduling: A cron job runs at the top of every hour (UTC) to update all server messages
- Updates: The bot fetches current and next rotation from the 24-hour schedule
- Reads the stored
message_idfor each channel from Supabase - Edits the existing pinned message or creates/pins a new one when needed
- Writes the latest
message_id/last_updatedback to Supabase - Generates visual map images on-demand using Puppeteer
- Button interactions are handled in
interactionCreate.ts - Interaction locks prevent multiple users from conflicting
- Locks expire after 15 seconds, reverting to home screen
- Ephemeral messages notify blocked users
Because configuration and message metadata live in Supabase, the bot resumes seamlessly after restarts.
The bot generates beautiful map images using:
- Puppeteer: Headless browser for HTML rendering
- HTML Templates: Custom templates with CSS styling
- Base Map: High-resolution map image (2690x1515px)
- Event Overlays: Dynamic markers showing active events at each location
- Forecast Cards: Upcoming rotation preview
Map coordinates are percentage-based for responsive scaling.
- Make sure you ran
npm run deploy-commands - Check that the bot has proper permissions in the server
- Global commands can take up to an hour to update after being deployed
- Use the
/set-channelcommand to designate a channel for updates - Check the bot has "Send Messages", "Embed Links", "Attach Files", and "Manage Messages" permissions in the designated channel
- Look at the bot's console logs for any error messages
- Ensure Puppeteer dependencies are installed (may require additional system packages on Linux)
- Check that
src/assets/map.pngexists and is readable - Verify sufficient disk space and memory for image generation
- Ensure the bot has "Read Message History" permission
- Check console logs for interaction errors
- Verify the message hasn't been deleted or unpinned
- Run
npm installto ensure all dependencies are installed - Check that Node.js version is 18.x or higher
- Run
npm run lintto check for code issues
- Verify all required environment variables are set in
.env - Check that the Discord token is valid
- Ensure the bot is invited to the server
- Verify Supabase credentials are correct
This project uses Biome.js for linting and formatting:
npm run lint # Check for issues
npm run lint:fix # Auto-fix issuesnpm run build # Compile TypeScript and copy assetsThe build process:
- Compiles TypeScript to JavaScript in
dist/ - Copies
templates/andassets/todist/
MIT
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch
- Make your changes
- Run
npm run lint:fixto format code - Test your changes thoroughly
- Submit a pull request
Questions or Issues? Open an issue on GitHub or join the discussion!