📋 Table of Contents
Why Use GitHub Actions for Cron Jobs?
If you need to capture a screenshot of a dashboard every morning, track competitor pricing daily, or maintain a visual archive of your homepage over time, setting up dedicated server infrastructure just for cron jobs is overkill.
GitHub Actions provides a free, generous tier for running scheduled workflows using the schedule
event trigger. By combining GitHub Actions with a Screenshot API, you can build a highly reliable,
zero-maintenance screenshot automation pipeline.
The GitHub Actions Workflow File
Create a file in your repository at .github/workflows/screenshot-cron.yml. We'll configure it to
run every day at midnight UTC:
name: Daily Website Screenshot
on:
schedule:
- cron: '0 0 * * *' # Runs every day at 00:00 UTC
workflow_dispatch: # Allows manual triggering
jobs:
capture:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Dependencies
run: npm ci
- name: Run Screenshot Script
env:
SNAPAPI_KEY: ${{ secrets.SNAPAPI_KEY }}
run: node scripts/capture.js
- name: Commit and Push Changes
run: |
git config --global user.name "GitHub Action Bot"
git config --global user.email "[email protected]"
git add screenshots/
git commit -m "Automated screenshot capture" || echo "No changes to commit"
git push
Node.js Script Implementation
Next, we write the scripts/capture.js file that actually makes the request. Using SnapAPI
ensures our GitHub Action completes in seconds rather than spending minutes installing headless browsers.
const fs = require('fs');
const path = require('path');
const https = require('https');
const API_KEY = process.env.SNAPAPI_KEY;
const TARGET_URL = 'https://news.ycombinator.com';
const DATE_STR = new Date().toISOString().split('T')[0];
const OUTPUT_FILE = path.join(__dirname, '../screenshots', `snapshot-${DATE_STR}.png`);
async function capture() {
// Ensure directory exists
fs.mkdirSync(path.join(__dirname, '../screenshots'), { recursive: true });
const apiUrl = `https://snapapi.alterra-solutions.com/v1/screenshot?url=${encodeURIComponent(TARGET_URL)}&api_key=${API_KEY}&full_page=true`;
console.log('Fetching screenshot...');
const file = fs.createWriteStream(OUTPUT_FILE);
https.get(apiUrl, (response) => {
if (response.statusCode === 200) {
response.pipe(file);
file.on('finish', () => {
file.close();
console.log(`Screenshot saved to ${OUTPUT_FILE}`);
});
} else {
console.error(`Error: Request failed with status code ${response.statusCode}`);
process.exit(1);
}
}).on('error', (err) => {
console.error(`Error: ${err.message}`);
process.exit(1);
});
}
capture();
Saving & Committing Results
In the workflow provided above, the final step uses Git commands to commit the newly generated PNG file from
the screenshots/ directory back into the repository.
Alternatively, if you don't want to bloat your Git repository with large images, you can modify the workflow
to use GitHub Actions Setup AWS CLI and sync the resulting images directly to an Amazon S3
bucket, or simply upload them as workflow artifacts using the
actions/upload-artifact step.
Automate Your Screenshots Today
Get 100 free API requests per month to use with your GitHub Actions cron jobs.
Get Started Free →