Files
kolaytercih/scripts/indexnow.ts
bilalgursen 24d4bea32c
All checks were successful
Deploy / deploy (push) Successful in 6m16s
feat(geo): llms.txt, RSS, IndexNow, Article yazar/görsel, bölüm sayfasına veri özeti, vakıf bursu yazısı
GEO araştırması (docs/arastirma/2026-09-24-geo-seo) Dalga 1-2 uygulaması:
- /llms.txt ve /feed.xml route'ları (getAllRehberler'den otomatik), head'de RSS linki
- Article JSON-LD: author, image, mainEntityOfPage, publisher logo; görünür 'Yazan' satırı
- robots: ClaudeBot ayrı grupta Crawl-delay 1
- scripts/indexnow.ts (pnpm indexnow) + public anahtar dosyası
- bölüm sayfası açılışı veriden üretilen özgü cümleler (il/program/tür/kontenjan, taban aralığı, yıllık yön)
- ana sayfa fiyat iddiasına kaynak; iki yazıda 23.000 -> 21.000+; beş yazıya 'Kısa cevap' açılışı
- yeni yazı: vakif-universitesi-bursu-kesilir-mi (ÖSYM 2026 kılavuzu + YÖK ücret esasları)
- YAYIN-KUYRUGU: IndexNow adımı ve aylık AI görünürlük rutini

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 17:42:29 +03:00

93 lines
3.2 KiB
TypeScript
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 bildirimi (Bing + Yandex; Google desteklemiyor).
*
* Anahtar dosyası: public/<anahtar>.txt — canlıda https://kolaytercih.com/<anahtar>.txt
* olarak sunulur; IndexNow her bildirimde bu dosyayı okuyup anahtarı doğrular.
* Anahtar gizli değildir (dosya zaten herkese açık), ama değiştirilirse
* public/ altındaki dosya da birlikte değişmeli.
*
* Kullanım (canlıda 200 dönen adresler için, yayından SONRA):
* pnpm indexnow https://kolaytercih.com/rehber/<slug> [...]
* pnpm indexnow --rehber # content/rehber altındaki tüm yazılar
* pnpm indexnow --sitemap # canlı sitemap.xml'deki tüm adresler (10.000'e kadar)
*
* Bing Webmaster → IndexNow sekmesinde alınan bildirimler görünür; Yandex
* Webmaster'da "Indexing → IndexNow" altında. Aynı adres günde bir kez yeter.
*/
import fs from "node:fs";
import path from "node:path";
const HOST = "kolaytercih.com";
const SITE = `https://${HOST}`;
const UC = "https://api.indexnow.org/indexnow";
function anahtarOku(): string {
const dizin = path.join(process.cwd(), "public");
const dosya = fs
.readdirSync(dizin)
.find((f) => /^[0-9a-f]{32}\.txt$/.test(f));
if (!dosya) {
throw new Error("indexnow: public/ altında <32 hex>.txt anahtar dosyası yok");
}
const anahtar = fs.readFileSync(path.join(dizin, dosya), "utf8").trim();
if (anahtar !== dosya.replace(/\.txt$/, "")) {
throw new Error(`indexnow: ${dosya} içeriği dosya adıyla eşleşmiyor`);
}
return anahtar;
}
function rehberAdresleri(): string[] {
const dizin = path.join(process.cwd(), "content", "rehber");
return fs
.readdirSync(dizin)
.filter((f) => f.endsWith(".md"))
.map((f) => `${SITE}/rehber/${f.replace(/\.md$/, "")}`);
}
async function sitemapAdresleri(): Promise<string[]> {
const res = await fetch(`${SITE}/sitemap.xml`);
if (!res.ok) throw new Error(`indexnow: sitemap ${res.status}`);
const xml = await res.text();
return [...xml.matchAll(/<loc>([^<]+)<\/loc>/g)].map((m) => m[1].trim());
}
async function main() {
const args = process.argv.slice(2);
let adresler: string[];
if (args.includes("--rehber")) adresler = rehberAdresleri();
else if (args.includes("--sitemap")) adresler = await sitemapAdresleri();
else adresler = args.filter((a) => a.startsWith("http"));
adresler = [...new Set(adresler)].filter((a) => a.startsWith(SITE));
if (adresler.length === 0) {
console.error("indexnow: adres yok. Kullanım: pnpm indexnow <url...> | --rehber | --sitemap");
process.exit(1);
}
if (adresler.length > 10_000) {
throw new Error("indexnow: tek istekte en fazla 10.000 adres");
}
const key = anahtarOku();
const res = await fetch(UC, {
method: "POST",
headers: { "Content-Type": "application/json; charset=utf-8" },
body: JSON.stringify({
host: HOST,
key,
keyLocation: `${SITE}/${key}.txt`,
urlList: adresler,
}),
});
// 200 = işlendi, 202 = alındı (anahtar sonra doğrulanacak), 4xx = hata.
console.log(`indexnow: ${adresler.length} adres → HTTP ${res.status}`);
if (!res.ok && res.status !== 202) {
console.error(await res.text());
process.exit(1);
}
}
main().catch((e) => {
console.error(e);
process.exit(1);
});