Please reference the information below when contributing to this repository.
Welcome to the FlyByWire Simulations Discord bot repository. Thank you for your interest in contributing to the project. Full details and guidelines on how to ensure this project is managed are included below.
Please help other contributors to the project wherever you can, as people all start somewhere. If you require assistance or wish to provide assistance you can ask/answer questions in the #discord-bot or #dev-support channel on discord.
- node version >= 18.x
To ensure that commands are written professionally and clearly, please follow the guide below:
- Use the proper name for third party services. For example: SimBrief and not simBrief.
- If you are using images within the command, please ensure that they are clear and easy to understand.
- Refrain from using exclamation points unless it is a warning.
- Ensure that the contents of the command are correct. If you are unsure if something is correct please speak to any bot developer, and they will be able to verify anything.
- Ensure that grammar and spelling is correct.
Reminder: When submitting a pull request, please ensure you target the staging
branch.
- Fork the repository.
- Clone to your local system using your IDE of choice.
- Make a new branch from staging and name it appropriately (e.g. feat: added ADIRS command, fix: typos fixed in ADIRS).
- Create/edit the command you are working on.
- Test your build locally.
- Create a PR to merge your changes into staging.
Note: It may be beneficial to create a draft PR while working on your command. This will allow us to see who is working on what, and will enable the community to give active feedback on your work.
You can find the pull request template here.
- Copy the
.env.example
file and rename it to.env
.
The config
folder contains the configuration details for running the bot in the staging or production environment.
The config contains different variables and settings which are used by the bot to reference channels, check permissions, use colors, etc. All these values are defined based on the Discord server the bot will connect to and are unique to that server.
You need to create your own config json file by copying one of the existing ones and updating the different constants/settings with your own values. This allows you to run the bot in your own environment without having to recompile it from the source. See Setting up the config for more information.
The config system uses the great node-config library.
This library will load a file from the config
folder, based on an environment variable. It can read several types of files, including json, yaml, properties, toml, xml and more. For this bot, the standard is JSON, but nothing stops you from using your own format during development.
- Create a file named
development.json
at ../config/. - Paste the contents of ../config/staging.json into
development.json
. - In your
.env
file setNODE_CONFIG_ENV
todevelopment
. - In your
development.json
file replace theguildId
field with your server ID. - Update the channel and role IDs to those in your server.
- Add your test bot ID to
modLogExclude
anduserLogExclude
.
Warning
Not updating the IDs will produce unexpected behavior!
Note
If your feature requires a permanent addition to the config where you do not know the correct ID, leave a note on your PR and a team member will handle it.
- Log into the Discord website and navigate to the applications page.
- Click
New Application
. - Give your application a name.
- Navigate to the
Bot
tab and clickAdd Bot
. You will have to confirm by clickingYes, do it!
. - Click the
Copy
button underneath token. (Do not share this). - Inside the
.env
file, findBOT_SECRET=TOKEN
and replace theTOKEN
with what you copied instep 5
.
Note
If you want to use features that rely on 3rd parties like AVWX or WolframAlpha, you need to update their respective environment variables. See below for more information.
Privileged Gateway Intents must now be enabled within the Discord Developer Portal in order for your bot to function. The steps below will explain how to enable them.
- Log into the Discord website and navigate to the applications page and select your application. Then select
Bot
underSettings
. - Scroll down to the Privileged Gateway Intents section and enable all the intents.
- Create a Discord server where you can test your bot.
- On the applications page, select your application and navigate to the
OAuth2
tab. Then selectbot
under thescopes
section. - Tick
Administrator
box under theBot Permissions
section. - Click the
Copy
button and paste it into your search bar in the browser of your choice, and invite it to your test server.
We recommend running your bot with the development node environment. Set NODE_ENV=development
in your .env
file.
- Run
npm install
to install the dependencies. - Run
npm run dev
to start the development build.
When running the bot for the first time, it is important to set DEPLOY=true
in your .env
. This will ensure that commands are registered with Discord. Once the bot has been run once, you can set DEPLOY=false
to prevent the bot from re-deploying commands every time it starts.
Important
There is a daily limit on command creation, so make sure you set DEPLOY
to false after the first launch!
If you need to re-deploy commands after making changes, you can run the /deploy-command
command in Discord.
Please note: If you are running the bot in a development environment, your commands will be deployed to the guild you have set in your config file (likely your test server). If running in a production environment, your commands will be deployed globally.
When deploying guild commands, they are registered and available immediately. However, global commands can take up to an hour to be registered and available.
Some commands require access to a MongoDB server to store persistence data. The steps below outline MongoDB's setup procedure, and the necessary steps to connect your application to your MongoDB instance.
- Install MongoDB from their website or set up an Atlas cluster.
- If running MongoDB locally, run it as a service or from the terminal.
- Create a new database named fbw in your MongoDB instance.
- Inside the .env file, on a new line type
MONGODB_URL=URL
replacingURL
with your MongoDB access URL.
If you have installed MongoDB locally, your access url will be mongodb://localhost:27017/fbw
. If you are using Atlas, the connection URL can be found under
Connect->Connect your application
in Database, located under Deployments.
This is a guide on how to set up a MongoDB instance with Docker.
- Install Docker from their website and read the guide on how to get started if unsure how to use it.
- In the
.env
file, on a new line typeMONGODB_URL=URL
replacingURL
with your MongoDB access URL. - In the
.env
file, on a new line typeMONGODB_DATABASE=DATABASE_NAME
replacing DATABASE with your MongoDB database name. - In the
.env
file, on a new line typeMONGODB_USERNAME=USER_NAME
replacing USER with your MongoDB username. - In the
.env
file, on a new line typeMONGODB_PASSWORD=PASSWORD
replacing PASSWORD with your MongoDB password. - To run the docker-compose file, run
docker-compose up -d
this will start the MongoDB instance along with mongo-express to view the DB. - To stop the container run
docker-compose down
. - The volumes will be created in the
/data
directory.
TheMONGODB_URL
will be mongodb://USERNAME:PASSWORD@localhost:27017/DATABASE_NAME?authSource=admin
.
You can access mongo-express by visiting localhost:8081.
If your command requires environment variables please add them to the .env.example
file for documentation.
- Copy the
.env.example
file to.env
. - You can do this manually or using the command line by typing
cp .env.example .env
. - Fill out the
.env
file with your environment variables.
A ban appeal form is sent to a user when they are banned. The URL for the form is stored as an environment variable, BAN_APPEAL_URL
. For testing, you could set to a URL like https://flybywiresim.com/
.
Some commands may require additional tokens. If you would like to test them out on your bot, you must include the tokens inside your .env file. These commands include the metar, station and Wolfram Alpha commands. The steps below will explain how to set this up.
- Make a free account here. Then, follow the steps here to get your token.
- Inside the .env file, on a new line type
METAR_TOKEN=TOKEN
replacingTOKEN
with what you copied instep 1
. - Then, on another new line within the .env file, type
STATION_TOKEN=TOKEN
replacingTOKEN
with what you copied instep 1
. - Then, on another new line within the .env file, type
TAF_TOKEN=TOKEN
replacing theTOKEN
with what you copied instep 1
.
- Select get API access here to create an account.
- Once you have an account you will need to get an AppID from here.
- Inside the
.env
file, on a new line typeWOLFRAMALPHA_TOKEN=TOKEN
replacingTOKEN
with your wolfram alpha AppID.
Please note, this will only show the basics of adding a command.
- Create a new file in the relevant folder within
src/commands/
and name it appropriately.yourcommand.ts
. - Create your command.
- Add it to
src/commands/index.ts
. You need to add the lineimport name from './commandfolder/filename';
, replacingname
with the file name from your command,commandfolder
with the relevant folder your command has been placed within, andfilename
with the file name you created instep 1
(Add this below the last command). Please note: context commands have their ownindex.ts
file withing thesrc/commands/context/
folder. - Add changes to
.github/CHANGELOG.md
and add command to.github/command-docs.md
.
If you need help creating a command, you may find it useful to copy an existing command as a template, changing what you need.
- Choose user-friendly command names.
- Test your build locally before submitting it as ready for review.
- All you need to do is open the command you wish to edit in
src/commands/
and edit what you need. - Add changes to
.github/CHANGELOG.md
(and.github/command-docs.md
if necessary). - Commit and Push.
An autocomplete callback function of type AutocompleteCallback
can be passed to slashCommand()
as a third argument.
Note
In order for autocomplete to work, you have to set the autocomplete
flag of your command option to true.
Important
Autocomplete choices are not enforced by the Discord client so make sure you handle invalid user input!
The basic structure of such a command looks similar to this example:
import { ApplicationCommandOptionType, ApplicationCommandType } from 'discord.js';
import { slashCommand, slashCommandStructure, AutocompleteCallback, makeEmbed } from '../../lib';
const data = slashCommandStructure({
name: 'ping',
description: 'Ping the bot for a response.',
type: ApplicationCommandType.ChatInput,
default_member_permissions: constantsConfig.commandPermission.MANAGE_SERVER, //Optional command permission - always use MANAGE_SERVER and add a comment to specify overrides needed (roles, channels etc.)
dm_permission: false, // Optional, this sets if commands can be run in DMs (global commands only)
options: [{ // Optional, this is where you can add options to your command
name: 'message',
description: 'Provide some text to send back.',
type: ApplicationCommandOptionType.String,
max_length: 100,
required: false,
autocomplete: true, // Optional - This is only required if you plan on using autocomplete for your command.
}],
});
// Optional - This is only required if you plan on using autocomplete for your command.
const autocompleteCallback: AutocompleteCallback = ({ interaction }) => {
// Autocomplete logic goes here
const choices = [
{
name: 'Display Name',
value: 'Value that is actually sent to your bot.'
},
];
// If you can't autocomplete anything respond with an empty array.
return interaction.respond(choices);
};
export default slashCommand(data, async ({ interaction }) => {
const msg = interaction.options.getString('message') ?? 'Pong 🏓';
const pongEmbed = makeEmbed({ description: msg });
return interaction.reply({ embeds: [pongEmbed] });
}, autocompleteCallback); // Optional - This is only required if you plan on using autocomplete for your command.
By default, all commands can be used by anyone, everywhere.
If you want to restrict a command to a specific role or channel, you can add the default_member_permissions
property to the command structure, and set it to constantsConfig.commandPermission.MANAGE_SERVER
(this is the permission we use as only Admins hold this permission). This will prevent the command from being used by anyone, unless they have the MANAGE_SERVER
permission.
Once your command is deployed, you can then go to your server settings, integrations and select your bot. Select the command you wish to change the role and channel permissions for and set permissions accordingly.
We ask that if you are submitting a pull request that you add a comment to the default_member_permissions
property to specify what permissions are needed to use the command. This will allow us to easily change and keep track of the permissions required when deploying the command.
Using this permission system enables us to easily change the permissions required to use a command, without having to change any code.