import cloud from '@lafjs/cloud' const db = cloud.database(); const TA_RECEIVER_URL = "https://data.nika4fun.com/sync_data"; const TA_PRODUCTION_APP_ID = "87d18958cea145f29d3265470ecd3486"; const TA_TEST_APP_ID = "121591378fc1423893deb12041413eb3"; const UPLOAD_CONFIRMATION = "UPLOAD"; export default async function (ctx: FunctionContext) { const body = ctx.body || {}; const configuredToken = String((globalThis as any).process?.env?.TA_UNIONID_SYNC_TOKEN || ""); const adminToken = String(body.adminToken || ""); if (!configuredToken) { return fail("服务端未配置 TA_UNIONID_SYNC_TOKEN"); } if (!adminToken || adminToken !== configuredToken) { return fail("unauthorized"); } const openid = typeof body.openid === "string" ? body.openid.trim() : ""; if (!openid) { return fail("openid required"); } const collectionName = body.gameName === "iaa" ? "usersAd" : "users"; const result = await db.collection(collectionName).where({ openid: openid }).getOne(); const user = result.data; if (!user) { return fail(`未在 ${collectionName} 中找到该 openid`); } const unionid = typeof user.unionid === "string" ? user.unionid.trim() : ""; if (!unionid) { return fail("该用户没有有效的 unionid"); } const taProject = resolveTaProject(user.isDebug); if (!taProject) { return fail("用户 isDebug 字段缺失或无效,无法安全判断数数项目"); } const distinctId = typeof user.distinctId === "string" ? user.distinctId.trim() : ""; const preview = { collection: collectionName, taProject: taProject.name, accountId: openid, distinctId: distinctId || null, properties: { unionid: unionid, }, }; if (body.confirm !== UPLOAD_CONFIRMATION) { return { code: 1, data: { dryRun: true, ...preview }, msg: `预览成功;确认无误后传 confirm=${UPLOAD_CONFIRMATION} 才会上传`, }; } try { const receiverResponse = await uploadUnionId( taProject.appId, openid, distinctId, unionid, ); return { code: 1, data: { uploaded: true, ...preview, receiverResponse: receiverResponse }, msg: "unionid 已提交到数数", }; } catch (error) { const message = getErrorMessage(error); console.error("syncUserUnionId upload failed:", message); return fail(message); } } function resolveTaProject(isDebug: any) { const releaseFlag = normalizeBoolean(isDebug); if (releaseFlag === null) { return null; } // 当前客户端把“正式版”记录为 isDebug=true,这里与现有登录逻辑保持一致。 return releaseFlag ? { name: "production", appId: TA_PRODUCTION_APP_ID } : { name: "test", appId: TA_TEST_APP_ID }; } function normalizeBoolean(value: any): boolean | null { if (value === true || value === "true" || value === 1 || value === "1") { return true; } if (value === false || value === "false" || value === 0 || value === "0") { return false; } return null; } async function uploadUnionId( appId: string, accountId: string, distinctId: string, unionid: string, ) { const data: any = { "#account_id": accountId, "#type": "user_set", properties: { unionid: unionid, }, }; if (distinctId) { data["#distinct_id"] = distinctId; } const formData = [ `appid=${encodeURIComponent(appId)}`, `data=${encodeURIComponent(JSON.stringify(data))}`, "debug=0", ].join("&"); const response = await cloud.fetch({ url: TA_RECEIVER_URL, method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", }, data: formData, timeout: 10000, }); const receiverResponse = parseReceiverResponse(response?.data); if (!receiverResponse || Number(receiverResponse.code) !== 0) { throw new Error(`数数接收失败: ${JSON.stringify(receiverResponse ?? response?.data)}`); } return receiverResponse; } function parseReceiverResponse(value: any) { if (typeof value !== "string") { return value; } try { return JSON.parse(value); } catch { return null; } } function getErrorMessage(error: any) { return error instanceof Error ? error.message : String(error); } function fail(msg: string) { return { code: 0, data: null, msg: msg }; }