π€ AI-powered GitHub webhook handler with Claude Code integration for intelligent issue and PR analysis
The HLS (Hook Line Sinker) webhook handler is a production-ready GitHub webhook service that uses Claude AI to automatically analyze issues, pull requests, and other GitHub events. It features advanced chained prompts for multi-step analysis and automatic backup processing via cron jobs.
sequenceDiagram
participant GH as GitHub
participant NG as nginx<br/>(Let's Encrypt SSL)
participant WH as adnanh/webhook<br/>(:9000)
participant PY as webhook_dispatch.py
participant HLS as HLS Python<br/>(FastAPI)
participant AI as Claude AI
participant API as GitHub API
Note over GH: Issue/PR created
GH->>NG: POST https://clidecoder.com/hooks/github-webhook
Note over NG: SSL termination<br/>Let's Encrypt cert
NG->>WH: Proxy to localhost:9000
Note over WH: Validate webhook rules<br/>Check signature
WH->>PY: Execute script with payload
Note over PY: Load settings.yaml<br/>Validate signature
PY->>HLS: Import and call modules
HLS->>AI: Analyze with prompts
AI-->>HLS: Return analysis
HLS->>API: Apply labels/comments
API-->>GH: Update issue/PR
HLS-->>PY: Return result
PY-->>WH: Exit with status
WH-->>NG: 200 OK response
NG-->>GH: Webhook delivered
server {
server_name clidecoder.com;
# Webhook endpoint - proxy to adnanh/webhook service
location /hooks {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Preserve GitHub webhook headers
proxy_set_header X-GitHub-Event $http_x_github_event;
proxy_set_header X-GitHub-Delivery $http_x_github_delivery;
proxy_set_header X-Hub-Signature-256 $http_x_hub_signature_256;
# Timeouts for webhook processing
proxy_connect_timeout 10s;
proxy_send_timeout 10s;
proxy_read_timeout 300s; # 5 minutes for Claude processing
# Body size for large PR payloads
client_max_body_size 10M;
client_body_buffer_size 128k;
}
# Let's Encrypt SSL configuration
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/clidecoder.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/clidecoder.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
# HTTP to HTTPS redirect
server {
listen 80;
server_name clidecoder.com;
return 301 https://$server_name$request_uri;
}[
{
"id": "github-webhook",
"execute-command": "/home/clide/hls/webhook_dispatch.py",
"command-working-directory": "/home/clide/hls",
"response-message": "Webhook received",
"pass-arguments-to-command": [
{
"source": "entire-payload"
}
],
"pass-environment-to-command": [
{
"source": "header",
"name": "X-GitHub-Event",
"envname": "GITHUB_EVENT"
},
{
"source": "header",
"name": "X-GitHub-Delivery",
"envname": "GITHUB_DELIVERY"
},
{
"source": "header",
"name": "X-Hub-Signature-256",
"envname": "GITHUB_SIGNATURE"
}
],
"trigger-rule": {
"match": {
"type": "value",
"value": "application/json",
"parameter": {
"source": "header",
"name": "Content-Type"
}
}
}
}
]github:
webhook_secret: "your-secret-here" # Same as GitHub webhook config
token: "ghp_..." # GitHub PAT for API calls
repositories:
- name: "clidecoder/hls"
events: ["issues", "pull_request"]
settings:
apply_labels: true
post_analysis_comments: true
auto_close_invalid: false
features:
signature_validation: true # Verify webhook signatures
async_processing: false # Process synchronously- Chained Prompts - Multi-step analysis for better AI reasoning and context preservation
- Smart Labeling - Automatically applies relevant labels based on content analysis
- Priority Assessment - Determines issue priority and complexity
- Intelligent Comments - Generates contextual responses and feedback
- nginx Integration - SSL termination and load balancing
- Backup Processing - Cron jobs catch missed webhooks automatically
- Error Recovery - Comprehensive error handling and retry logic
- Monitoring - Structured logging, health checks, and performance metrics
- Context Awareness - Maintains conversation history between prompt steps
- Repository Filtering - Per-repository configuration and event filtering
- Rate Limiting - Respects GitHub and Claude API limits
- Webhook Validation - Secure signature verification
- Python 3.8+ with virtual environment
- nginx with SSL certificates
- webhook service (adnanh/webhook)
- GitHub Personal Access Token
- Claude Code CLI (or Anthropic API Key if not using Max plan)
- Public domain with SSL (e.g., clidecoder.com)
# Install certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx
# Get SSL certificate
sudo certbot --nginx -d clidecoder.com -d www.clidecoder.com
# Test auto-renewal
sudo certbot renew --dry-run# Install webhook service (adnanh/webhook)
# Option 1: Download binary from GitHub releases
wget https://github.com/adnanh/webhook/releases/download/2.8.0/webhook-linux-amd64.tar.gz
tar -xvf webhook-linux-amd64.tar.gz
# Option 2: Install with go
go install github.com/adnanh/webhook@latest# Clone the repository
git clone https://github.com/clidecoder/hls.git
cd hls
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Copy configuration
cp config/settings.example.yaml config/settings.yamlAdd to your nginx site configuration:
server {
server_name your-domain.com;
# Webhook endpoint for GitHub
location /hooks {
proxy_pass http://localhost:9000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Preserve GitHub webhook headers
proxy_set_header X-GitHub-Event $http_x_github_event;
proxy_set_header X-GitHub-Delivery $http_x_github_delivery;
proxy_set_header X-Hub-Signature-256 $http_x_hub_signature_256;
# Increase timeout for Claude processing
proxy_read_timeout 300s;
client_max_body_size 10M;
}
listen 443 ssl;
# SSL certificates configured by certbot or manually
}github:
token: "ghp_your_github_token"
webhook_secret: "generate_secure_secret_with_openssl"
claude:
api_key: "claude-code" # or your Anthropic API key
repositories:
- name: "your-org/your-repo"
enabled: true
events: ["issues", "pull_request"]
labels:
auto_apply: true
comments:
auto_post: true
features:
signature_validation: true
auto_labeling: true
auto_commenting: true# Generate secure webhook secret
openssl rand -hex 32# Edit webhook_dispatch.py first line to use venv Python
#!/home/your-user/hls/venv/bin/python# Use the setup script
source venv/bin/activate
python setup_github_webhook.py
# Or manually in GitHub repository settings:
# - URL: https://your-domain.com/hooks/github-webhook
# - Content type: application/json
# - Secret: Same as webhook_secret in settings.yaml
# - Events: Issues, Pull requests, etc.# Install pm2 globally
npm install -g pm2
# Start webhook service
pm2 start services/pm2/ecosystem.config.js
# Save pm2 configuration
pm2 save
# Set up pm2 to start on boot
pm2 startup# Run webhook service (port 9000)
webhook -hooks services/hooks.json -port 9000 -verbose
# Or run in background
webhook -hooks services/hooks.json -port 9000 -verbose > logs/webhook.log 2>&1 &# Only needed if you want direct API access
# The webhook service calls webhook_dispatch.py directly
source venv/bin/activate
python -m hls.src.hls_handler.main# Webhook service logs
tail -f logs/webhook.log
# Application logs
tail -f logs/webhook.log
# pm2 logs
pm2 logs hls-webhook# Test if webhook service is accessible
curl -X POST https://clidecoder.com/hooks/github-webhook \
-H "Content-Type: application/json" \
-d '{"test": "payload"}'- Go to your repository Settings β Webhooks
- Click on your webhook
- Check "Recent Deliveries" tab
- Green checkmark = successful delivery
- Click on a delivery to see details
# Watch real-time logs
pm2 logs hls-webhook --lines 100
# Check webhook statistics
curl http://localhost:8000/stats
# Check service health
pm2 statusChained prompts break complex AI analysis into multiple focused steps, maintaining context between each step for better reasoning and more accurate results.
-
Step 1 - Analysis: Understand the issue and extract structured data
- Categorize as bug/feature/question
- Assess priority and complexity
- Extract technical areas and requirements
-
Step 2 - Response: Generate appropriate response using analysis data
- Welcome the contributor
- Provide specific guidance based on issue type
- Suggest next steps and timeline
- Better Accuracy - Each step focuses on a specific task
- Context Preservation - Conversation history maintained between steps
- Structured Data - Extract and use metadata between steps
- Flexible Workflows - Easy to add/modify steps
prompts:
templates:
issues:
analyze: "issues/analyze.md" # Step 1: Analysis
respond: "issues/respond.md" # Step 2: ResponseSee Chained Prompts Guide for implementation details.
A cron job runs every hour to find and process issues that may have been missed by webhooks:
- Smart Detection - Finds issues older than 30 minutes without
clide-analyzedlabel - Same Quality - Uses identical chained prompt analysis as webhooks
- Safety Mechanisms - Rate limiting and concurrent execution prevention
- Comprehensive Logging - Detailed logs for monitoring and debugging
# Test mode (find issues without processing)
python3 scripts/analyze_missed_issues.py --dry-run
# Process issues older than 1 hour
python3 scripts/analyze_missed_issues.py --min-age 60
# Check what would be processed
python3 scripts/analyze_missed_issues.py --dry-run --min-age 30cron_analysis:
enabled: true
min_age_minutes: 30 # Only process issues older than 30 minutes
max_issues_per_repo: 10 # Safety limit per repository
delay_between_issues: 2 # Seconds between processingSee Cron Jobs Documentation for complete setup guide.
# Check processing status
curl http://localhost:8000/stats
# Monitor webhook logs
tail -f logs/webhook.log
# Monitor cron job logs
tail -f logs/cron-analyze.log- Processing Success Rate - Percentage of successful webhook processing
- Average Response Time - Time from webhook to completed analysis
- Issues Processed - Total issues analyzed (webhooks + cron)
- API Rate Limits - GitHub and Claude API usage tracking
- Architecture Guide - Detailed system architecture and components
- Architecture V2 - Enhanced multi-project webhook architecture
- Installation Guide - Step-by-step installation instructions
- Configuration Guide - Comprehensive configuration documentation
- Deployment Guide - Complete deployment instructions and options
- Development Guide - Local development setup and best practices
- Chained Prompts Guide - Multi-step prompt implementation
- Cron Jobs Documentation - Backup processing system
- Auto-Accept Invitations - Automatic repository invitation handling
- Nginx Proxy Configuration - Nginx setup for webhook proxying
- Nginx Proxy Manager Config - NPM configuration details
- Nginx Proxy Manager - Using Nginx Proxy Manager
- Startup Scripts - Service management and automation
- Monitoring Guide - System monitoring and observability
- Integration Plan - Integration strategies and planning
- Claude Code Guide - Instructions for Claude Code when working with this repository
- Limitations & Improvements - Known issues and enhancement recommendations
- Test PR Description - Example PR description for testing
- Example Configuration - Comprehensive configuration template
- Environment Variables - Environment variable template
GET /health- Health check and service statusPOST /webhook- GitHub webhook receiver (configurable path)GET /stats- Processing statistics and metrics
| Event Type | Description | Actions |
|---|---|---|
issues |
Issue lifecycle events | Analysis, labeling, commenting |
pull_request |
Pull request events | Review, labeling, size estimation |
pull_request_review |
PR review events | Response generation, analysis |
workflow_run |
GitHub Actions events | Failure analysis, reporting |
push |
Code push events | Commit analysis, change summary |
release |
Release events | Release quality analysis |
deployment |
Deployment events | Deployment readiness assessment |
fork |
Repository fork events | Fork tracking and analysis |
star |
Star/unstar events | Star tracking (lightweight) |
watch |
Watch/unwatch events | Watch tracking (lightweight) |
member |
Member access changes | Access change analysis |
team |
Team events | Team change analysis |
project |
Project board events | Project management analysis |
milestone |
Milestone events | Milestone progress analysis |
commit_comment |
Commit comments | Comment analysis |
| Generic Handler | Any unsupported event | Fallback analysis for all events |
Note: The system includes a GenericHandler that automatically processes any GitHub webhook event not explicitly supported, ensuring comprehensive coverage.
hls/
βββ webhook_dispatch.py # Entry point called by webhook service
βββ setup_github_webhook.py # GitHub webhook setup script
βββ install.sh # Installation script
βββ README.md # This file
βββ requirements.txt # Python dependencies
βββ venv/ # Python virtual environment
βββ archive/ # Archived configuration files
β βββ nginx-configs/ # Legacy nginx configurations
βββ config/ # Configuration files
β βββ settings.yaml # Main configuration
β βββ settings.example.yaml # Configuration template
β βββ settings.yaml.backup # Configuration backup
β βββ crontab.txt # Cron job configuration
βββ docs/ # All documentation
β βββ ARCHITECTURE.md # System architecture
β βββ ARCHITECTURE_V2.md # Enhanced architecture
β βββ CLAUDE.md # Claude Code guidance
β βββ DEPLOYMENT.md # Deployment instructions
β βββ INSTALLATION.md # Installation guide
β βββ CONFIGURATION.md # Configuration guide
β βββ DEVELOPMENT.md # Development setup
β βββ MONITORING.md # Monitoring and observability
β βββ CHAINED_PROMPTS.md # Multi-step prompt guide
β βββ CRON_JOBS.md # Backup processing system
β βββ LIMITATIONS.md # Known issues and improvements
β βββ ... # Other documentation files
βββ examples/ # Code examples
β βββ enable_chained_prompts.py
βββ hls/ # Core application code
β βββ src/hsl_handler/ # Main handler modules
β β βββ main.py # FastAPI application (optional)
β β βββ webhook_processor.py # Core processing logic
β β βββ handlers.py # Event-specific handlers
β β βββ chained_handlers.py # Chained prompt handlers
β β βββ clients.py # API clients (Claude, GitHub)
β β βββ config.py # Configuration management
β β βββ prompts.py # Template management
β β βββ logging_config.py # Logging setup
β βββ tests/ # Test files for core modules
βββ logs/ # Application and service logs
β βββ webhook.log # Current webhook logs
β βββ webhook_archive_*.log # Archived webhook logs
β βββ ... # Other log files
βββ outputs/ # Analysis output files
β βββ issues/ # Issue analysis results
β βββ pull_requests/ # PR analysis results
β βββ ... # Other event outputs
βββ prompts/ # Jinja2 prompt templates
β βββ issues/ # Issue analysis prompts
β βββ pull_requests/ # PR analysis prompts
β βββ reviews/ # Review response prompts
β βββ workflows/ # Workflow analysis prompts
β βββ releases/ # Release announcement prompts
β βββ deployment/ # Deployment event prompts
β βββ generic/ # Generic event prompts
β βββ push/ # Push event prompts
βββ scripts/ # Utility and maintenance scripts
β βββ analyze_missed_issues.py
β βββ auto_accept_invitations.py
β βββ setup_new_repository.py
β βββ cron_*.sh # Cron job scripts
βββ services/ # Service configurations
β βββ README.md # Service documentation
β βββ hooks.json # Webhook service configuration
β βββ systemd/ # Systemd service files
β β βββ hls-webhook.service
β β βββ github-webhook.service
β β βββ hls-fastapi.service
β βββ pm2/ # PM2 configuration
β β βββ ecosystem.config.js
β βββ scripts/ # Service management scripts
β βββ start-webhook.sh
β βββ stop-webhook.sh
β βββ install-services.sh
β βββ test-services.sh
βββ test/ # Test files and payloads
βββ test_*.py # Python test scripts
βββ test_*.json # Test payloads
βββ create_*.json # Test creation templates
When a new issue is created on GitHub:
- GitHub sends webhook to
https://your-domain.com/hooks/github-webhook - nginx receives HTTPS request and proxies to webhook service on port 9000
- webhook service validates the request matches
services/hooks.jsonrules - webhook service executes
webhook_dispatch.pywith:- JSON payload as command argument
- GitHub headers as environment variables
- webhook_dispatch.py:
- Loads settings from
config/settings.yaml - Validates webhook signature (HMAC-SHA256)
- Checks repository and event configuration
- Initializes WebhookProcessor from
hls/src/hsl_handler/
- Loads settings from
- WebhookProcessor routes to appropriate handler (e.g., IssueHandler, PushHandler, GenericHandler)
- Handler processes event:
- Loads Jinja2 prompt template from
prompts/directory - Sends prompt to Claude AI for analysis (with repository context)
- Parses Claude's response for labels and actions
- Saves analysis to
outputs/directory
- Loads Jinja2 prompt template from
- GitHub API updates (if configured):
- Applies suggested labels
- Posts analysis comment
- Marks issue as analyzed with
clide-analyzedlabel
- Response returned to GitHub with processing status
Edit templates in the prompts/ directory to customize Claude's analysis:
{# prompts/issues/analyze.j2 #}
Analyze this GitHub issue for {{ repository.name }}:
Title: {{ issue.title }}
Body: {{ issue.body }}
Author: {{ issue.user.login }}
Provide:
1. Priority (high/medium/low)
2. Difficulty (easy/moderate/complex)
3. Component (frontend/backend)
4. Suggested labelsConfigure different behavior per repository:
repositories:
- name: "org/frontend-repo"
events: ["issues", "pull_request"]
labels:
categories: ["bug", "enhancement", "ui-ux"]
- name: "org/backend-repo"
events: ["issues", "pull_request", "workflow_run"]
labels:
categories: ["bug", "enhancement", "performance", "security"]curl http://localhost:8000/healthcurl http://localhost:8000/statstail -f logs/hsl.log- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
- SSL/TLS termination by nginx for encrypted webhook delivery
- Webhook signatures validated using HMAC-SHA256
- Process isolation with webhook service running dispatch script
- Virtual environment isolates Python dependencies
- API keys stored in configuration files (use proper file permissions)
- No sensitive data logged by default
- Rate limiting prevents API abuse
[Add your license here]
For issues and questions:
- Check the Limitations document for known issues
- Review the Architecture document for system details
- Consult the Deployment guide for setup help
- Open an issue in this repository
See LIMITATIONS.md for planned improvements:
- Webhook deduplication
- Cost management and budgeting
- Enhanced monitoring and alerting
- Context retention across related events