Files
pitstopavto-su-v2/scripts/indexnow.js
Dmitry Gusev ed27dcfc14
Some checks failed
deploy / deploy (push) Failing after 14s
feat: скаффолд Astro 5 SSG (главная + /privacy + consent gate)
- Главная: hero, адрес Люблинская 100 (Аквапарк ФЭНТАЗИ), 4 кликабельных tel:, карта Яндекса
- /privacy: политика 152-ФЗ + ConsentRevoke (отозвать/сбросить)
- Аналитика перенесена 1:1 с WP: Яндекс.Метрика 47169531 (Webvisor) + GA4 GT-WRF7ZZ8
- Скрипты в type=text/plain, активируются после согласия (pit-consent в localStorage+cookie)
- robots.txt с явным Allow для GPTBot/ClaudeBot/PerplexityBot/Google-Extended/CCBot
- llms.txt + ai.txt (spawning.ai стандарт)
- IndexNow ключ 901a779d62ca4702ad810c863b45e1f7
- JSON-LD AutoPartsStore с адресом и 4 телефонами
- nginx:1.29-alpine runtime, контейнер на :4147
- Gitea Actions deploy.yml + Trivy scan + IndexNow ping
2026-05-22 04:31:55 +03:00

76 lines
2.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// IndexNow: уведомить Yandex/Bing о новых/обновлённых URL.
// Запуск: node scripts/indexnow.js (из CI после деплоя или вручную)
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const root = path.resolve(__dirname, '..');
const BASE = 'https://pitstopavto.su';
const HOST = 'pitstopavto.su';
const KEY = '901a779d62ca4702ad810c863b45e1f7';
const keyFile = path.join(root, 'public', `${KEY}.txt`);
if (!fs.existsSync(keyFile)) {
fs.writeFileSync(keyFile, KEY, 'utf-8');
console.log(`created key file: public/${KEY}.txt`);
}
function extractLocs(xml) {
return [...xml.matchAll(/<loc>([^<]+)<\/loc>/g)].map((m) => m[1].trim());
}
let urls = [];
const distDir = path.join(root, 'dist');
const sitemapIndex = path.join(distDir, 'sitemap-index.xml');
if (fs.existsSync(sitemapIndex)) {
const idx = fs.readFileSync(sitemapIndex, 'utf-8');
for (const sub of extractLocs(idx)) {
const fname = sub.split('/').pop();
const localPath = path.join(distDir, fname);
if (fs.existsSync(localPath)) {
urls.push(...extractLocs(fs.readFileSync(localPath, 'utf-8')));
}
}
} else {
console.log('no local sitemap-index.xml, fetching from production…');
try {
const idxResp = await fetch(`${BASE}/sitemap-index.xml`);
if (!idxResp.ok) throw new Error(`HTTP ${idxResp.status}`);
for (const sub of extractLocs(await idxResp.text())) {
const subResp = await fetch(sub);
if (!subResp.ok) continue;
urls.push(...extractLocs(await subResp.text()));
}
} catch (e) {
console.error(`failed to fetch sitemap from ${BASE}: ${e.message}`);
process.exit(1);
}
}
urls = [...new Set(urls)].filter((u) => u.startsWith(BASE));
if (urls.length === 0) { console.error('no URLs collected'); process.exit(1); }
console.log(`Submitting ${urls.length} URLs to IndexNow…`);
const payload = { host: HOST, key: KEY, keyLocation: `${BASE}/${KEY}.txt`, urlList: urls };
async function submit(endpoint) {
try {
const r = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=utf-8' },
body: JSON.stringify(payload),
});
console.log(` ${endpoint}: HTTP ${r.status}`);
} catch (e) {
console.error(` ${endpoint}: ${e.message}`);
}
}
await Promise.all([
submit('https://yandex.com/indexnow'),
submit('https://api.indexnow.org/indexnow'),
]);