A Discord bot built with Hono and Cloudflare Workers that reminds users to make daily GitHub contributions.
Features
- Monitors multiple GitHub users' daily contributions
- Sends Discord notifications when users haven't contributed
- Supports custom timezone configuration
- HTTP endpoint for manual contribution checks
- Scheduled daily checks via Cloudflare Cron
Tech Stack
- Hono (Web framework)
- Cloudflare Workers (Runtime)
- GitHub GraphQL API (Contribution data)
- Discord Webhooks (Notifications)
Setup
1. Install Dependencies
2. Configure Environment Variables
Copy the example file and fill in your values:
cp .dev.vars.example .dev.vars
Edit .dev.vars:
GITHUB_TOKEN=ghp_your_github_personal_access_token
USERS=[{"github":"username1","discord":"123456789012345678"},{"github":"username2","discord":"234567890123456789"}]
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your/webhook/url
API_KEY=your_secret_api_key
TIMEZONE_OFFSET=9
Environment Variables
| Variable | Description | Example |
|---|---|---|
GITHUB_TOKEN |
GitHub Personal Access Token (requires read:user scope) |
ghp_xxxxx |
USERS |
JSON array of users with GitHub username and Discord user ID | [{"github":"user1","discord":"123"}] |
DISCORD_WEBHOOK_URL |
Discord webhook URL for notifications | https://discord.com/api/webhooks/... |
API_KEY |
Secret key for /check-contribution endpoint authentication |
secret_key_123 |
TIMEZONE_OFFSET |
Timezone offset from UTC in hours (e.g., 9 for JST, -5 for EST) | 9 |
3. Get GitHub Personal Access Token
- Go to GitHub Settings > Developer settings > Personal access tokens > Tokens (classic)
- Generate new token with
read:userscope - Copy the token to
GITHUB_TOKENin.dev.vars
4. Get Discord Webhook URL
- Open Discord server settings > Integrations > Webhooks
- Create a new webhook
- Copy the webhook URL to
DISCORD_WEBHOOK_URLin.dev.vars
5. Get Discord User ID
- Enable Developer Mode in Discord (User Settings > Advanced > Developer Mode)
- Right-click on user and select "Copy User ID"
- Use this ID in the
USERSconfiguration
Development
Local Development Server
The server will start at http://localhost:8787
Test HTTP Endpoint Locally
curl -H "Authorization: Bearer your_secret_api_key" http://localhost:8787/check-contributionTest Cron Handler Locally
Since cron triggers cannot be tested directly in local dev, you can:
- Create a test script to call the handler:
// test-cron.ts import { checkAndNotify } from './src/handlers/contribution-handler'; const env = { GITHUB_TOKEN: 'your_token', USERS: '[{"github":"user1","discord":"123"}]', DISCORD_WEBHOOK_URL: 'your_webhook', API_KEY: 'test', TIMEZONE_OFFSET: '9', }; checkAndNotify(env).then(() => console.log('Done'));
- Run with:
Format Code
Lint Code
pnpm run lint pnpm run lint:fix
Deployment
Deploy to Cloudflare Workers
Set Production Environment Variables
wrangler secret put GITHUB_TOKEN wrangler secret put API_KEY wrangler secret put DISCORD_WEBHOOK_URL wrangler secret put USERS wrangler secret put TIMEZONE_OFFSET
API
GET /check-contribution
Manually trigger contribution check and Discord notification.
Authentication: Bearer token (API_KEY)
Request:
curl -H "Authorization: Bearer your_api_key" https://your-worker.workers.dev/check-contributionResponse:
{
"users": [
{
"username": "user1",
"hasCommit": true,
"contributionCount": 5
},
{
"username": "user2",
"hasCommit": false,
"contributionCount": 0
}
],
"notified": true
}Cron Schedule
The bot runs automatically based on the cron schedule defined in wrangler.toml:
[triggers] crons = ["0 11 * * *"] # 11:00 UTC = 20:00 JST (with TIMEZONE_OFFSET=9)
To change the notification time, edit the cron expression in wrangler.toml. The TIMEZONE_OFFSET environment variable is used to calculate the local date range (from midnight to the current time in your timezone).
Project Structure
src/
├── index.ts # Entry point with routes and cron
├── handlers/
│ └── contribution-handler.ts # Business logic for contribution checks
├── middlewares/
│ └── auth.ts # Authentication middleware
├── routes/
│ └── check-contribution.ts # HTTP endpoint definition
├── services/
│ ├── github.ts # GitHub API client
│ └── discord.ts # Discord webhook client
├── types/
│ └── env.ts # Environment variable types
└── utils/
├── time-range.ts # Timezone calculation utilities
└── notification-message.ts # Discord message formatting