A production-ready web application to monitor OpenTable restaurant availability. Features a user-friendly interface, automated checking, and Docker deployment support.
- Restaurant Search: Search OpenTable directly from the interface
- Flexible Configuration: Party size, date range, days of week, check frequency
- Two Modes: Single check or continuous monitoring
- Fast Parallel Checking: Multiple browser tabs for speed
- Production Ready: Security headers, rate limiting, validation, logging, Docker support
- Clickable Time Slots: Click any available time to book directly on OpenTable
- Node.js 18+ or Docker
# Install dependencies
npm install
# Copy environment file
cp .env.example .env
# Start development server
npm run dev# Build and run with Docker Compose
docker-compose up -d
# Or build manually
docker build -t opentable-monitor .
docker run -p 3001:3001 opentable-monitor- Open http://localhost:3001
- Search for a restaurant or paste an OpenTable URL
- Configure party size, date range, and days of week
- Click "Check Once" or "Start Continuous Monitoring"
- Click any available time slot to book on OpenTable
# Single check with default settings
npm run cli
# Continuous monitoring
npm run monitor
# Custom options
npm run cli -- --party=4 --days=14GET /health
GET /api/search?query=restaurant+name+city
POST /api/check
Content-Type: application/json
{
"restaurantUrl": "https://www.opentable.com/r/restaurant-name",
"restaurantName": "Restaurant Name",
"partySize": 2,
"daysToCheck": 30,
"concurrency": 6,
"openDays": [0, 1, 2, 3, 4, 5, 6]
}
POST /api/monitor/start
POST /api/monitor/stop/:sessionId
GET /api/results/:sessionId
GET /api/sessions
Environment variables (see .env.example):
| Variable | Default | Description |
|---|---|---|
PORT |
3001 | Server port |
NODE_ENV |
development | Environment mode |
LOG_LEVEL |
info | Logging level |
MAX_CONCURRENCY |
6 | Max parallel browser tabs |
MAX_DAYS_TO_CHECK |
90 | Max days allowed |
RATE_LIMIT_WINDOW_MS |
900000 | Rate limit window (15 min) |
RATE_LIMIT_MAX |
100 | Max requests per window |
CORS_ORIGINS |
- | Allowed origins (production) |
SLACK_WEBHOOK |
- | Slack notification URL |
NOTIFY_EMAIL |
- | Email for notifications |
When you click "Start Continuous Monitoring":
- The server starts checking the restaurant at your specified interval (e.g., every 30 minutes)
- Results are saved and displayed on the web interface
- If availability is found, notifications are sent via Slack and/or Email
- Monitoring continues until you click "Stop" or the server restarts
- Go to api.slack.com/apps
- Click Create New App → From scratch
- Name it "OpenTable Monitor" and select your workspace
- Go to Incoming Webhooks → Enable it
- Click Add New Webhook to Workspace
- Select the channel for notifications
- Copy the webhook URL and set it as
SLACK_WEBHOOKenvironment variable
- Enable 2FA on your Google account
- Go to Google App Passwords
- Create an app password for "Mail"
- Set these environment variables:
NOTIFY_EMAIL=your@email.com SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your@gmail.com SMTP_PASS=your-app-password
-
Create Railway Account: railway.app
-
Deploy from GitHub:
# Push to GitHub first git init git add . git commit -m "Initial commit" git remote add origin https://github.com/yourusername/opentable-monitor.git git push -u origin main
-
In Railway Dashboard:
- Click New Project → Deploy from GitHub repo
- Select your repository
- Railway auto-detects Node.js and deploys
-
Set Environment Variables (Railway Dashboard → Variables):
SLACK_WEBHOOK=https://hooks.slack.com/services/YOUR/WEBHOOK/URL -
Get Your URL: Railway provides a free
*.railway.appdomain
That's it! Railway handles everything else automatically.
# Create production .env
cp .env.example .env
# Edit .env with production values
# Start
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose down# Install production dependencies
npm ci --only=production
# Set environment
export NODE_ENV=production
# Start
npm startserver {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
}
}- Helmet.js: Security headers (CSP, XSS protection, etc.)
- Rate Limiting: Prevents abuse (100 requests per 15 minutes)
- Input Validation: All inputs validated and sanitized
- CORS: Configurable for production
- Non-root Docker: Container runs as unprivileged user
- Graceful Shutdown: Clean resource cleanup
opentable-monitor/
├── server.js # Production Express server
├── monitor.js # CLI monitoring tool
├── public/
│ └── index.html # Web interface
├── data/ # Saved results
├── Dockerfile # Production Docker image
├── docker-compose.yml # Docker Compose config
├── package.json
├── .env.example
└── README.md
# Install Chrome dependencies (Linux)
apt-get install -y chromium fonts-liberation libxss1- Reduce check frequency
- Increase
RATE_LIMIT_MAXfor trusted deployments
- Reduce
MAX_CONCURRENCY - Increase Docker memory limit
MIT
For personal use only. Use reasonable check intervals. Respect OpenTable's terms of service.