This application automates posting daily summaries to LinkedIn about GitHub events using AI-generated, humanized content.
- Monitors GitHub webhooks for releases, commits (pushes), repository changes, and organization events
- Accumulates events throughout the day and posts a single daily summary at 6 PM UTC
- Uses Groq (free LLM) to generate and humanize engaging LinkedIn posts
- Automatically posts to LinkedIn
- Comprehensive Logging: Every action logged with detailed information
- Review System: Manual approval required before posting (configurable)
- Auto-Recovery: Handles missed posts when computer shuts down
- Auto-Startup: Windows batch script for automatic launch on boot
- Modular Architecture: 8 well-documented modules for maintainability
Yes! Groq offers a generous free tier:
- Free Credits: New users get free credits to start
- Mixtral Model: Uses the free Mixtral-8x7B model
- Rate Limits: Reasonable limits for personal use
- No Credit Card Required: Sign up at https://console.groq.com/
git clone <your-repo-url>
cd github-social-automation
pip install -r requirements.txt- Go to https://console.groq.com/
- Sign up for a free account
- Create an API key
- Copy the API key
- Go to GitHub → Settings → Developer settings → Personal access tokens
- Generate new token with these permissions:
repo(Full control of private repositories)admin:repo_hook(for webhooks)admin:org_hook(for organization webhooks)read:org(for organization info)
- Copy the token
Note: For organization-wide monitoring, ensure the token has access to the organization and all repositories you want to monitor.
Option A: Automated Setup (Recommended)
# First, fix the redirect URI to match your LinkedIn app
python fix_linkedin_redirect.py
# Then get your access token
python linkedin_oauth_helper.pyWhat these scripts do:
fix_linkedin_redirect.py: Updates the redirect URI to match your LinkedIn app settingslinkedin_oauth_helper.py: Opens browser, handles OAuth flow, gives you the access token
Option B: Manual Setup
- Go to https://developer.linkedin.com/
- Create a new app with these settings:
- App name: "GitHub Social Automation"
- LinkedIn page: Select your personal/company page
- App logo: Upload any image
- In "Auth" tab:
- Redirect URLs:
http://localhost:8000/callback - Scopes:
w_member_social(for posting)
- Redirect URLs:
- Copy Client ID and Client Secret to
.env - Use OAuth tool or Postman to get access token
Option C: Use Existing Token
If you already have a LinkedIn access token, just paste it in .env
Option D: Pipedream Integration (Easiest & Most Reliable) Skip all LinkedIn OAuth complications! Use Pipedream for serverless LinkedIn posting:
- Sign up at https://pipedream.com/ (free)
- Create workflow: HTTP Trigger → LinkedIn Post
- Copy the Pipedream webhook URL
- Your automation sends content to Pipedream
- Pipedream handles LinkedIn posting automatically
See detailed guide: pipedream_setup.md
Benefits:
- ✅ Zero server management
- ✅ No OAuth headaches
- ✅ Handles LinkedIn auth automatically
- ✅ 1000 free requests/month
- ✅ Visual workflow builder
- ✅ Enterprise reliability
Create a .env file:
# GitHub Configuration
GITHUB_TOKEN=your_github_token_here
GITHUB_WEBHOOK_SECRET=your_random_secret_string
# LinkedIn Configuration
LINKEDIN_ACCESS_TOKEN=your_linkedin_access_token
# Groq Configuration (Free!)
GROQ_API_KEY=your_groq_api_key_here
# Optional: Change daily post time (UTC)
DAILY_POST_TIME=18:00Create a random secret for webhook security:
python -c "import secrets; print(secrets.token_hex(32))"Use this as GITHUB_WEBHOOK_SECRET
python app.pyThe app will start on http://localhost:5000
Since webhooks require a publicly accessible endpoint, here are several options:
Best for testing and development
- Install ngrok: Download from https://ngrok.com/download
- Run your app:
python app.py - Expose locally:
ngrok http 5000 - Copy the HTTPS URL (e.g.,
https://abc123.ngrok.io) - Use as Payload URL:
https://abc123.ngrok.io/webhook
Note: Free ngrok URLs change on restart. For production, use ngrok auth token.
Serverless deployment using GitHub's infrastructure
- Create GitHub repository for your automation
- Add workflow file
.github/workflows/deploy.yml:
name: Deploy Webhook Handler
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to Railway/Render/Vercel
# Add deployment steps here- Sign up at https://railway.app
- Connect GitHub repo
- Deploy automatically
- Get your domain (e.g.,
your-app.railway.app) - Use as Payload URL:
https://your-app.railway.app/webhook
- Sign up at https://render.com
- Create Web Service from GitHub repo
- Deploy Flask app
- Get your domain
- Use as Payload URL
- Sign up at https://vercel.com
- Deploy from GitHub
- Get your domain
- Use as Payload URL
For testing without public access
- Run locally:
python app.py - Test webhooks using GitHub's webhook delivery page
- Use tools like webhook.site or ngrok for temporary testing
- Install ngrok from https://ngrok.com/download
- Get ngrok auth token from https://dashboard.ngrok.com/get-started/your-authtoken
- Run:
ngrok config add-authtoken YOUR_TOKEN - Fill in your API keys in the
.envfile - Run the automated setup:
python setup_ngrok.py - The script automatically:
- ✅ Starts your Flask app
- ✅ Launches ngrok tunnel
- ✅ Tests everything is working
- ✅ Provides your webhook URL
- ✅ Keeps everything running
Alternative Manual Setup:
- Install ngrok
- Run your app locally:
python app.py - Start ngrok:
ngrok http 5000 - Use ngrok URL as payload URL in GitHub webhook
- Test by making commits and checking webhook deliveries
- Go to your GitHub Organization → Settings → Webhooks
- Click "Add webhook"
- Payload URL:
https://your-domain.com/webhook(your server's webhook endpoint) - Content type:
application/json - Secret: Use your
GITHUB_WEBHOOK_SECRET - Which events would you like to trigger this webhook?: Select "Send me everything" or choose:
- Push
- Release
- Repository
- Organization
- Click "Add webhook"
- Go to specific Repository → Settings → Webhooks
- Follow same steps as above
- This will only monitor the single repository
- Make a commit/push to test GitHub webhooks
- Check http://localhost:5000/health for status
- Check http://localhost:5000/stats for event counts
- Wait for 6 PM UTC to see the daily summary post
- Monitors one specific repository
- Webhooks configured per repository
- Daily summary for that repository's activity
- Monitors ALL repositories in your organization
- Single webhook at organization level
- Aggregates activity from all repos into one daily summary
- More comprehensive overview of organizational activity
Webhooks are HTTP callbacks triggered by events. Instead of constantly polling for changes, GitHub sends an HTTP POST request to your server when events occur. Your application receives these events in real-time and processes them.
The Payload URL is the webhook endpoint where GitHub sends HTTP POST requests containing event data. It's your server's URL that receives the webhook payloads.
Example: https://your-server.com/webhook
When you push code to GitHub, it sends a POST request to this URL with JSON data about the push event.
├── app.py # Main Flask application
├── config.py # Configuration management
├── ai_processor.py # AI content generation (Groq)
├── event_manager.py # Event storage and retrieval
├── linkedin_poster.py # LinkedIn API integration
├── github_handler.py # GitHub webhook processing
├── scheduler.py # Daily posting scheduler
├── setup_ngrok.py # Ngrok setup helper script
├── test.py # Unit tests
├── requirements.txt # Python dependencies
├── .env # Environment variables (not committed)
└── README.md # This file
- Event Collection: GitHub sends webhook events → saved to daily JSON files
- Daily Processing: At 6 PM UTC, AI generates summary from events
- Humanization: Content is rewritten to sound natural and professional
- Posting: Summary posted to LinkedIn automatically
- Archiving: Events file archived after posting
POST /webhook- Receives GitHub webhook eventsGET /health- Health check and configuration infoGET /stats- Event statistics for today
"Traffic successfully made it to the ngrok agent, but the agent failed to establish a connection to the upstream web service"
This means ngrok is working but your Flask app isn't running on localhost:5000.
Solutions:
- Make sure Flask app is running: Run
python app.pyin another terminal first - Check port availability: Run
netstat -ano | findstr :5000to see if port is in use - Use the setup script: Run
python setup_ngrok.pywhich starts both automatically - Change port: Set
PORT=5001in.envand update ngrok command tongrok http 5001
- Webhook not working: Check webhook delivery in GitHub settings
- Posts not appearing: Verify LinkedIn token permissions
- AI errors: Check Groq API key and credits
- Port issues: Change PORT in .env if 5000 is occupied
- ngrok URLs change: Get auth token for persistent URLs
For production use:
- Use a proper WSGI server (gunicorn)
- Set up HTTPS
- Use environment variables instead of .env file
- Set up monitoring and logging
- Configure firewall and security groups