Sleep → Focus → Stress & Anxiety → Motivation → Overthinking

// MindCheck Coach backend for Cloudflare Workers. // Setup: add a secret named ANTHROPIC_API_KEY. Optionally bind a KV namespace named RL for rate limiting. // 1. Put the exact addresses of your own sites here (no trailing slash). const ALLOWED = [ "https://skillrisecareer.blogspot.com", "https://www.visibilitychecker.online", "https://visibilitychecker.online" ]; const MODEL = "claude-haiku-5-5"; const HOURLY_LIMIT = 30; // messages per visitor per hour const SYSTEM = `You are MindCheck Coach, a warm, practical wellness coach on a public website. Scope: sleep, focus and concentration, stress, anxiety-type feelings, overthinking, low motivation and energy, daily habits, basic nutrition, light exercise, and routine building. If a question is outside this scope, say so kindly and bring the conversation back. How to answer: 1. Reply in the language the user writes in (English, Urdu, or Roman Urdu). 2. Begin with one short sentence that shows you understood them. 3. If key details are missing, ask at most two short questions before giving a full plan. If the user has given enough detail, go straight to the plan. 4. Give a clear plan: likely reasons in plain words, then 3 to 5 numbered steps they can start today, then a simple 7-day tip if useful. 5. Keep answers under 250 words. Use plain text. You may use **bold** for key words. No headings, no emojis. Safety rules: - You are not a doctor or therapist. Never diagnose, never name medicines or doses. - If symptoms sound serious (chest pain, fainting, severe or long-lasting symptoms, pregnancy, children, existing medical conditions), tell them to see a qualified doctor. - If the user mentions suicide, self-harm, or feeling unsafe, respond with care, do not give a normal plan, and urge them to contact a trusted person and local emergency or crisis services right now. - Never claim certainty about health outcomes.`; export default { async fetch(req, env) { const origin = req.headers.get("Origin") || ""; const ok = ALLOWED.includes(origin); const cors = { "Access-Control-Allow-Origin": ok ? origin : ALLOWED[0], "Access-Control-Allow-Methods": "POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type", "Vary": "Origin" }; const reply = (obj, status = 200) => new Response(JSON.stringify(obj), { status, headers: { ...cors, "Content-Type": "application/json" } }); if (req.method === "OPTIONS") return new Response(null, { headers: cors }); if (req.method !== "POST" || !ok) return reply({ error: "Not allowed" }, 403); // Optional rate limit per visitor per hour (needs a KV binding named RL). if (env.RL) { const ip = req.headers.get("CF-Connecting-IP") || "x"; const key = "rl:" + ip + ":" + Math.floor(Date.now() / 3600000); const n = parseInt((await env.RL.get(key)) || "0", 10); if (n >= HOURLY_LIMIT) return reply({ error: "Too many messages. Please try again later." }, 429); await env.RL.put(key, String(n + 1), { expirationTtl: 3700 }); } let body; try { body = await req.json(); } catch { return reply({ error: "Bad request" }, 400); } let msgs = Array.isArray(body.messages) ? body.messages.slice(-12) : []; msgs = msgs .filter(m => m && (m.role === "user" || m.role === "assistant") && typeof m.content === "string") .map(m => ({ role: m.role, content: m.content.slice(0, 1500) })); while (msgs.length && msgs[0].role !== "user") msgs.shift(); if (!msgs.length || msgs[msgs.length - 1].role !== "user") return reply({ error: "Bad request" }, 400); try { const r = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "x-api-key": env.ANTHROPIC_API_KEY, "anthropic-version": "2023-06-01", "content-type": "application/json" }, body: JSON.stringify({ model: MODEL, max_tokens: 700, system: SYSTEM, messages: msgs }) }); const data = await r.json(); const text = data.content && data.content[0] && data.content[0].text; if (!r.ok || !text) return reply({ error: "Coach unavailable" }, 502); return reply({ reply: text }); } catch (e) { return reply({ error: "Coach unavailable" }, 502); } } };

Comments

Popular posts from this blog

HOME PAGE