159 lines
4.2 KiB
JavaScript
159 lines
4.2 KiB
JavaScript
const express = require('express');
|
|
const { fetchHtml, extractSeo, extractMetaTags } = require('./scraper');
|
|
const dbOps = require('./database');
|
|
const { authenticateApiKey } = require('./middleware');
|
|
const { isBrowserConnected } = require('./browser');
|
|
const config = require('./config');
|
|
|
|
const router = express.Router();
|
|
|
|
// Main API endpoint
|
|
router.get('/', authenticateApiKey, async (req, res) => {
|
|
const { url, skipCache } = req.query;
|
|
|
|
// Validate URL parameter
|
|
if (!url) {
|
|
return res.status(400).json({
|
|
error: 'Missing required parameter: url',
|
|
});
|
|
}
|
|
|
|
// Validate URL format
|
|
let urlObj;
|
|
try {
|
|
urlObj = new URL(url);
|
|
} catch (error) {
|
|
return res.status(400).json({
|
|
error: 'Invalid URL format',
|
|
});
|
|
}
|
|
|
|
// Parse skipCache (accept 'true', '1', 'yes', etc.)
|
|
const shouldSkipCache = skipCache === 'true' || skipCache === '1' || skipCache === 'yes';
|
|
|
|
try {
|
|
const html = await fetchHtml(url, shouldSkipCache);
|
|
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
res.send(html);
|
|
} catch (error) {
|
|
console.error('Request error:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to fetch webpage',
|
|
message: error.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
// Health check endpoint
|
|
router.get('/health', async (req, res) => {
|
|
res.json({
|
|
status: 'ok',
|
|
cacheExpiryHours: config.CACHE_EXPIRY_HOURS,
|
|
browserConnected: isBrowserConnected(),
|
|
database: dbOps.getDbType(),
|
|
});
|
|
});
|
|
|
|
// Cache stats endpoint
|
|
router.get('/cache/stats', authenticateApiKey, async (req, res) => {
|
|
try {
|
|
const stats = await dbOps.getStats();
|
|
res.json(stats);
|
|
} catch (error) {
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Clear cache endpoint (optional, for maintenance)
|
|
router.delete('/cache', authenticateApiKey, async (req, res) => {
|
|
try {
|
|
const { url } = req.query;
|
|
if (url) {
|
|
const deleted = await dbOps.deleteByUrl(url);
|
|
res.json({ deleted });
|
|
} else {
|
|
// Clear all cache
|
|
const deleted = await dbOps.deleteAll();
|
|
res.json({ deleted });
|
|
}
|
|
} catch (error) {
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// SEO extraction endpoint
|
|
router.get('/seo', authenticateApiKey, async (req, res) => {
|
|
const { url, skipCache } = req.query;
|
|
|
|
// Validate URL parameter
|
|
if (!url) {
|
|
return res.status(400).json({
|
|
error: 'Missing required parameter: url',
|
|
});
|
|
}
|
|
|
|
// Validate URL format
|
|
let urlObj;
|
|
try {
|
|
urlObj = new URL(url);
|
|
} catch (error) {
|
|
return res.status(400).json({
|
|
error: 'Invalid URL format',
|
|
});
|
|
}
|
|
|
|
// Parse skipCache (accept 'true', '1', 'yes', etc.)
|
|
const shouldSkipCache = skipCache === 'true' || skipCache === '1' || skipCache === 'yes';
|
|
|
|
try {
|
|
const seoData = await extractSeo(url, shouldSkipCache);
|
|
res.json(seoData);
|
|
} catch (error) {
|
|
console.error('SEO extraction error:', error);
|
|
res.status(500).json({
|
|
status: 'error',
|
|
url: url,
|
|
error: error.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
// Meta tags extraction endpoint
|
|
router.get('/meta', authenticateApiKey, async (req, res) => {
|
|
const { url, skipCache } = req.query;
|
|
|
|
// Validate URL parameter
|
|
if (!url) {
|
|
return res.status(400).json({
|
|
error: 'Missing required parameter: url',
|
|
});
|
|
}
|
|
|
|
// Validate URL format
|
|
let urlObj;
|
|
try {
|
|
urlObj = new URL(url);
|
|
} catch (error) {
|
|
return res.status(400).json({
|
|
error: 'Invalid URL format',
|
|
});
|
|
}
|
|
|
|
// Parse skipCache (accept 'true', '1', 'yes', etc.)
|
|
const shouldSkipCache = skipCache === 'true' || skipCache === '1' || skipCache === 'yes';
|
|
|
|
try {
|
|
const metaData = await extractMetaTags(url, shouldSkipCache);
|
|
res.json(metaData);
|
|
} catch (error) {
|
|
console.error('Meta tags extraction error:', error);
|
|
res.status(500).json({
|
|
status: 'error',
|
|
url: url,
|
|
error: error.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|