Skip to content

Instantly share code, notes, and snippets.

@DRFR0ST
Last active January 2, 2025 13:16
Show Gist options
  • Save DRFR0ST/fff7dc8571ce773ce69c83bea6f3e041 to your computer and use it in GitHub Desktop.
Save DRFR0ST/fff7dc8571ce773ce69c83bea6f3e041 to your computer and use it in GitHub Desktop.
A Bun/Node.js script that monitors a given URL for file content changes, notifying the user with console output when changes are detected.

️ File Change Monitor Script (Node.js & Bun)

This script keeps an eye on a file hosted online and alerts you whenever its content changes!

Features:

  • Cross-platform: Works on both Windows 🪟 and Linux/Mac systems!
  • No external dependencies: No need to install extra libraries
  • Robust error handling: Handles network issues and non-200 status codes
  • Clear notifications: Shows both old and new content for easy comparison
  • Graceful shutdown: Exits cleanly with Ctrl+C or errors

How to Use:

  1. Save the script: Copy and paste the code below into a file named monitor.ts.

  2. Run the script:

    • Using Node.js (v14 or later):

      node monitor.ts <your_url_here>
    • Using Bun (v0.1 or later):

      bun run monitor.ts <your_url_here>

Example:

Let's say you want to monitor a configuration file at https://example.com/config.txt.

Node.js:

node monitor.js https://example.com/config.txt

Bun:

bun run monitor.js https://example.com/config.txt

Explanation:

The script will initially fetch the content of the file and store it as a reference in the memory. Then, it checks for changes at regular intervals (default 20 seconds) and alerts you if the content differs from the previous version. The output uses ANSI escape codes for basic styling (may not work in all terminals).

Customization:

  • You can change the check interval (in milliseconds) by modifying the value passed to setInterval.

Happy monitoring!

import https from 'https';
const fetchFile = async (url: string): Promise<string> => {
return new Promise((resolve, reject) => {
https.get(url, (res) => {
if (res.statusCode !== 200) {
reject(new Error(`Request failed with status code: ${res.statusCode}`));
return;
}
const chunks: Buffer[] = [];
res.on('data', (chunk) => chunks.push(chunk));
res.on('end', () => resolve(Buffer.concat(chunks).toString()));
res.on('error', reject);
}).on('error', reject);
});
};
const compareContent = (oldContent: string | null, newContent: string): void => {
const bold = (str: string) => `\x1b[1m${str}\x1b[0m`;
const dim = (str: string) => `\x1B[2m${str}\x1b[0m`;
const inverse = (str: string) => `\x1b[7m${str}\x1b[0m`;
const red = (str: string) => `\x1b[31m${str}\x1b[0m`;
const green = (str: string) => `\x1b[32m${str}\x1b[0m`;
const gray = (str: string) => `\x1b[90m${str}\x1b[0m`; // Using bright black for gray
if (!oldContent) {
console.log(green('Original file content fetched and stored.'));
console.log(dim('Original content:\n' + newContent), "\n");
return;
}
if (newContent !== oldContent) {
console.log(bold(red(`File content has changed!`)));
console.log(dim('Previous content:\n' + oldContent), "\n");
console.log(bold('New content:\n' + newContent), "\n");
} else {
console.log(gray('File content is unchanged.'));
}
};
const monitorFile = async (url: string) => {
let originalFileContent: string | null = null;
let intervalId: NodeJS.Timeout | null = null; // Store the interval ID
const check = async () => {
try {
const newContent = await fetchFile(url);
compareContent(originalFileContent, newContent);
originalFileContent = newContent;
} catch (error) {
console.error(red(`Error: ${error.message}`)); // Use the red function
if (intervalId) { // Clear the interval if error occurs
clearInterval(intervalId);
}
process.exit(1); // Exit with error code
}
};
const red = (str: string) => `\x1b[31m${str}\x1b[0m`; // Moved red function here for error handling
await check(); // Initial check
intervalId = setInterval(check, 20000);
process.on('SIGINT', () => {
const yellow = (str: string) => `\x1b[33m${str}\x1b[0m`; // Moved yellow function here for warning handling on SIGINT.
console.log(yellow('Exiting...'));
if (intervalId) {
clearInterval(intervalId);
}
process.exit();
});
};
if (process.argv.length < 3) {
console.error(`\x1b[31mUsage: node script.js <url>\x1b[0m`); // red error message
process.exit(1);
}
const url = process.argv[2];
monitorFile(url);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment