This guide explains how to set up Gmail push notifications using Google Cloud Pub/Sub to replace polling with real-time updates.
Instead of polling Gmail every 2-5 minutes, this implementation uses Gmail's push notification system to receive real-time updates when new emails arrive. This is more efficient and provides instant notifications.
- Google Cloud Project with billing enabled
- Gmail API enabled in your project
- Cloud Pub/Sub API enabled
# Using gcloud CLI
gcloud pubsub topics create gmail-notifications
# Or via Cloud Console
# Go to Cloud Pub/Sub > Topics > Create Topic
# Name: gmail-notifications# For webhook push (recommended)
gcloud pubsub subscriptions create gmail-webhook-sub \
--topic=gmail-notifications \
--push-endpoint=https://yourdomain.com/api/gmail-webhook
# Or for pull subscription
gcloud pubsub subscriptions create gmail-pull-sub \
--topic=gmail-notificationsGrant publish rights to Gmail API service account:
gcloud pubsub topics add-iam-policy-binding gmail-notifications \
--member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
--role=roles/pubsub.publisherOr via Cloud Console:
- Go to Cloud Pub/Sub > Topics > gmail-notifications
- Click "PERMISSIONS" tab
- Click "ADD PRINCIPAL"
- Principal:
gmail-api-push@system.gserviceaccount.com - Role:
Pub/Sub Publisher
Add to your .env.local:
# Your Cloud Pub/Sub topic name (replace zero-455106 with your actual project ID)
NEXT_PUBLIC_GMAIL_TOPIC_NAME=projects/zero-455106/topics/gmail-notifications
# Optional: Webhook verification token
GMAIL_WEBHOOK_TOKEN=your-secret-tokenThe webhook endpoint is already created at /api/gmail-webhook. Make sure your application is deployed and accessible at the URL you specified in the subscription.
- Start your application
- Sign in with Gmail
- Navigate to the emails page
- The system will automatically set up the watch request
- Check the status indicator in the header (should show "Live" with green dot)
When a user visits the emails page, the system:
- Calls Gmail API
watchendpoint - Registers your Pub/Sub topic for notifications
- Stores the
historyIdfor tracking changes
When Gmail detects changes:
- Sends notification to your Pub/Sub topic
- Pub/Sub delivers to your webhook endpoint
- Your app receives the notification with new
historyId
Your webhook endpoint:
- Decodes the base64-encoded notification data
- Extracts
emailAddressandhistoryId - Can trigger cache invalidation or real-time updates
/api/gmail-webhook- Handles incoming push notifications/api/gmail-watch- Manages watch setup/teardownuseGmailNotificationshook - React hook for notification management- Updated emails page - Integrated push notification setup
- Automatic setup: Watch is set up automatically when viewing emails
- Auto-renewal: Watch is renewed every 6 days (expires in 7 days)
- Fallback polling: Falls back to 5-minute polling if push fails
- Status indicator: Shows live/manual status in the UI
- Persistent state: Remembers watch status across browser sessions
# The Gmail API doesn't provide a direct way to check watch status
# Status is stored in localStorage and server logs- Go to Cloud Pub/Sub in Google Cloud Console
- Select your topic/subscription
- View delivery metrics and error rates
- Permission denied: Ensure Gmail service account has publisher role
- Webhook unreachable: Verify your domain is accessible and HTTPS
- Topic not found: Check topic name matches exactly
- Watch expires: Implement auto-renewal (already included)
- Cloud Pub/Sub pricing: ~$0.40 per million messages
- Gmail API quota: 250 quota units per user per second
- Much more cost-effective than constant polling
- Webhook endpoint validates message format
- Consider adding webhook token verification
- Use HTTPS for all endpoints
- Implement rate limiting on webhook endpoint
- Set up your Cloud Pub/Sub topic and subscription
- Update the topic name in environment variables
- Deploy your application
- Test with real Gmail account
- Monitor for successful notifications
The system will automatically handle:
- Setting up watch requests
- Renewing expired watches
- Falling back to polling if needed
- Showing status to users
This replaces the previous 2-minute polling with real-time push notifications, providing better user experience and lower resource usage.