Bridge your GitHub issues and Discord discussions.
Create, sync, and manage GitHub issues directly from a Discord forum channel.
- Interactive GitHub issue creation from Discord
- Label selection synced from GitHub
- Organized command structure with subcommands (
/utils
,/github …
) - Automatic linking between GitHub issues and Discord threads (coming soon)
- TypeScript + discord.js + Octokit
- Explicit, strongly typed event/command registration
- GitHub App authentication (short-lived installation tokens, no personal PATs)
Command | Description |
---|---|
/utils ping |
Sanity check — replies with "🏓 Pong!" |
/github issues create |
Opens a modal to create a GitHub issue with title, description, and labels populated from the repo |
- Node.js 24+ (managed via mise in this repo)
- A Discord Application with a bot user
- A GitHub App installed on your repo with Issues (read & write) + Metadata (read-only) permissions
Clone the repo and install dependencies:
git clone https://github.com/IgiCodes/OctoCord.git
cd OctoCord
mise install
pnpm install
Copy the example env config and fill in your secrets:
cp mise.example.toml mise.local.toml
Update the values inside with:
- Discord → bot token, app ID, guild ID
- GitHub App → app ID, installation ID, PEM private key (string form), repo owner, repo name
Run the bot in dev mode:
mise run dev
Register slash commands with Discord:
mise run register-commands
Build for production:
mise run build
Start compiled bot:
mise run start
The project includes a ready-to-use Dockerfile
and compose.yml
.
Docker workflows are integrated into mise
tasks.
Bring up the bot in Docker (generates .env
automatically):
mise run docker-up
Start the bot in detached mode:
mise run docker-start
Stop and remove containers:
mise run docker-down
View logs from the running container:
mise run docker-logs
Rebuild the image manually (without running):
mise run docker-build
- A
.env
file is generated frommise
tasks (mise run generate-env
). - The
.env
file is mounted automatically into the container bycompose.yml
. - Secrets (Discord token, GitHub keys, etc.) are pulled from this file.
The container exposes a health endpoint:
GET /healthz
Docker Compose uses this for automatic restart if the bot crashes.
src/config/
→ Environment variable loading & configsrc/discord/
→ Discord client, commands, events, handlerssrc/github/
→ GitHub App clientsrc/storage/
→ Data storage layer (currently in-memory, future: SQLite, etc.)src/index.ts
→ Main bot entrypointsrc/registerCommands.ts
→ Script to register slash commandsassets/
→ Logo and static assets (bundled into Docker image)
Variable | Required | Default | Description |
---|---|---|---|
PORT |
Yes | none | Internal port the bot listens on (healthcheck endpoint runs here). |
HOST_PORT |
Yes | none | Host machine port mapped via Docker Compose. |
DISCORD_TOKEN |
Yes | none | Bot token from your Discord application. |
DISCORD_APP_ID |
Yes | none | Discord application ID. |
DISCORD_PUBLIC_KEY |
Yes | none | Discord app public key (used for interactions/webhooks). |
DISCORD_GUILD_ID |
No | unset | Guild/server ID for development — if not set, commands register globally. |
GITHUB_APP_ID |
Yes | none | GitHub App ID. |
GITHUB_APP_INSTALLATION_ID |
Yes | none | Installation ID of the GitHub App on your repo/org. |
GITHUB_APP_PRIVATE_KEY_PEM |
Yes | none | Private key string for the GitHub App (PEM contents). |
GITHUB_OWNER |
Yes | none | GitHub org or username that owns the repo. |
GITHUB_REPO |
Yes | none | GitHub repo name. |
DRY_RUN |
No | false |
If true , simulate command registration without sending to Discord. |
DEBUG_PAYLOAD |
No | false |
If true , logs the JSON payload sent to Discord during registration. |
FORCE_GLOBAL |
No | false |
If true , forces commands to register globally even if DISCORD_GUILD_ID . |
UNREGISTER_COMMANDS |
No | false |
If true , will unregister commands from discord (global if FORCE_GLOBAL or DISCORD_GUID_ID is unset). |
- Secrets (
.env
,mise.local.toml
, PEM key) are never committed — check.gitignore
. - GitHub App credentials are short-lived installation tokens, not long-lived PATs.
- Webhook secret support planned (to verify incoming GitHub → Discord events).
- Sync issue comments → Discord forum thread
- Sync thread replies → GitHub issue comments
- Support closing/reopening issues from Discord
- Support multiple repos per server
- CI/CD deployment recipe
PRs welcome! Feel free to file an issue if you want to help out.
GPL 3.0 © IgiCodes