// ───────── 主に見る3つの数字(2026-11-06。集計は worker/kpi.js)───────── async function kpiStats(request, env, url) { if (request.method !== 'GET') return new Response('Method Not Allowed', { status: 405 }); const day = (k, d) => (/^\d{4}-\d{2}-\d{2}$/.test(url.searchParams.get(k) || '') ? url.searchParams.get(k) : d); const today = todayJst(); // ?sc=refresh で Search Console からサイト名の検索の数を取り直す(?since= の週から。最初の埋め戻し用) if (url.searchParams.get('sc') === 'refresh') { try { return json(await gscRefresh(env, { since: day('since', '') })); } catch (e) { return json({ ok: false, error: e.message }, 500); } } const data = await kpiRange(env, day('since', addDays(today, -28)), day('until', today)); if (url.searchParams.get('format') === 'json') { return new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json; charset=utf-8', 'x-robots-tag': 'noindex', 'cache-control': 'no-store' } }); } const esc = (s) => String(s).replace(/[&<>"]/g, (ch) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[ch])); const kv = (o) => Object.entries(o || {}).sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k} ${v}`).join('、'); const table = (cols, list) => list.length ? `
| ${h} | `).join('')}
|---|
| ${esc(f ? f(r[k], r) : (r[k] ?? '-'))} | `).join('')}
まだ記録がありません。
'; const html = `AI に調べられることで、人の来訪や知名度がいつ増えはじめるかを見るための数。日付は日本時間、週は月曜はじまり。${esc(data.since)} 〜 ${esc(data.until)}(?since=・?until= で変える)。${data.pendingDays.length ? ` 集計がまだの日が ${data.pendingDays.length} 日ある(開き直すと作る)。` : ''}
AI の依頼読み:ChatGPT-User・Claude-User・Perplexity-User などが読んだページの数(「AIで読む」ボタン経由はエイイチ・Claude の試しが混ざりうる)。AI のリンクから:chatgpt.com などのリンクから来た、人の操作があった表示。サイト名の検索:Search Console から週ごとに記録したクリック数。