Add Markdown dns checking, and persistant logging

This commit is contained in:
2025-04-29 17:45:00 -07:00
parent ba95f2bd1d
commit bf943ec5d4
3 changed files with 44 additions and 10 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ config.json
data/state.json data/state.json
old.js old.js
package-lock.json package-lock.json
data/error.log

View File

@ -1,18 +1,31 @@
const axios = require('axios'); const axios = require('axios');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const dns = require('dns');
// --- CONFIG --- // --- CONFIG ---
const pollIntervalMs = 30 * 1000; // 30 seconds const pollIntervalMs = 30 * 1000; // 30 seconds
const configPath = path.join(__dirname, 'config.json'); const configPath = path.join(__dirname, 'config.json');
const statePath = path.join(__dirname, './data/state.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 // Load configs
let configs; let configs;
try { try {
configs = JSON.parse(fs.readFileSync(configPath, 'utf8')); configs = JSON.parse(fs.readFileSync(configPath, 'utf8'));
} catch (error) { } catch (error) {
console.error('❗ Failed to load config.json:', error.message); logError('❗ Failed to load config.json: ' + error.message);
process.exit(1); process.exit(1);
} }
@ -22,7 +35,7 @@ if (fs.existsSync(statePath)) {
try { try {
state = JSON.parse(fs.readFileSync(statePath, 'utf8')); state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
} catch (error) { } catch (error) {
console.error('❗ Failed to load state.json:', error.message); logError('❗ Failed to load state.json: ' + error.message);
process.exit(1); process.exit(1);
} }
} }
@ -37,13 +50,31 @@ function normalizeContent(content) {
return content.replace(/\r\n/g, '\n').trim(); 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 // Fetch markdown content
async function fetchMarkdown(url) { async function fetchMarkdown(url) {
const hostOK = await checkHostAvailability(url);
if (!hostOK) return '';
try { try {
const { data } = await axios.get(url); const { data } = await axios.get(url);
return data; return data;
} catch (error) { } catch (error) {
console.error('❗ Error fetching markdown:', error.message); logError(`❗ Error fetching markdown from ${url}: ${error.message}`);
return ''; return '';
} }
} }
@ -59,10 +90,10 @@ async function createNewMessage(config) {
saveState(); saveState();
console.log(`✅ [${config.name}] New message sent and ID saved.`); console.log(`✅ [${config.name}] New message sent and ID saved.`);
} else { } else {
console.error(`❗ [${config.name}] Failed to get message ID.`); logError(`❗ [${config.name}] Failed to get message ID.`);
} }
} catch (error) { } 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.`); console.log(`✅ [${config.name}] Message updated.`);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 404) { 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 = ''; state[config.name].messageId = '';
await createNewMessage(config); await createNewMessage(config);
} else { } 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.`); console.log(`✅ [${config.name}] Existing message validated.`);
} catch (error) { } catch (error) {
if (error.response && error.response.status === 404) { 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 = ''; state[config.name].messageId = '';
} else { } else {
console.error(`❗ [${config.name}] Error validating message:`, error.message); logError(`❗ [${config.name}] Error validating message: ${error.message}`);
} }
} }
} }

View File

@ -3,7 +3,8 @@
"version": "1.0.5", "version": "1.0.5",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "node index.js" "test": "node index.js",
"run": "node index.js"
}, },
"keywords": [], "keywords": [],
"author": "Sophia Atkinson", "author": "Sophia Atkinson",
@ -11,6 +12,7 @@
"description": "", "description": "",
"dependencies": { "dependencies": {
"axios": "^1.9.0", "axios": "^1.9.0",
"dns": "^0.2.2",
"fs": "^0.0.1-security", "fs": "^0.0.1-security",
"path": "^0.12.7" "path": "^0.12.7"
} }