diff --git a/.gitignore b/.gitignore index e1d35cf..3af4979 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ config.json data/state.json old.js package-lock.json +data/error.log diff --git a/index.js b/index.js index 755ece4..c01036f 100644 --- a/index.js +++ b/index.js @@ -1,18 +1,31 @@ const axios = require('axios'); const fs = require('fs'); const path = require('path'); +const dns = require('dns'); // --- CONFIG --- const pollIntervalMs = 30 * 1000; // 30 seconds const configPath = path.join(__dirname, 'config.json'); const statePath = path.join(__dirname, './data/state.json'); +const errorLogPath = path.join(__dirname, './data/error.log'); + +// --- ERROR LOGGER --- +function logError(message) { + const timestamp = new Date().toLocaleString('en-US', { + timeZone: 'America/Los_Angeles' + }); + const line = `[${timestamp}] ${message}\n`; + fs.appendFileSync(errorLogPath, line); + console.error(message); +} + // Load configs let configs; try { configs = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch (error) { - console.error('❗ Failed to load config.json:', error.message); + logError('❗ Failed to load config.json: ' + error.message); process.exit(1); } @@ -22,7 +35,7 @@ if (fs.existsSync(statePath)) { try { state = JSON.parse(fs.readFileSync(statePath, 'utf8')); } catch (error) { - console.error('❗ Failed to load state.json:', error.message); + logError('❗ Failed to load state.json: ' + error.message); process.exit(1); } } @@ -37,13 +50,31 @@ function normalizeContent(content) { return content.replace(/\r\n/g, '\n').trim(); } +// Check if the host of a URL is reachable +async function checkHostAvailability(url) { + const { hostname } = new URL(url); + return new Promise((resolve) => { + dns.lookup(hostname, (err) => { + if (err) { + logError(`🌐 Host unreachable: ${hostname} – ${err.message}`); + resolve(false); + } else { + resolve(true); + } + }); + }); +} + // Fetch markdown content async function fetchMarkdown(url) { + const hostOK = await checkHostAvailability(url); + if (!hostOK) return ''; + try { const { data } = await axios.get(url); return data; } catch (error) { - console.error('❗ Error fetching markdown:', error.message); + logError(`❗ Error fetching markdown from ${url}: ${error.message}`); return ''; } } @@ -59,10 +90,10 @@ async function createNewMessage(config) { saveState(); console.log(`✅ [${config.name}] New message sent and ID saved.`); } else { - console.error(`❗ [${config.name}] Failed to get message ID.`); + logError(`❗ [${config.name}] Failed to get message ID.`); } } catch (error) { - console.error(`❌ [${config.name}] Error sending new message:`, error.message); + logError(`❌ [${config.name}] Error sending new message: ${error.message}`); } } @@ -75,11 +106,11 @@ async function updateMessage(config) { console.log(`✅ [${config.name}] Message updated.`); } catch (error) { if (error.response && error.response.status === 404) { - console.error(`⚠️ [${config.name}] Message not found (deleted?). Creating new...`); + logError(`⚠️ [${config.name}] Message not found (deleted?). Creating new...`); state[config.name].messageId = ''; await createNewMessage(config); } else { - console.error(`❌ [${config.name}] Error updating message:`, error.message); + logError(`❌ [${config.name}] Error updating message: ${error.message}`); } } } @@ -92,10 +123,10 @@ async function validateExistingMessage(config) { console.log(`✅ [${config.name}] Existing message validated.`); } catch (error) { if (error.response && error.response.status === 404) { - console.error(`⚠️ [${config.name}] Message not found. Will create new.`); + logError(`⚠️ [${config.name}] Message not found. Will create new.`); state[config.name].messageId = ''; } else { - console.error(`❗ [${config.name}] Error validating message:`, error.message); + logError(`❗ [${config.name}] Error validating message: ${error.message}`); } } } diff --git a/package.json b/package.json index f103910..2b60b89 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "1.0.5", "main": "index.js", "scripts": { - "test": "node index.js" + "test": "node index.js", + "run": "node index.js" }, "keywords": [], "author": "Sophia Atkinson", @@ -11,6 +12,7 @@ "description": "", "dependencies": { "axios": "^1.9.0", + "dns": "^0.2.2", "fs": "^0.0.1-security", "path": "^0.12.7" }