230 lines
5.1 KiB
Markdown
230 lines
5.1 KiB
Markdown
# Library Availability Monitor
|
|
|
|
A Node.js service that monitors San Diego libraries for parking pass availability and sends notifications via ntfy when passes become available at the desired branch.
|
|
|
|
## Features
|
|
|
|
- 📚 Monitors specific library book availability via BiblioCommons API
|
|
- 📱 Sends push notifications via ntfy when new books become available
|
|
- ⏰ Polls hourly and tracks availability changes
|
|
- 🔄 Graceful error handling and recovery
|
|
- 🧪 Comprehensive testing suite
|
|
- 🎭 Mock testing capabilities
|
|
- 🚀 Easy deployment to Linux servers
|
|
|
|
## Setup
|
|
|
|
### Prerequisites
|
|
|
|
- Node.js 18+
|
|
- npm
|
|
- SSH access to deployment server (optional)
|
|
|
|
### Installation
|
|
|
|
1. Clone or download this repository
|
|
2. Install dependencies:
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
3. Configure your ntfy settings in `index.js`:
|
|
```javascript
|
|
const CONFIG = {
|
|
NTFY_TOPIC: 'your-topic-name',
|
|
NTFY_SERVER: 'https://ntfy.sh', // or your own server
|
|
// ... other settings
|
|
};
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Running the Monitor
|
|
|
|
```bash
|
|
# Start the monitor
|
|
npm start
|
|
|
|
# Development mode with auto-restart
|
|
npm run dev
|
|
```
|
|
|
|
### Testing
|
|
|
|
```bash
|
|
# Run all tests
|
|
npm test
|
|
|
|
# Validate against real API response example
|
|
npm run validate
|
|
|
|
# Interactive mock testing
|
|
npm run mock
|
|
|
|
# Simulate availability changes
|
|
node mock.js test 3 # Simulate 3 available books
|
|
node mock.js notify # Send test notification
|
|
node mock.js status # Show current state
|
|
node mock.js reset # Reset state file
|
|
```
|
|
|
|
### Deployment
|
|
|
|
The included deployment script uploads and manages the service on a remote Linux server:
|
|
|
|
```bash
|
|
# Deploy to configured server
|
|
npm run deploy
|
|
|
|
# Or run directly
|
|
./deploy.sh
|
|
```
|
|
|
|
#### Deployment Setup
|
|
|
|
1. Configure SSH access to your server as 'linode' in `~/.ssh/config`:
|
|
```
|
|
Host linode
|
|
HostName your-server-ip
|
|
User your-username
|
|
IdentityFile ~/.ssh/your-key
|
|
```
|
|
|
|
2. The deployment script will:
|
|
- Upload files to `/opt/sd-park-pass-ntfy`
|
|
- Install dependencies
|
|
- Create and start a systemd service
|
|
- Enable auto-start on boot
|
|
|
|
## Configuration
|
|
|
|
### Main Configuration (index.js)
|
|
|
|
```javascript
|
|
const CONFIG = {
|
|
API_URL: 'https://gateway.bibliocommons.com/v2/libraries/sandiego/bibs/S161C1805116/availability',
|
|
BRANCH_NAME: 'Rancho Penasquitos',
|
|
NTFY_TOPIC: 'sdparkpass',
|
|
NTFY_SERVER: 'https://ntfy.sh',
|
|
POLL_INTERVAL: '0 * * * *', // Every hour
|
|
// ...
|
|
};
|
|
```
|
|
|
|
### Systemd Service
|
|
|
|
The service runs as user `nobody` for security and includes:
|
|
- Automatic restart on failure
|
|
- Proper logging via journald
|
|
- Security hardening
|
|
- Environment isolation
|
|
|
|
View logs:
|
|
```bash
|
|
sudo journalctl -u sd-park-pass-ntfy -f
|
|
```
|
|
|
|
## API Response Format
|
|
|
|
The monitor expects BiblioCommons API responses in this format:
|
|
|
|
```json
|
|
{
|
|
"entities": {
|
|
"bibItems": {
|
|
"1805116|31336107103179||76": {
|
|
"collection": "Adult - Circulation Desk",
|
|
"callNumber": "CA STATE LIBRARY PARKS PASS HIKING BACKPACK",
|
|
"itemId": "1805116|31336107103179||76",
|
|
"branch": {
|
|
"name": "Rancho Penasquitos",
|
|
"code": "29"
|
|
},
|
|
"availability": {
|
|
"status": "AVAILABLE",
|
|
"statusType": "AVAILABLE",
|
|
"libraryStatus": "Available"
|
|
},
|
|
"branchName": "Rancho Penasquitos",
|
|
"dueDate": null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
The monitor looks for:
|
|
- Items with `branchName` containing "Rancho Penasquitos"
|
|
- Items with `availability.statusType` NOT equal to "UNAVAILABLE"
|
|
- Available status types include: "AVAILABLE", "RECENTLY_RETURNED"
|
|
|
|
## State Management
|
|
|
|
The monitor tracks availability in `last_availability.json`:
|
|
|
|
```json
|
|
{
|
|
"availabilityCount": 2,
|
|
"lastUpdated": "2025-07-13T10:00:00.000Z",
|
|
"previousCount": 1,
|
|
"branch": "Rancho Penasquitos",
|
|
"apiUrl": "https://..."
|
|
}
|
|
```
|
|
|
|
## Notification Types
|
|
|
|
- 📚 **High Priority**: New books became available
|
|
- ⚠️ **Low Priority**: Errors or status changes
|
|
- 🔴 **Service Events**: Start/stop notifications
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **No notifications received**:
|
|
- Check ntfy topic subscription on your phone
|
|
- Verify NTFY_SERVER and NTFY_TOPIC settings
|
|
- Test with `node mock.js notify`
|
|
|
|
2. **API errors**:
|
|
- Check network connectivity
|
|
- Verify API URL is still valid
|
|
- Monitor rate limiting
|
|
|
|
3. **Service not starting**:
|
|
- Check file permissions
|
|
- Review systemd logs: `journalctl -u sd-park-pass-ntfy`
|
|
- Ensure Node.js is installed on server
|
|
|
|
### Mock Testing
|
|
|
|
Use the mock script to verify functionality:
|
|
|
|
```bash
|
|
# Interactive mode
|
|
node mock.js
|
|
|
|
# Commands in interactive mode:
|
|
> test 5 # Simulate 5 available books
|
|
> notify # Send test notification
|
|
> status # Show current state
|
|
> reset # Clear state file
|
|
> quit # Exit
|
|
```
|
|
|
|
## Files
|
|
|
|
- `index.js` - Main application
|
|
- `test.js` - Test suite
|
|
- `mock.js` - Mock testing script
|
|
- `validate-real-response.js` - Validates parsing against real API response
|
|
- `deploy.sh` - Deployment script
|
|
- `sd-park-pass-ntfy.service` - Systemd service file
|
|
- `test-config.js` - Test configuration and mock data
|
|
- `example-response.json` - Real API response example for reference
|
|
|
|
## License
|
|
|
|
ISC
|