A flexible, extensible Discord bot that listens to GitHub webhooks and automatically publishes beautiful release announcements on X (Twitter) โ with a Canvas-generated image card.
๐ฆ Features ยท ๐ Quick Start ยท โ๏ธ Configuration ยท ๐ฆ X Setup ยท ๐จ Card Preview ยท ๐ก Adding Repos
| Feature | Details |
|---|---|
| ๐ GitHub Webhooks | Listens for release and push events โ supports unlimited repos |
| ๐จ Canvas Image | Auto-generates a 1200ร630 announcement card with logo, name, version & changelog |
| ๐ผ Discord Server Logo | Fetched automatically from your Discord guild via bot token |
| ๐ฆ X Auto-Tweet | Posts a formatted tweet with the image, no official Twitter API key needed |
| ๐ Discord Embed | Rich branded embed sent to your announcement channel simultaneously |
| ๐ Deduplication DB | JSON database prevents double-posting the same release |
| ๐งฉ Multi-Repo | Monitor multiple GitHub repos, each with different Discord channels & Twitter settings |
| ๐ MIT License | Fully open source, free to use and extend |
discord-github-x-bot/
โโโ index.js โ Entry point โ boots all systems
โโโ config.json โ All non-secret configuration
โโโ .env โ ๐ Secret tokens (never commit!)
โโโ .gitignore
โโโ LICENSE
โโโ README.md
โ
โโโ commands/
โ โโโ status.js โ !status Discord command
โ
โโโ database/
โ โโโ db.js โ JSON database (deduplication)
โ โโโ data.json โ Auto-created at first run
โ
โโโ media/ โ Generated PNG announcement cards
โ
โโโ systems/
โ โโโ discord/
โ โ โโโ client.js โ Discord.js bot client + guild icon fetcher
โ โ โโโ canvas.js โ ๐จ Canvas image generator (1200ร630)
โ โโโ github/
โ โ โโโ webhook.js โ Express server โ receives GitHub webhooks
โ โ โโโ handler.js โ Pipeline orchestrator (logo โ canvas โ Discord โ X)
โ โโโ twitter/
โ โโโ poster.js โ X poster via auth_token cookie
โ โโโ formatter.js โ Builds beautiful tweet text
โ
โโโ utils/
โโโ logger.js โ Colorful timestamped console logger
- Node.js v18+ โ nodejs.org
- A Discord bot with
Send Messages,Attach Files,Embed Linkspermissions โ Discord Developer Portal - A GitHub account with webhook access to your repo(s)
- An X (Twitter) account you're logged into in your browser
git clone https://github.com/aymenelouadi/discord-github-x-bot.git
cd discord-github-x-bot
npm installWindows users:
canvasrequires native build tools. Run once if needed:npm install --global --production windows-build-tools
Create a .env file in the project root:
# โโ Discord โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
DISCORD_TOKEN=your_discord_bot_token_here
# โโ GitHub โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
GITHUB_TOKEN=ghp_your_github_classic_token
# โโ X (Twitter) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
TWITTER_AUTH_TOKEN=your_auth_token_cookie_value
TWITTER_CT0=your_ct0_cookie_value
# โโ Webhook Server โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
WEBHOOK_PORT=3000
WEBHOOK_SECRET=optional_secret_for_hmac_verificationHow to get each token: see Discord Token, GitHub Token, and X auth_token sections below.
Edit the repositories array โ add one entry per GitHub repo you want to watch:
{
"repositories": [
{
"id": "my-awesome-project",
"enabled": true,
"repo": "github-username/repo-name",
"events": ["release", "push"],
"branch_filter": "main",
"discord": {
"guild_id": "123456789012345678",
"channel_id": "987654321098765432",
"notify_on_push": false,
"notify_on_release": true,
"embed_color": "#58b9ff"
},
"twitter": {
"enabled": true,
"post_on_push": false,
"post_on_release": true,
"hashtags": ["OpenSource", "GitHub", "JavaScript"]
},
"project": {
"name": "My Awesome Project",
"short_description": "A great open-source tool",
"language": "JavaScript",
"logo_source": "discord_guild"
}
}
]
}
logo_source: "discord_guild"โ the bot fetches your Discord server icon automatically and uses it in the card image.
In your GitHub repository โ Settings โ Webhooks โ Add webhook:
| Field | Value |
|---|---|
| Payload URL | https://your-domain.com/github/webhook |
| Content type | application/json |
| Secret | Same value as WEBHOOK_SECRET in .env (optional) |
| Which events? | โ Releases ยท โ Pushes |
| Active | โ |
The Payload URL is built from WEBHOOK_PUBLIC_URL (.env) + the path in config.json:
# Example with a real domain:
WEBHOOK_PUBLIC_URL=https://your-domain.com
# โ Payload URL = https://your-domain.com/github/webhook
# Example with localhost (no WEBHOOK_PUBLIC_URL set):
# โ Payload URL = http://localhost:3000/github/webhook
No domain yet? Use ngrok for local testing:
ngrok http 3000 # Then set WEBHOOK_PUBLIC_URL=https://xxxx.ngrok.io
# Production
npm start
# Development (auto-restart on file changes)
npm run devYou should see:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Discord ร GitHub ร X Auto-Publisher v1.0 โ
โ MIT License ๐ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2026-03-13 12:00:00 [DISCORD] Logged in as YourBot#1234
2026-03-13 12:00:01 [TWITTER] Authenticated via auth_token cookie โ
2026-03-13 12:00:01 [GITHUB ] Webhook server listening on port 3000
2026-03-13 12:00:01 [GITHUB ] Endpoint: POST http://localhost:3000/github/webhook
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2026-03-13 12:00:01 [SUCCESS] All systems online. Listening for GitHub webhooksโฆ
{
"webhook_server": {
"port": 3000, // Port the Express server listens on
"path": "/github/webhook" // Endpoint path
},
"discord": {
"prefix": "!", // Bot command prefix
"status_message": "Watching GitHub ๐"
},
"repositories": [ /* see above */ ],
"twitter": {
"tweet_templates": {
"release": {
"header": "๐ New Release Drop",
"footer": "Built with โค๏ธ โ Open Source under MIT License",
"max_changelog_lines": 5 // Max bullet points shown in tweet
},
"push": {
"header": "โก New Update Pushed",
"footer": "Stay tuned for more updates!",
"max_changelog_lines": 3
}
}
},
"canvas": {
"width": 1200,
"height": 630,
"theme": {
"bg_gradient_start": "#0d1117",
"bg_gradient_end": "#161b22",
"accent": "#58b9ff",
"accent_secondary": "#7c3aed",
"text_primary": "#f0f6fc",
"text_secondary": "#8b949e",
"logo_glow": "#58b9ff"
}
}
}- Go to discord.com/developers/applications
- New Application โ give it a name
- Bot tab โ Reset Token โ copy the token โ paste as
DISCORD_TOKENin.env - OAuth2 โ URL Generator: scopes
bot, permissions:Send Messages,Embed Links,Attach Files - Open the generated URL and invite the bot to your server
- Go to github.com/settings/tokens โ Generate new token (classic)
- Scopes needed:
repo(private repos) orpublic_repo(public repos only) - Copy and paste as
GITHUB_TOKENin.env
The bot uses browser session cookies โ no Twitter Developer API required.
- Log in to x.com in your browser
- Open DevTools (
F12) โ Application tab โ Cookies โhttps://x.com - Copy
auth_tokenโ paste asTWITTER_AUTH_TOKENin.env - Copy
ct0โ paste asTWITTER_CT0in.env
DevTools โ Application โ Storage โ Cookies โ https://x.com
auth_token โ ebb31c... โ copy this
ct0 โ abc123... โ copy this too
โ ๏ธ Cookies expire when you log out or after some time. Re-copy them if tweets stop posting.โ ๏ธ Do NOT log out of X while the bot is running.
When a new GitHub Release is published, the bot automatically posts:
๐ New Release Drop
๐ฆ My Awesome Project v2.1.0
๐ฌ A great open-source tool
โจ What's New:
โธ Added dark mode support
โธ 40% performance improvement
โธ Fixed critical bug in parser
โธ New CLI interface
๐ https://github.com/owner/repo/releases/tag/v2.1.0
#OpenSource #GitHub #JavaScript
Built with โค๏ธ โ Open Source under MIT License
The generated 1200ร630 PNG card is attached to each tweet and Discord embed:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ accent line
โ โ
โ โญโโโโโฎ My Awesome Project [v2.1.0] [JavaScript] โ
โ โLOGOโ โ
โ โฐโโโโโฏ A great open-source tool โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โธ Added dark mode support โ
โ โธ 40% performance improvement โ
โ โธ Fixed critical bug in parser โ
โ โ
โ โ github.com/owner/repo ๐ MIT License โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ accent line
The logo is circular with a neon glow ring. If no Discord guild icon is found, an auto-generated colored avatar with the project's initial letter is used as fallback.
No code changes needed โ add another object to config.json:
{
"repositories": [
{ "id": "project-one", "repo": "you/project-one", ... },
{ "id": "project-two", "repo": "you/project-two", ... },
{ "id": "project-three", "repo": "org/another-repo", ... }
]
}Each repo can independently configure:
- Discord channel & embed color
- Twitter hashtags and on/off per event type
- Branch filter for push events
| Command | Description |
|---|---|
!status |
Shows monitored repos, total posts, recent releases and bot uptime |
While the bot is running:
GET http://localhost:3000/healthReturns:
{
"ok": true,
"uptime": 3600,
"repositories": ["owner/repo-one", "owner/repo-two"],
"timestamp": "2026-03-13T12:00:00.000Z"
}Pull requests are welcome! Open an issue first for major changes.
- Fork: github.com/aymenelouadi/discord-github-x-bot
- Create your branch:
git checkout -b feat/amazing-feature - Commit:
git commit -m 'feat: add amazing feature' - Push:
git push origin feat/amazing-feature - Open a Pull Request
MIT ยฉ 2026 aymenelouadi