Facebook/Instagram Webhook Setup Guide
Quick Start
Follow these steps to set up webhooks for receiving real-time social media insights.
Prerequisites
- Facebook App with Instagram Basic Display or Instagram Graph API
- Public HTTPS endpoint (production) or ngrok (development)
- Environment variables configured
Step 1: Configure Environment Variables
Add to your .env file:
# Facebook App Secret (from App Dashboard → Settings → Basic)
FACEBOOK_APP_SECRET=your_app_secret_here
# Webhook Verify Token (create a random string)
FACEBOOK_WEBHOOK_VERIFY_TOKEN=your_random_secure_token_here
# Your public URL (for production)
WEBHOOK_BASE_URL=https://yourdomain.com
Generate Verify Token
# Generate a random secure token
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Step 2: Set Up Local Development (Optional)
Using ngrok
# Install ngrok
npm install -g ngrok
# Start your Medusa server
npm run dev
# In another terminal, start ngrok
ngrok http 9000
# Copy the HTTPS URL (e.g., https://abc123.ngrok.io)
Your webhook URL will be: https://abc123.ngrok.io/webhooks/social/facebook
Step 3: Configure Facebook App Webhooks
3.1 Go to Facebook App Dashboard
- Visit: https://developers.facebook.com/apps
- Select your app
- Go to Products → Webhooks
3.2 Add Webhook Subscription
For Facebook Pages:
- Click Add Subscription under Page
- Enter:
- Callback URL:
https://yourdomain.com/webhooks/social/facebook - Verify Token: Same as
FACEBOOK_WEBHOOK_VERIFY_TOKEN
- Callback URL:
- Click Verify and Save
For Instagram:
- Click Add Subscription under Instagram
- Enter:
- Callback URL:
https://yourdomain.com/webhooks/social/facebook - Verify Token: Same as
FACEBOOK_WEBHOOK_VERIFY_TOKEN
- Callback URL:
- Click Verify and Save
3.3 Subscribe to Fields
Facebook Page Fields:
- ✅
feed- Post updates (new, edited, deleted) - ✅
posts- Post insights - ✅
comments- New comments - ✅
reactions- New reactions - ✅
mention- Page mentions
Instagram Fields:
- ✅
comments- New comments - ✅
mentions- Story mentions - ✅
live_comments- Live video comments
Step 4: Test Webhook Verification
Test GET Endpoint (Verification)
curl "https://yourdomain.com/webhooks/social/facebook?hub.mode=subscribe&hub.challenge=test123&hub.verify_token=YOUR_VERIFY_TOKEN"
Expected Response: test123 (the challenge value)
Check Server Logs
You should see:
Webhook verified successfully
Step 5: Test Webhook Events
Test POST Endpoint (Event Receiver)
# Create a test payload
curl -X POST https://yourdomain.com/webhooks/social/facebook \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=$(echo -n '{"object":"page","entry":[]}' | openssl dgst -sha256 -hmac 'YOUR_APP_SECRET' | cut -d' ' -f2)" \
-d '{"object":"page","entry":[]}'
Expected Response: EVENT_RECEIVED
Step 6: Subscribe Pages/Accounts
Subscribe a Facebook Page
curl -X POST "https://graph.facebook.com/v24.0/PAGE_ID/subscribed_apps" \
-d "subscribed_fields=feed,posts,comments,reactions" \
-d "access_token=PAGE_ACCESS_TOKEN"
Subscribe an Instagram Account
curl -X POST "https://graph.facebook.com/v24.0/IG_USER_ID/subscribed_apps" \
-d "subscribed_fields=comments,mentions" \
-d "access_token=PAGE_ACCESS_TOKEN"
Step 7: Monitor Webhooks
Check Facebook App Dashboard
- Go to Webhooks in your app
- Click View Events next to your subscription
- Monitor:
- Delivery status
- Response times
- Error logs
Check Your Server Logs
Look for:
Webhook received: { object: 'page', entries: 1, timestamp: 1234567890 }
Processing page event: { pageId: '...', changes: 1 }
Feed change: { pageId: '...', postId: '...', verb: 'add' }
Step 8: Test Real Events
Test Facebook Post
- Create a post on your Facebook Page
- Check webhook logs for event
- Verify post insights are updated in database
Test Instagram Post
- Create a post on Instagram Business Account
- Check webhook logs for event
- Verify post data is updated
Test Comments
- Comment on a Facebook/Instagram post
- Check webhook logs
- Verify comment is stored in post insights
Troubleshooting
Webhook Verification Fails
Problem: Facebook shows "Verification Failed"
Solutions:
- Check
FACEBOOK_WEBHOOK_VERIFY_TOKENmatches exactly - Ensure endpoint is publicly accessible (HTTPS)
- Check server logs for errors
- Test GET endpoint manually with curl
No Events Received
Problem: Webhook verified but no events coming through
Solutions:
- Check page/account is subscribed:
GET /PAGE_ID/subscribed_apps - Verify webhook fields are selected
- Check Facebook App is in Live mode (not Development)
- Ensure app has required permissions
Signature Validation Fails
Problem: Invalid signature error in logs
Solutions:
- Check
FACEBOOK_APP_SECRETis correct - Ensure you're using raw body (not parsed JSON)
- Verify header is
X-Hub-Signature-256(notX-Hub-Signature) - Check App Secret in Facebook App Dashboard
Events Not Processing
Problem: Events received but not updating database
Solutions:
- Check post exists in database
- Verify post has correct
facebook_post_idorinstagram_media_id - Check server logs for processing errors
- Ensure database permissions are correct
Production Deployment
1. Use HTTPS
Webhooks must use HTTPS in production:
- Use SSL certificate (Let's Encrypt, Cloudflare, etc.)
- Configure reverse proxy (Nginx, Caddy)
2. Update Webhook URL
In Facebook App Dashboard:
- Go to Webhooks
- Click Edit on subscription
- Update Callback URL to production URL
- Click Verify and Save
3. Monitor Performance
Set up monitoring for:
- Webhook delivery rate
- Response times
- Error rates
- Database updates
4. Handle High Volume
For high-traffic pages:
- Use queue system (Bull, BullMQ)
- Process events asynchronously
- Implement rate limiting
- Scale horizontally
Security Best Practices
1. Always Validate Signatures
// Never skip signature validation
if (!validateSignature(payload, signature, appSecret)) {
return res.status(401).send("Unauthorized")
}
2. Use Environment Variables
// Never hardcode secrets
const appSecret = process.env.FACEBOOK_APP_SECRET
const verifyToken = process.env.FACEBOOK_WEBHOOK_VERIFY_TOKEN
3. Respond Quickly
// Return 200 OK immediately
res.status(200).send("EVENT_RECEIVED")
// Process asynchronously
processWebhookEvent(body).catch(console.error)
4. Handle Retries
// Use idempotency keys
const eventId = `${entry.id}-${entry.time}`
if (await isProcessed(eventId)) {
return // Skip duplicate
}
await markProcessed(eventId)
5. Log Everything
console.log("Webhook received:", {
object: body.object,
entries: body.entry.length,
timestamp: Date.now(),
})
Webhook Event Examples
Facebook Post Created
{
"object": "page",
"entry": [{
"id": "PAGE_ID",
"time": 1234567890,
"changes": [{
"field": "feed",
"value": {
"item": "post",
"post_id": "PAGE_ID_POST_ID",
"verb": "add",
"published": 1,
"created_time": 1234567890,
"message": "Post content"
}
}]
}]
}
Instagram Comment
{
"object": "instagram",
"entry": [{
"id": "IG_USER_ID",
"time": 1234567890,
"changes": [{
"field": "comments",
"value": {
"media_id": "MEDIA_ID",
"id": "COMMENT_ID",
"text": "Comment text"
}
}]
}]
}
Next Steps
- ✅ Configure environment variables
- ✅ Set up ngrok for local testing
- ✅ Configure Facebook App webhooks
- ✅ Test verification endpoint
- ✅ Test event receiver
- ✅ Subscribe pages/accounts
- ✅ Monitor webhook delivery
- ✅ Deploy to production
Resources
Support
For issues:
- Check server logs
- Check Facebook App Dashboard → Webhooks → View Events
- Review troubleshooting section above
- Test with curl commands