Overview
The cron system performs the following tasks:- Checks for expired subscriptions every hour
- Removes users from the Telegram channel by banning them
- Deletes MetaCopier accounts for premium users
- Sends expiry notifications to removed users
- Updates the database to mark subscriptions as removed
The cron job runs automatically when deployed on Vercel. No manual configuration needed after setup.
Cron Endpoint
The cron job is implemented as an API route: Endpoint:/api/cron/remove-expired
File: src/app/api/cron/remove-expired/route.ts
Methods: GET and POST (POST is for manual testing)
Schedule: Every hour (0 * * * * in cron syntax)
How It Works
Here’s the step-by-step flow when the cron job runs:1. Find Expired Subscriptions
src/app/api/cron/remove-expired/route.ts
2. Process Each Expired Subscription
For each expired user:3. Return Results
Vercel Cron Configuration
To enable automatic hourly execution on Vercel, create avercel.json file in your project root:
vercel.json
The API route to call (always
/api/cron/remove-expired)Cron expression for the schedule. Format:
minute hour day month weekdayExamples:0 * * * *- Every hour at minute 0*/30 * * * *- Every 30 minutes0 */6 * * *- Every 6 hours0 0 * * *- Daily at midnight0 2 * * *- Daily at 2 AM
Customizing the Schedule
Run Every 30 Minutes
vercel.json
Run Every 6 Hours
vercel.json
Run Daily at 2 AM
vercel.json
More frequent runs consume more serverless function invocations. Hourly is recommended for balancing timely removals with resource usage.
Manual Testing
You can manually trigger the cron job for testing:Using cURL
Using Browser
Simply visit:Expected Response
Total number of expired subscriptions found
Number of users successfully removed from channel
Number of removals that failed (will retry next run)
ISO 8601 timestamp when the cron job ran
Error Handling
The cron job implements robust error handling:MetaCopier Removal Failures
If MetaCopier account deletion fails, the admin receives a notification:Telegram Ban Failures
If banning a user fails:- The subscription is not marked as removed
- The failure is logged and counted
- The job will retry on the next run
Database Errors
If the database query fails, the endpoint returns:Monitoring
Check Vercel Cron Logs
- Go to Vercel Dashboard
- Select your project
- Navigate to Deployments → Functions
- Click on
/api/cron/remove-expired - View execution logs and metrics
Database Monitoring
Query removed subscriptions:isRemoved: trueremovedAt: [recent date range]
Admin Notifications
The cron job sends Telegram messages to the admin (configured inADMIN_ID) when:
- MetaCopier removal fails
- Critical errors occur during processing
Best Practices
Performance Tips:
- The cron job processes all expired subscriptions in a single run
- Failed removals are automatically retried on the next scheduled run
- Running every hour balances timeliness with serverless function usage
- Consider more frequent runs (every 30 minutes) for high-volume operations
Troubleshooting
Cron Job Not Running
- Check
vercel.jsonexists in project root - Verify deployment includes the cron configuration
- Review Vercel logs for errors
- Ensure endpoint returns 200 status code
Users Not Being Removed
- Check bot permissions in the Telegram channel
- Verify
TELEGRAM_BOT_TOKENis correct - Review database - are subscriptions actually expired?
- Check
isRemovedflag - might already be processed
Too Many Failed Removals
- Check Telegram API rate limits (20 requests/second)
- Verify bot hasn’t been removed from the channel
- Review error logs for specific failure reasons
- Consider adding retry delays between removals
Duplicate Removals
The system prevents duplicates by:- Checking
isRemoved: falsebefore processing - Setting
isRemoved: trueimmediately after successful removal - Using database transactions for atomicity
Advanced Configuration
For more control, you can modify the cron job behavior insrc/app/api/cron/remove-expired/route.ts:
Add Grace Period
Batch Processing
Custom Notifications
Modify the expiry message sent to users in thesendMessage call within the route handler.