UNPKG

@cruxstack/node-sdk

Version:

A Node.js SDK for event tracking, user traits lookup, validation, and automatic retry with queueing.

182 lines (181 loc) 6.78 kB
import axios, { AxiosError } from "axios"; export async function sendEvent(event) { try { // Construct outgoing payload with all available fields const payload = { cid: event.cid, cna: event.cna, uid: event.uid, eid: event.eid, dtm: event.dtm, e: event.e, ev: event.ev, tna: event.tna, tv: event.tv, // Optional fields - only include if they exist ...(event.sid && { sid: event.sid }), ...(event.ua && { ua: event.ua }), ...(event.sh && { sh: event.sh }), ...(event.sw && { sw: event.sw }), ...(event.l && { l: event.l }), ...(event.p && { p: event.p }), ...(event.an !== undefined && { an: event.an }), ...(event.vh && { vh: event.vh }), ...(event.vw && { vw: event.vw }), ...(event.pt && { pt: event.pt }), ...(event.pu && { pu: event.pu }), ...(event.pp && { pp: event.pp }), ...(event.pd && { pd: event.pd }), ...(event.pl && { pl: event.pl }), ...(event.pr && { pr: event.pr }), ...(event.ip && { ip: event.ip }), ...(event.tz && { tz: event.tz }), }; // Wrap payload in events array const eventsPayload = { events: [payload], }; const response = await axios.post("https://api.cruxstack.com/api/v1/events", eventsPayload, { headers: { "Content-Type": "application/json", "x-client-id": event.client_id, }, }); if (response.status >= 200 && response.status < 300) { console.log(`Event sent successfully: ${event.eid}`); } else { throw new Error(`API returned status ${response.status}`); } } catch (error) { if (error instanceof AxiosError) { const message = error.response?.data?.message || error.message; console.error(`Failed to send event: ${message}`); throw new Error(`Failed to send event: ${message}`); } throw new Error(`Failed to send event: ${error instanceof Error ? error.message : "Unknown error"}`); } } export async function getUserTraitsFromAPI(clientId, customerId, request) { try { // Add validation for customerId if (!customerId || customerId === "undefined") { throw new Error("customerId is required for getUserTraits"); } const response = await axios.post(`https://api.cruxstack.com/backend/v1/users/traits?customerId=${encodeURIComponent(customerId)}`, request, { headers: { "Content-Type": "application/json", "x-client-id": clientId, }, }); if (response.status >= 200 && response.status < 300) { return { success: true, data: response.data, message: "User traits retrieved successfully", }; } else { throw new Error(`API returned status ${response.status}`); } } catch (error) { if (error instanceof AxiosError) { const message = error.response?.data?.message || error.message; console.error(`Failed to get user traits: ${message}`); return { success: false, error: `Failed to get user traits: ${message}`, }; } return { success: false, error: `Failed to get user traits: ${error instanceof Error ? error.message : "Unknown error"}`, }; } } export async function sendBulkEvents(events) { try { if (!events || events.length === 0) { throw new Error('Events array cannot be empty'); } if (events.length > 1000) { throw new Error('Maximum 1000 events per batch'); } // Validate all events have the same client_id const clientId = events[0].client_id; for (const event of events) { if (event.client_id !== clientId) { throw new Error('All events in a batch must have the same client_id'); } } // Transform all events to API format const payloads = events.map(event => ({ cid: event.cid, cna: event.cna, uid: event.uid, eid: event.eid, dtm: event.dtm, e: event.e, ev: event.ev, tna: event.tna, tv: event.tv, ...(event.sid && { sid: event.sid }), ...(event.ua && { ua: event.ua }), ...(event.sh && { sh: event.sh }), ...(event.sw && { sw: event.sw }), ...(event.l && { l: event.l }), ...(event.p && { p: event.p }), ...(event.an !== undefined && { an: event.an }), ...(event.vh && { vh: event.vh }), ...(event.vw && { vw: event.vw }), ...(event.pt && { pt: event.pt }), ...(event.pu && { pu: event.pu }), ...(event.pp && { pp: event.pp }), ...(event.pd && { pd: event.pd }), ...(event.pl && { pl: event.pl }), ...(event.pr && { pr: event.pr }), ...(event.ip && { ip: event.ip }), ...(event.tz && { tz: event.tz }), })); const eventsPayload = { events: payloads }; const response = await axios.post("https://api.cruxstack.com/api/v1/events", eventsPayload, { headers: { "Content-Type": "application/json", "x-client-id": clientId, }, }); if (response.status >= 200 && response.status < 300) { console.log(`Bulk events sent successfully: ${events.length} events`); return { success: true, processed: events.length, failed: 0 }; } else { throw new Error(`API returned status ${response.status}`); } } catch (error) { if (error instanceof AxiosError) { const message = error.response?.data?.message || error.message; console.error(`Failed to send bulk events: ${message}`); return { success: false, processed: 0, failed: events.length, errors: [message] }; } return { success: false, processed: 0, failed: events.length, errors: [error instanceof Error ? error.message : "Unknown error"] }; } }