AccelByte Discord Integration is an Extend Service Extension app that integrates Discord with AccelByte Gaming Services (AGS). It enables account linking, role synchronization, leaderboards, and session/party creation through Discord slash commands.
- Go to Discord Developer Portal
- Click New Application and give it a name
- From General Information, copy:
- Application ID →
DISCORD_CLIENT_ID - Public Key →
DISCORD_PUBLIC_KEY
- Application ID →
- Go to OAuth2 > General, copy:
- Client Secret →
DISCORD_CLIENT_SECRET
- Client Secret →
- Under Redirects, add your callback URL:
- Local:
http://localhost:8000/discord/link/callback - Production (default
BASE_PATH=/discord):<Service URL>/discord/link/callback(see note below) - If you changed
BASE_PATH, use<Service URL><BASE_PATH>/link/callback
- Local:
- Go to Bot, click Add Bot, then:
- Click Reset Token and copy →
DISCORD_BOT_TOKEN - Enable Server Members Intent (required for role sync)
- Click Reset Token and copy →
- Invite the bot to your server:
- Go to OAuth2 > URL Generator
- Select scopes:
bot,applications.commands - Select permissions:
Manage Roles,Send Messages - Open the generated URL and add to your server
- Copy your Server ID (right-click server → Copy Server ID) →
DISCORD_GUILD_ID
- Log in to AGS Admin Portal
- Go to Game Setup > IAM Clients
- Create a new Confidential client
| Resource | Permissions |
|---|---|
ADMIN:NAMESPACE:{namespace}:USER |
Read |
ADMIN:NAMESPACE:{namespace}:USER:* |
Read, Update |
ADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORD |
Create, Read, Update, Delete |
ADMIN:NAMESPACE:{namespace}:USER:*:STATITEM |
Create, Read, Update |
ADMIN:NAMESPACE:{namespace}:LEADERBOARD |
Read |
ADMIN:NAMESPACE:{namespace}:USER:*:LEADERBOARD |
Read |
ADMIN:NAMESPACE:{namespace}:STATITEM |
Read |
NAMESPACE:{namespace}:SESSION:GAME |
Create, Read, Update |
ADMIN:NAMESPACE:{namespace}:SESSION:PARTY |
Read |
| Permission | Read | Create | Update | Delete |
|---|---|---|---|---|
| Cloud Save > Game Records | ✓ | ✓ | ✓ | ✓ |
| Cloud Save > Player Records | ✓ | ✓ | ✓ | ✓ |
| IAM > Users | ✓ | ✓ | ||
| Leaderboard > Leaderboard Configuration and Data | ✓ | |||
| Leaderboard > User Visibility | ✓ | ✓ | ||
| Platform Store > Entitlement | ✓ | ✓ | ||
| Session > Game Session | ✓ | ✓ | ✓ | |
| Session > Party | ✓ | |||
| Statistics > User's Statistics Value | ✓ |
- Copy:
- Client ID →
AB_CLIENT_ID - Client Secret →
AB_CLIENT_SECRET
- Client ID →
Copy .env.template to .env and fill in your values:
# AccelByte
AB_BASE_URL=https://demo.accelbyte.io # Your AGS environment
AB_NAMESPACE=mygame # Your namespace
AB_CLIENT_ID=xxxxxxxx # From Step 2
AB_CLIENT_SECRET=xxxxxxxx # From Step 2
# Discord
DISCORD_PUBLIC_KEY=xxxxxxxx # From Step 1.3
DISCORD_GUILD_ID=123456789012345678 # From Step 1.8
DISCORD_BOT_TOKEN=xxxxxxxx # From Step 1.6
DISCORD_CLIENT_ID=123456789012345678 # From Step 1.3
DISCORD_CLIENT_SECRET=xxxxxxxx # From Step 1.4
DISCORD_REDIRECT_URI=http://localhost:8000/discord/link/callback
DISCORD_STATE_SECRET=change-this-to-random-string
# Admin (optional for local dev)
ADMIN_AUTH_DISABLED=true
# For production: set STUDIO_ADMIN_ROLE_ID (see docs/admin-panel.md for how to find it)
# STUDIO_ADMIN_ROLE_ID=xxxxxxxxdocker compose up --buildThe service will be available at:
- Swagger UI: http://localhost:8000/discord/apidocs/
- Admin Panel: http://localhost:8000/discord/admin/
Register commands with Discord using the bot token:
curl -X PUT "https://discord.com/api/v10/applications/${DISCORD_CLIENT_ID}/guilds/${DISCORD_GUILD_ID}/commands" \
-H "Authorization: Bot ${DISCORD_BOT_TOKEN}" \
-H "Content-Type: application/json" \
-d '[
{"name": "link", "description": "Link your Discord account to your game account"},
{"name": "sync-role", "description": "Sync your Discord roles with your game data"},
{"name": "rank", "description": "Check leaderboard ranking", "options": [
{"name": "me", "description": "Check your own ranking", "type": 1},
{"name": "user", "description": "Check another user ranking", "type": 1, "options": [
{"name": "target", "description": "User to check", "type": 6, "required": true}
]}
]},
{"name": "versus", "description": "Challenge someone to 1v1", "options": [
{"name": "opponent", "description": "User to challenge", "type": 6, "required": true}
]},
{"name": "match", "description": "Create a match (admin only)", "default_member_permissions": "0", "options": [
{"name": "user1", "description": "Player 1", "type": 6, "required": true},
{"name": "user2", "description": "Player 2", "type": 6, "required": true},
{"name": "user3", "description": "Player 3", "type": 6},
{"name": "user4", "description": "Player 4", "type": 6},
{"name": "user5", "description": "Player 5", "type": 6},
{"name": "user6", "description": "Player 6", "type": 6},
{"name": "user7", "description": "Player 7", "type": 6},
{"name": "user8", "description": "Player 8", "type": 6},
{"name": "user9", "description": "Player 9", "type": 6},
{"name": "user10", "description": "Player 10", "type": 6}
]},
{"name": "party", "description": "Party-related commands", "options": [
{"name": "create", "description": "Create a party and invite other players", "type": 1, "options": [
{"name": "member1", "description": "First party member", "type": 6, "required": true},
{"name": "member2", "description": "Second party member", "type": 6},
{"name": "member3", "description": "Third party member", "type": 6},
{"name": "member4", "description": "Fourth party member", "type": 6},
{"name": "member5", "description": "Fifth party member", "type": 6},
{"name": "member6", "description": "Sixth party member", "type": 6},
{"name": "member7", "description": "Seventh party member", "type": 6},
{"name": "member8", "description": "Eighth party member", "type": 6},
{"name": "member9", "description": "Ninth party member", "type": 6},
{"name": "member10", "description": "Tenth party member", "type": 6}
]},
{"name": "join", "description": "Join a user's current party", "type": 1, "options": [
{"name": "user", "description": "User whose party you want to join", "type": 6, "required": true}
]},
{"name": "leave", "description": "Leave your current party", "type": 1},
{"name": "kick", "description": "Kick a user from your party (Leader only)", "type": 1, "options": [
{"name": "user", "description": "User to kick from your party", "type": 6, "required": true}
]},
{"name": "invite", "description": "Invite a user to your current party (Leader only)", "type": 1, "options": [
{"name": "user", "description": "User to invite to your party", "type": 6, "required": true}
]}
]}
]'For local development, use a tunnel like ngrok:
ngrok http 8000Then in Discord Developer Portal:
- Go to your application > General Information
- Set Interactions Endpoint URL to:
https://<ngrok-url>/discord/interactions - Discord will verify the endpoint before saving
- Go to your Discord server
- Run
/linkto test account linking - Complete the OAuth flow
- Run
/sync-roleto test role synchronization
Note for AGS Shared Cloud: The
/linkcommand requires the service to be deployed to AGS. Running locally will result in CORS errors during the OAuth callback. Other commands like/sync-role,/rank,/versus,/match, and/party create|join|leave|kick|invitework locally.
Finding your Service URL: In AGS Admin Portal, go to Extend > Service Extension > select your app. The Service URL is displayed on the app details page.
- Configure role mappings in the Admin Panel
- Set up deployment to AGS
- Review all configuration options
| Document | Description |
|---|---|
| Architecture | System design and component overview |
| Configuration | All environment variables and CloudSave config |
| Development | Local development workflow |
| Deployment | Deploying to AGS |
| Admin Panel | Admin panel features |
| Command | Description |
|---|---|
| /link | Link Discord account to AGS account |
| /sync-role | Sync Discord roles based on AGS data |
| /rank | Display leaderboard ranking |
| /versus | Challenge another user to 1v1 |
| /match | Admin-only multi-user match creation |
| /party create | Create an AGS party and invite users from Discord |
| /party join, /party leave, /party kick, /party invite | Join, leave, invite, and manage party members (leader-only kick/invite) |
| /clan request-discord-sync | Request Discord role sync for your clan (leader only) |
| /tournament | Tournament management — list, register, brackets, and admin lifecycle |
