import { timingSafeEqual } from "node:crypto"; crypto.subtle.timingSafeEqual = (a, b) => timingSafeEqual(Buffer.from(a), Buffer.from(b)); import { computeKpiDay, kpiRange, kpiCron, todayJst, addDays } from '/home/claude/p2m-site/worker/kpi.js'; import { handleMcp, mcpKey } from '/home/claude/p2m-site/worker/mcp.js'; // R2 のまね const store = new Map(); const R2 = { async list({ prefix = '', cursor, limit = 1000 }) { const keys = [...store.keys()].filter(k => k.startsWith(prefix)).sort(); const start = cursor ? +cursor : 0; const objs = keys.slice(start, start + 3).map(k => ({ key: k, customMetadata: store.get(k).meta })); const next = start + 3; return { objects: objs, truncated: next < keys.length, cursor: String(next) }; }, async get(k) { const v = store.get(k); return v ? { json: async () => JSON.parse(v.body) } : null; }, async head(k) { return store.has(k) ? {} : null; }, async put(k, body, o = {}) { store.set(k, { body, meta: o.customMetadata || {} }); }, }; const env = { MESSAGES: R2, STATS_KEY: 'testkey' }; const y = addDays(todayJst(), -1); const put = (k, meta) => store.set(k, { body: '', meta }); put(`cr/${y}/1-a`, { b: 'ChatGPT-User', p: '/', s: '200', ok: '1' }); put(`cr/${y}/2-a`, { b: 'ChatGPT-User', p: '/record/x', s: '200', ok: '0' }); put(`cr/${y}/3-a`, { b: 'Claude-User', p: '/robots.txt', s: '200', ok: '?' }); put(`cr/${y}/4-a`, { b: 'Claude-User', p: '/record/x.md', s: '200', ok: '?', v: 'claude' }); put(`cr/${y}/5-a`, { b: 'Amazonbot', p: '/record/x.md', s: '200', ok: '1', v: 'gemini' }); put(`cr/${y}/6-a`, { b: 'PerplexityBot', p: '/', s: '200', ok: '0' }); put(`ev/${y}/1-v1-0`, { v: 'v1', n: '0', p: '/', r: '', us: 'chatgpt.com', k: 'x' }); put(`ev/${y}/2-v1-1`, { v: 'v1', n: '1', p: '/', r: '', us: 'chatgpt.com', k: 'h' }); put(`ev/${y}/3-v2-0`, { v: 'v2', n: '0', p: '/gpu', r: 'perplexity.ai', us: '', k: 'b' }); put(`ev/${y}/4-v3-0`, { v: 'v3', n: '0', p: '/a', r: 'www.google.com', us: '', k: 'h' }); put(`ev/${y}/5-v4-0`, { v: 'v4', n: '0', p: '/b', f: '/a', r: '', us: '', k: 'h' }); console.log(JSON.stringify(await computeKpiDay(env, y), null, 1)); console.log(await kpiCron(env), await kpiCron(env)); const key = await mcpKey(env); const call = async (body, k = key) => { const u = new URL(`https://pixelstomotors.com/mcp/${k}`); const r = await handleMcp(new Request(u, { method: 'POST', body: JSON.stringify(body) }), env, u, { evStats: async () => new Response('{"x":1}'), crStats: async (req, e, uu) => new Response(JSON.stringify({ q: uu.search })), hkStats: async () => new Response('{}') }); return [r.status, r.status === 200 ? await r.json() : null]; }; console.log(await call({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '2025-06-18' } }, 'wrong')); console.log(JSON.stringify(await call({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '2025-06-18' } }))); console.log(await call({ jsonrpc: '2.0', method: 'notifications/initialized' })); console.log((await call({ jsonrpc: '2.0', id: 2, method: 'tools/list' }))[1].result.tools.map(t => t.name)); const k = await call({ jsonrpc: '2.0', id: 3, method: 'tools/call', params: { name: 'kpi', arguments: { since: addDays(y, -2) } } }); console.log(k[1].result.content[0].text.slice(0, 900)); console.log(JSON.stringify(await call({ jsonrpc: '2.0', id: 4, method: 'tools/call', params: { name: 'crawler_visits', arguments: { bot: 'ChatGPT-User' } } }))); console.log(JSON.stringify(await call({ jsonrpc: '2.0', id: 5, method: 'tools/call', params: { name: 'record_name_search', arguments: { week: '2026-11-02', clicks: 3, impressions: 40 } } }))); console.log(JSON.stringify(await call({ jsonrpc: '2.0', id: 6, method: 'tools/call', params: { name: 'record_name_search', arguments: { week: '2026-11-03', clicks: 3, impressions: 40 } } }))); const k2 = await call({ jsonrpc: '2.0', id: 7, method: 'tools/call', params: { name: 'kpi', arguments: { since: '2026-11-02' } } }); console.log(JSON.parse(k2[1].result.content[0].text).byWeek);