mirror of
https://github.com/direct-img/direct-img.link.git
synced 2026-10-17 10:17:53 +00:00
Feat: Add GoatCounter analytics, Terms & Privacy pages, prompt copy button
- Update AI system prompt example (README + index) - Add copy button for the prompt on the index page - Add GoatCounter to homepage; report image hits server-side via waitUntil (optional GOATCOUNTER_URL/GOATCOUNTER_TOKEN) - Add TERMS.md and PRIVACY.md, linked in the index footer - Remove dead c.planetrenox.com tracker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,8 @@ export async function onRequest(context) {
|
||||
if (!query) return jsonResponse(400, { error: "Empty query" });
|
||||
if (query.length > 200) return jsonResponse(400, { error: "Query too long (max 200 characters)" });
|
||||
|
||||
context.waitUntil(countHit(env, request, query));
|
||||
|
||||
const cacheKey = query;
|
||||
const r2Key = await sha256(query);
|
||||
|
||||
@@ -209,6 +211,19 @@ async function notify(env,{ title, message, tags, priority }) {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
async function countHit(env, request, query) {
|
||||
if (!env.GOATCOUNTER_URL || !env.GOATCOUNTER_TOKEN) return;
|
||||
const h = k => request.headers.get(k) || "";
|
||||
try {
|
||||
await fetch(`${env.GOATCOUNTER_URL}/api/v0/count`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${env.GOATCOUNTER_TOKEN}` },
|
||||
body: JSON.stringify({ no_sessions: true, hits: [{ path: `/${query.replace(/ /g, "+")}`, title: query, ref: h("referer"), user_agent: h("user-agent"), ip: h("cf-connecting-ip") }] }),
|
||||
signal: AbortSignal.timeout(5000)
|
||||
});
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function normalizeQuery(path) {
|
||||
try {
|
||||
return decodeURIComponent(path.replace(/\+/g, " ")).toLowerCase().trim().replace(/[\x00-\x1f]/g, "").replace(/\/+$/, "").replace(/\s+/g, " ");
|
||||
|
||||
Reference in New Issue
Block a user