Skip to content

ghostty-org/discord-bot

Repository files navigation

Ghostty Discord Bot

The Ghostty Discord Bot, humorlessly named "Ghostty Bot."

It originally powered the invite system during Ghostty's private beta period, successfully inviting ~5,000 people. It now serves as the community's helper bot, making development discussion and community moderation more efficient.


Bot setup

Warning

The bot is tailor-made for the Ghostty community and will most definitely be unsuitable for other servers. If you're looking to use similar features, you should consider looking for a more general-purpose bot, or forking this project and modifying it to suit your needs. That said, the core intent of this guide is to help contributors set up their development environment for building and testing new features. Contributions are the goal, not standalone usage.

The bot is built and deployed using Nix. While it's possible to develop the bot without it, the preferred and supported method is through a Nix-based workflow. To that end:

  • The bot must successfully build and run using the Nix setup.
  • If you're developing outside of Nix, you are responsible for troubleshooting any issues that arise.
    As a tip: as long as no changes are made to the project's configuration (e.g. build dependencies), if the bot successfully runs outside of Nix, it will most likely work within Nix as well.

1. Preparing a Discord application

1.1. Creating a Discord application

  1. Go to the Discord Developer Portal.
  2. Click on the "New Application" button.
  3. Pick a name for your bot.

1.2. Getting a Discord token

On your newly created bot's dashboard:

  1. Go to "Bot" on the sidebar.
  2. Click on the "Reset Token" button.
  3. Save the newly generated token for later.
  4. Under "Privileged Gateway Intents", enable:
    • Server Members Intent
    • Message Content Intent

1.3. Inviting the bot to your server

  1. Go to "OAuth2" on the sidebar.
  2. Under "OAuth2 URL Generator", select the bot scope.
  3. Under "Bot Permissions" that appears, choose the following permissions:
    • Attach Files
    • Manage Messages
    • Manage Roles
    • Manage Threads
    • Manage Webhooks
    • Send Messages
    • Use External Apps
      (your URL should contain a 1125917892061184 bitfield for permissions)
  4. Use the generated URL at the bottom of the page to invite the bot to your server.

2. Getting a GitHub token

A GitHub token is necessary for the bot's Entity Mentions feature.

You can get one in two ways:

  • On GitHub, go to Settings > Developer settings > Personal access tokens > Tokens (classic) > Generate new token, or use this link: Generate new token. As the bot only accesses public repositories, it doesn't require any scopes.
  • If you have the gh CLI installed and authenticated, run gh auth token.

3. Preparing a Discord server

The following channels will be necessary:

  • #help: a forum channel
  • #media: a text channel
  • #showcase: a text channel

The following roles will be necessary (both requiring the Manage Messages permission):

  • mod
  • helper

4. Preparing the .env file

Create a .env file in the root of the project based on .env.example. Below are explanations for each variable:

  • channel/role IDs from step 3:
    • BOT_HELP_CHANNEL_ID
    • BOT_MEDIA_CHANNEL_ID
    • BOT_SHOWCASE_CHANNEL_ID
    • BOT_MOD_ROLE_ID
    • BOT_HELPER_ROLE_ID
  • BOT_TOKEN: the Discord bot token from step 1.
  • GITHUB_ORG: the GitHub organization name.
  • GITHUB_REPOS: a comma-separated list of prefix:repo_name pairs used for entity mention prefixes. The main/bot/web prefixes aren't exactly fixed, but some of the bot logic assumes these names (e.g. defaulting to main).
  • GITHUB_TOKEN: the GitHub token from step 2.
  • SENTRY_DSN: the Sentry DSN (optional).

5. Running the bot

Nix

Run the bot with:

$ python -m app
...

After you've made your changes, run the linter and formatter:

$ ruff check
$ ruff format

Non-Nix

This bot runs on Python 3.12+ and is managed with Poetry. To get started:

  1. Install Poetry (e.g. via uv or pipx).
  2. Install the project and run the bot:
    $ poetry install
  3. Run the bot:
    $ poetry run python -m app
    ...
  4. After you've made your changes, run the linter and formatter:
    $ poetry run ruff check
    $ poetry run ruff format

Project structure

Project structure graph
  • components/ is a place for all dedicated features, such as message filters or entity mentions. Most new features should become modules belonging to this package.
  • config.py handles reading and parsing the environment variables and the local .env file. Although a standalone module, it's typically accessed through a setup.py re-export for brevity:
    -from app import config
    -from app.setup import bot
    +from app.setup import bot, config
  • core.py loads the components package and houses the code for handling the most standard bot events (e.g. on_ready, on_message, on_error).
  • setup.py creates the Discord and GitHub clients.
  • utils.py contains utility functions not exactly tied to a specific feature.
  • __main__.py initializes Sentry (optional) and starts the bot.

Features

/docs

A command for linking Ghostty documentation with autocomplete and an optional message option:

/docs command autocomplete /docs command message option

Entity mentions

Automatic links to Ghostty's GitHub issues/PRs/discussions ("entities") when a message contains GitHub-like mentions (#1234). It reacts to message edits and deletions for 24 hours, while also providing a "🗑️ Delete" button for 30 seconds in case of false positives. Mentioning entities in other repos is also supported with prefixes:

The bot also keeps a TTR cache to avoid looking up the same entity multiple times (with data being refetched 30 minutes since last use), making the bot more responsive (the example below can take ~7s on the first lookup and ~0.5ms on subsequent lookups).

Entity mentions example

Message filters

This feature takes care of keeping the #showcase and #media channels clean. The bot will delete any message:

  • without an attachment in #showcase
  • without a link in #media

It will also DM users about the deletion and provide an explanation to make it less confusing:

Message filter notification

Moving messages

Used for moving messages to more fitting channels (e.g. off-topic questions in #development to #tech).

Move message example

Ghostty troubleshooting questions can be turned into #help posts with a related feature:

Turn into #help post example

Releases

No releases published

Packages

No packages published