This project provides a Node.js bot to integrate Discord linked roles with an XAuthConnect authorization server. It allows users to link their Minecraft (XAuthConnect) account to their Discord profile, displaying their XAuth username as a linked role connection.
- Discord Linked Roles Integration: Connects user's XAuthConnect account to their Discord profile.
- XAuth Username Display: Shows the XAuth username in Discord's linked roles section.
- Rate Limit Handling: Implements retry mechanisms for Discord API requests to gracefully handle rate limits.
- Localization Support: Discord command descriptions are localized, with support for multiple languages (e.g., English, Ukrainian). Easily extendable to other languages by adding new locale files.
- Database Storage: Stores linked user data (Discord ID, XAuth ID, tokens) in a PostgreSQL database.
- Interactive CLI: Manage the bot with commands directly from the console.
- Automated Pruning: Remove linked users who are no longer in the Discord server.
- Metadata Refresh: Update existing linked role metadata for all users.
The application exposes the following routes:
GET /: Displays the main page of the application. Can also display status messages (success, error, access denied) based onstatusquery parameter (e.g.,/?status=success).GET /start: Initiates the account linking process. This redirects the user to Discord for authorization.POST /discord/interactions: The endpoint for receiving Discord interactions (e.g., slash commands).GET /discord/callback: The redirect URI for Discord OAuth2. Handles the authorization code exchange and redirects to/with a status.GET /xauth/callback: The redirect URI for XAuthConnect OAuth2. Handles the authorization code exchange and links the accounts, then redirects to/with a status.
- Node.js (v18 or higher recommended)
- PostgreSQL database
- A Discord Application (for OAuth2, Bot, and Interactions)
- An XAuthConnect Authorization Server
To begin, you will need to retrieve the project's source code, install all necessary dependencies, and then proceed to the configuration phase where all the Discord, XAuth, and database connection details are specified in the appropriate files:
-
Clone the repository:
git clone https://github.com/newlandpe/discord-xauth-integration.git cd discord-xauth-integration -
Install dependencies:
npm install
-
Configure Environment Variables (
.envfile): Create a.envfile in the project root based on.env.example.# Discord OAuth2 Redirect URI (must match your Discord Application settings) REDIRECT_URI=http://localhost:3000/discord/callback # Server Port PORT=3000 # PostgreSQL Database Connection DB_HOST=localhost DB_USER=your_db_user DB_PASSWORD=your_db_password DB_DATABASE=your_db_nameImportant: The
REDIRECT_URImust exactly match the one configured in your Discord Application's OAuth2 settings. -
Configure Application (
config.jsonfile): Create aconfig.jsonfile in the project root based onconfig.json.example. This file defines your application credentials and settings.{ "platformName": "XAuthConnect", "discord": { "clientId": "YOUR_DISCORD_CLIENT_ID", "clientSecret": "YOUR_DISCORD_CLIENT_SECRET", "guildId": "YOUR_DISCORD_GUILD_ID", "botToken": "YOUR_DISCORD_BOT_TOKEN", "publicKey": "YOUR_DISCORD_APPLICATION_PUBLIC_KEY" }, "xauth": { "clientId": "YOUR_XAUTH_CLIENT_ID", "clientSecret": "YOUR_XAUTH_CLIENT_SECRET", "redirectUri": "http://localhost:3000/xauth/callback", "authorizationUrl": "http://xauth-server.com/xauth/authorize", "tokenUrl": "http://xauth-server.com/xauth/token", "userinfoUrl": "http://xauth-server.com/xauth/user", "scopes": ["profile:uuid", "profile:nickname"] } }platformName: The name that will be displayed in the user's Discord profile under the "Connections" section.discord.clientId,discord.clientSecret: Obtained from your Discord Application's OAuth2 settings.discord.guildId: The ID of the Discord server (guild) where the bot operates. Required for theprunecommand. See How to get Guild ID.discord.botToken: The token for your Discord bot. Ensure your bot has theGUILD_MEMBERS_READprivileged intent enabled in the Discord Developer Portal for theprunecommand to work.discord.publicKey: The public key for your Discord Application, used for verifying interaction signatures. Obtain this from your Discord Application's General Information page.xauth.*: Credentials and URLs for your XAuthConnect Authorization Server.
Note on Redirect URIs:
- The
REDIRECT_URIin your.envfile is the callback URL for your Discord Application's OAuth2 flow, pointing back to your bot. - The
xauth.redirectUriinconfig.jsonis the redirect URI that your XAuthConnect Authorization Server uses to send users back to your bot after successful authentication. Ensure both are correctly configured and match their respective application settings.
For the bot to function correctly, especially for features like prune and handling interactions, you need to configure specific permissions and enable certain Privileged Gateway Intents in your Discord Developer Portal.
Required Permissions (for your bot role in Discord):
Send Messages(for basic command responses)Use Slash Commands(for interacting with slash commands)
Required Privileged Gateway Intents (in Discord Developer Portal -> Your Application -> Bot -> Privileged Gateway Intents):
GUILD_MEMBERS_READ: Required for theprunecommand to check if users are still in the guild. Without this, theprunecommand will not work correctly.
Ensure these are properly configured to avoid unexpected behavior.
To get the ID of a Discord server (guild), you need to enable Developer Mode in your Discord client:
-
Enable Developer Mode:
- Go to User Settings > Advanced.
- Turn on "Developer Mode".
-
Copy the Guild ID:
- Right-click on the server icon in the server list.
- Click "Copy Server ID".
After a successful installation and configuration, you can start the bot, register its slash commands, and use the interactive CLI for management:
-
Start the bot (server and Discord client): To start the HTTP server and bring the Discord bot online, use:
node app.js start-server
This command runs the server and bot in the background.
-
Register Application Metadata: Run the following command from your terminal. This only needs to be done once.
node app.js register-metadata -
Register Discord Commands: Run the following command from your terminal:
node app.js register-discord-commandsThis will register the application's slash commands with Discord.
-
Link an account: Direct users to the URL
http://localhost:3000/start(replacelocalhost:3000with your bot's actual address). This will initiate the Discord and XAuthConnect OAuth flow. -
Use Slash Commands: Users can now use the registered slash commands (e.g.,
/update) in any Discord channel where the bot is present to refresh their linked role data. -
CLI Management Commands: You can manage the application using the following command-line interface (CLI) commands:
node app.js help: Displays a list of all available commands and their descriptions.node app.js list: Lists all linked users from the database.node app.js prune: Removes users from the database who are no longer in the Discord server specified byguildId. This command does not bring the Discord bot online.node app.js refresh-all: Refreshes the Discord linked role metadata for all users in the database. This command does not bring the Discord bot online.node app.js register-discord-commands: Registers the application's global slash commands with Discord. This command does not bring the Discord bot online.node app.js register-metadata: Registers the application's role connection metadata schema with Discord. This command does not bring the Discord bot online.node app.js stop-server: Stops the background HTTP server and Discord bot.
For Discord to send interactions (like slash commands) to your bot, your bot's interaction endpoint must be publicly accessible. This is crucial for both local development and production deployments. Below are two common methods:
Ngrok creates a secure tunnel from a public endpoint to a locally running service. It's ideal for testing your bot during development.
- Install Ngrok: Follow the instructions on the Ngrok website.
- Run Ngrok: In your terminal, start Ngrok to expose your bot's port (default 3000):
ngrok http 3000
- Copy Public URL: Ngrok will provide a public HTTPS URL (e.g.,
https://xxxx-xxxx-xxxx-xxxx.ngrok-free.app). - Update Discord Application: Go to your Discord Developer Portal -> Your Application -> General Information, and set the "Interaction Endpoint URL" to your Ngrok public URL.
- Update
REDIRECT_URI: If you are using the OAuth2 flow, update theREDIRECT_URIin your bot's.envfile to use the Ngrok public URL (e.g.,REDIRECT_URI=https://xxxx-xxxx-xxxx-xxxx.ngrok-free.app/discord/callback).
Cloudflare Tunnel securely connects your origin server (where your bot is hosted) to Cloudflare's network without exposing your IP address. It's a more robust solution for production.
- Install
cloudflared: Follow the instructions on the Cloudflare Developers documentation. - Authenticate
cloudflared: Runcloudflared tunnel loginand follow the browser prompts. - Create a Tunnel:
cloudflared tunnel create <TUNNEL_NAME> - Create a Configuration File (
config.yml): Create a file (e.g.,~/.cloudflared/config.ymlor in your project directory) for your tunnel:Replacetunnel: <TUNNEL_UUID> credentials-file: /home/.cloudflared/<TUNNEL_UUID>.json ingress: - hostname: your-bot-domain.com service: http://localhost:3000 # Or your bot's internal IP:port - service: http_status:404
<TUNNEL_UUID>with your tunnel's UUID andyour-bot-domain.comwith your desired public domain. - Run the Tunnel:
cloudflared tunnel run <TUNNEL_NAME> - Update Discord Application: Go to your Discord Developer Portal -> Your Application -> General Information, and set the "Interaction Endpoint URL" to your public domain (e.g.,
https://your-bot-domain.com/discord/interactions). - Update
REDIRECT_URI: Update theREDIRECT_URIin your bot's.envfile to use your public domain (e.g.,REDIRECT_URI=https://your-bot-domain.com/discord/callback).
Contributions are welcome and appreciated! Here's how you can contribute:
- Fork the project on GitHub.
- Create your feature branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add some AmazingFeature'). - Push to the branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
Please make sure to update tests as appropriate and adhere to the existing coding style.
This project is licensed under the CSSM Unlimited License v2.0 (CSSM-ULv2). See the LICENSE file for details.