ð§ Worker æŽæ°ä»£ç
æäžé¢ä»£ç èŽŽå° Cloudflare Workers çŒèŸåšïŒç¹ Deployã
// ================================================================
// School Panda ç»äžäºåæ¥ Worker
// åæ¶æ¯æïŒè¯Ÿæ¶ç³»ç» + 诟çšè¡šç³»ç»
// ç»å® KV: SP_KVïŒç¯å¢åé: SYNC_KEY
//
// æ°æ® keyïŒ
// 诟æ¶ç³»ç» â school_panda_data (åæïŒäžå)
// 诟çšè¡š â school_panda_timetable_data (æ°å¢)
// ================================================================
const ALLOWED_KEYS = ["school_panda_data", "school_panda_timetable_data"];
export default {
async fetch(request, env) {
const cors = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, X-Sync-Key, X-Device-Id, X-Data-Key",
"Access-Control-Max-Age": "86400",
};
if (request.method === "OPTIONS") {
return new Response(null, { headers: cors });
}
// å¯é¥éªè¯
const key = request.headers.get("X-Sync-Key");
if (!key || key !== env.SYNC_KEY) {
return new Response(JSON.stringify({ error: "unauthorized" }), {
status: 401,
headers: { ...cors, "Content-Type": "application/json" },
});
}
// 读å dataKeyïŒç±å®¢æ·ç«¯æå®ïŒé»è®€å
Œå®¹è¯Ÿæ¶ç³»ç»ïŒ
const url = new URL(request.url);
const dataKey = request.headers.get("X-Data-Key")
|| url.searchParams.get("dataKey")
|| "school_panda_data";
// å®å
šçœååïŒé²æ¢ä¹±å KV
if (!ALLOWED_KEYS.includes(dataKey)) {
return new Response(JSON.stringify({ error: "invalid dataKey" }), {
status: 400,
headers: { ...cors, "Content-Type": "application/json" },
});
}
try {
if (request.method === "GET") {
const stored = await env.SP_KV.get(dataKey, "json");
return new Response(JSON.stringify(stored || { data: null, modified: 0 }), {
headers: { ...cors, "Content-Type": "application/json" },
});
}
if (request.method === "POST") {
const body = await request.json();
if (!body || !body.data) {
return new Response(JSON.stringify({ error: "invalid body" }), {
status: 400,
headers: { ...cors, "Content-Type": "application/json" },
});
}
const payload = {
data: body.data,
modified: body.modified || Date.now(),
device: body.device || "unknown",
updatedAt: Date.now(),
};
await env.SP_KV.put(dataKey, JSON.stringify(payload));
return new Response(JSON.stringify({ ok: true, modified: payload.modified }), {
headers: { ...cors, "Content-Type": "application/json" },
});
}
return new Response(JSON.stringify({ error: "method not allowed" }), {
status: 405,
headers: { ...cors, "Content-Type": "application/json" },
});
} catch (e) {
return new Response(JSON.stringify({ error: e.message }), {
status: 500,
headers: { ...cors, "Content-Type": "application/json" },
});
}
},
};
â
å·²å€å¶ïŒ