Edit: /tmp/tsx-0/17887-a13b314df30a3100fba5435959730ab6833025ff (9284B)
{"code":"__filename=\"/opt/canhelp/apps/api/src/lib/push.ts\";(()=>{\n\"use strict\";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var push_exports={};__export(push_exports,{sendPushToUser:()=>sendPushToUser});module.exports=__toCommonJS(push_exports);var import_drizzle_orm=require(\"drizzle-orm\");var import_googleapis=require(\"googleapis\");var import_db=require(\"../db.js\");var import_db2=require(\"@canhelp/db\");const FCM_SCOPE=\"https://www.googleapis.com/auth/firebase.messaging\";let cachedAccessToken=null;function getServiceAccountConfig(){const projectId=process.env.FCM_PROJECT_ID?.trim()||process.env.FIREBASE_PROJECT_ID?.trim()||\"\";const clientEmail=process.env.FCM_CLIENT_EMAIL?.trim()||\"\";const privateKeyRaw=process.env.FCM_PRIVATE_KEY||\"\";const privateKey=privateKeyRaw.replace(/\\\\n/g,\"\\n\").trim();if(!projectId||!clientEmail||!privateKey)return null;return{projectId,clientEmail,privateKey}}__name(getServiceAccountConfig,\"getServiceAccountConfig\");async function getAccessToken(cfg){const now=Date.now();if(cachedAccessToken&&cachedAccessToken.expiresAt-now>6e4){return cachedAccessToken.token}const jwt=new import_googleapis.google.auth.JWT({email:cfg.clientEmail,key:cfg.privateKey,scopes:[FCM_SCOPE]});const token=await jwt.authorize();if(!token.access_token)return null;cachedAccessToken={token:token.access_token,expiresAt:token.expiry_date??now+50*60*1e3};return token.access_token}__name(getAccessToken,\"getAccessToken\");function isInvalidTokenError(errorBody){if(!errorBody||typeof errorBody!==\"object\")return false;const err=errorBody.error;if(!err||typeof err!==\"object\")return false;const status=err.status;const details=err.details;if(status===\"UNREGISTERED\")return true;if(!Array.isArray(details))return status===\"INVALID_ARGUMENT\";for(const d of details){if(!d||typeof d!==\"object\")continue;const code=d.errorCode;if(code===\"UNREGISTERED\"||code===\"INVALID_ARGUMENT\")return true}return status===\"INVALID_ARGUMENT\"}__name(isInvalidTokenError,\"isInvalidTokenError\");function extractFcmFailure(errorBody,httpStatus,raw){if(!errorBody||typeof errorBody!==\"object\"){return{key:`HTTP_${httpStatus}`,message:raw||`FCM request failed with HTTP ${httpStatus}`}}const err=errorBody.error;if(!err||typeof err!==\"object\"){return{key:`HTTP_${httpStatus}`,message:raw||`FCM request failed with HTTP ${httpStatus}`}}const status=err.status?.trim()||\"\";const message=err.message?.trim()||raw||`FCM request failed with HTTP ${httpStatus}`;const details=err.details;if(Array.isArray(details)){for(const d of details){if(!d||typeof d!==\"object\")continue;const code=d.errorCode?.trim();if(code)return{key:code,message}}}if(status)return{key:status,message};return{key:`HTTP_${httpStatus}`,message}}__name(extractFcmFailure,\"extractFcmFailure\");async function sendPushToUser(userId,payload){const serviceCfg=getServiceAccountConfig();if(!serviceCfg){return{sent:0,invalidTokens:[],tokensFound:0,reason:\"fcm_not_configured\"}}const accessToken=await getAccessToken(serviceCfg);if(!accessToken){console.error(\"[push] failed to get FCM access token\");return{sent:0,invalidTokens:[],tokensFound:0,reason:\"fcm_auth_failed\"}}const fcmEndpoint=`https://fcm.googleapis.com/v1/projects/${serviceCfg.projectId}/messages:send`;const tokensRows=await import_db.db.select({token:import_db2.pushTokens.token}).from(import_db2.pushTokens).where((0,import_drizzle_orm.eq)(import_db2.pushTokens.userId,userId));if(tokensRows.length===0){return{sent:0,invalidTokens:[],tokensFound:0,reason:\"no_tokens\"}}const tokens=tokensRows.map(r=>r.token).filter(t=>t.length>0);const invalidTokens=[];let sent=0;let failureKey;let failureMessage;for(const token of tokens){try{const res=await fetch(fcmEndpoint,{method:\"POST\",headers:{Authorization:`Bearer ${accessToken}`,\"Content-Type\":\"application/json\"},body:JSON.stringify({message:{token,notification:{title:payload.title,body:payload.body??void 0},data:payload.data??{}}})});const raw=await res.text();let parsed=null;try{parsed=raw?JSON.parse(raw):null}catch(_){}if(!res.ok){console.error(\"[push] fcm error\",res.status,raw);if(isInvalidTokenError(parsed)){invalidTokens.push(token)}else if(!failureKey){const failure=extractFcmFailure(parsed,res.status,raw);failureKey=failure.key;failureMessage=failure.message}continue}sent+=1}catch(err){console.error(\"[push] request failed\",err);if(!failureKey){failureKey=\"REQUEST_FAILED\";failureMessage=err instanceof Error?err.message:\"FCM request failed before response\"}}}if(invalidTokens.length>0){await import_db.db.delete(import_db2.pushTokens).where((0,import_drizzle_orm.and)((0,import_drizzle_orm.eq)(import_db2.pushTokens.userId,userId),(0,import_drizzle_orm.inArray)(import_db2.pushTokens.token,invalidTokens)))}const reason=sent===0?\"fcm_send_failed\":void 0;return{sent,invalidTokens,tokensFound:tokens.length,reason,failureKey,failureMessage}}__name(sendPushToUser,\"sendPushToUser\");0&&(module.exports={sendPushToUser});\n})()\n","warnings":[],"map":{"version":3,"mappings":"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","names":["import_db"],"ignoreList":[],"sources":["/opt/canhelp/apps/api/src/lib/push.ts"],"sourcesContent":[null]}}