@sinaptik/retein-sdk
Version:
Retein Node.js SDK for event-based email marketing automation.
180 lines (179 loc) • 7.21 kB
JavaScript
"use strict";
// File: retein-sdk.ts
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReteinSDK = void 0;
const node_fetch_1 = __importDefault(require("node-fetch"));
class ReteinSDK {
constructor(public_key, options) {
var _a, _b;
this.identityId = null;
this.sessionId = null;
this.distinctId = null;
this.public_key = public_key;
this.host = (_a = options === null || options === void 0 ? void 0 : options.host) !== null && _a !== void 0 ? _a : 'https://api.retein.io';
this.verbose = (_b = options === null || options === void 0 ? void 0 : options.verbose) !== null && _b !== void 0 ? _b : false;
if (this.verbose) {
console.log('[ReteinSDK] Initialized with public_key:', public_key);
}
}
static async create(public_key, options) {
return new ReteinSDK(public_key, options);
}
async _retrieveSessionId(options) {
const sessionDetails = {
...(options ? options : {}),
identity_id: this.identityId,
};
this.log('[validateAndRetrieveSessionId] Creating session with:', sessionDetails);
const session = await this.fetchWithRetry(`${this.host}/api/create-session`, {
method: 'POST',
headers: this.defaultHeaders(),
body: JSON.stringify(sessionDetails),
});
if (!session.ok) {
throw new Error('Failed to retrieve session');
}
const data = await session.json();
this.sessionId = data.id;
this.log('[validateAndRetrieveSessionId] Retrieved session ID:', this.sessionId);
}
async track(eventName, properties) {
if (!this.identityId) {
throw new Error('User identity not identified');
}
const track_event = {
event_name: eventName,
identity_id: this.identityId,
session_id: this.sessionId,
public_key: this.public_key,
params: properties,
};
this.log('[track] Sending track event:', track_event);
const response = await this.fetchWithRetry(`${this.host}/api/events`, {
method: 'POST',
headers: this.defaultHeaders(),
body: JSON.stringify(track_event),
});
if (!response.ok) {
throw new Error(`Failed to track event: ${response.statusText}`);
}
this.log('[track] Event tracked successfully');
}
async identify(distinctId, options) {
if (options !== undefined && typeof options !== 'object') {
throw new Error('Session options must be provided as an object.');
}
if (this.identityId && this.distinctId === distinctId) {
this.log('[retrieveIdentityId] Identity ID already exists:', this.identityId);
return;
}
this.distinctId = distinctId;
this.log('[retrieveIdentityId] Requesting identity from server...');
const identity = await this.fetchWithRetry(`${this.host}/api/fetch-backend-identity`, {
method: 'POST',
headers: this.defaultHeaders(),
body: JSON.stringify({
distinct_id: this.distinctId,
}),
});
if (!identity.ok) {
throw new Error('Failed to retrieve identity');
}
const data = await identity.json();
this.identityId = data.id;
if (options === null || options === void 0 ? void 0 : options.session_id) {
this.sessionId = options.session_id;
}
else {
// Retrieve session
await this._retrieveSessionId(options);
}
this.log('[retrieveIdentityId] Retrieved identity ID:', this.identityId);
this.log('[identify] Identify event sent successfully');
}
/**
* List the last sessions for a specific identity
*
* @param distinctId The distinct ID of the user
* @param limit Maximum number of sessions to return (between 5-20, default: 5)
* @returns Object containing array of session objects
*/
async listLastSessions(distinctId, limit) {
// Build query parameters
const queryParams = new URLSearchParams();
if (limit !== undefined) {
queryParams.append('limit', limit.toString());
}
queryParams.append('distinct_id', distinctId);
this.log('[listLastSessions] Fetching sessions for identity:', distinctId);
const response = await this.fetchWithRetry(`${this.host}/api/sessions?${queryParams.toString()}`, {
method: 'GET',
headers: this.defaultHeaders(),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Failed to retrieve sessions: ${response.statusText}. ${errorText}`);
}
const data = await response.json();
this.log('[listLastSessions] Retrieved sessions successfully');
return data.data;
}
async updateUser(properties) {
if (!this.identityId) {
throw new Error('User identity not identified');
}
const { email, name, ...restProperties } = properties;
const payload = { email, name, properties: restProperties };
this.log('[updateUser] Sending update user payload:', payload);
const response = await this.fetchWithRetry(`${this.host}/api/update-user/${this.identityId}`, {
method: 'PUT',
headers: this.defaultHeaders(),
body: JSON.stringify(payload),
});
if (!response.ok) {
const errorResponse = await response.json();
throw new Error(`Failed to update user: ${errorResponse.message}`);
}
this.log('[updateUser] User updated successfully');
}
defaultHeaders() {
return {
'Content-Type': 'application/json',
'x-api-key': this.public_key,
};
}
async fetchWithRetry(url, options, retries = 3) {
let attempt = 0;
while (attempt < retries) {
try {
this.log(`[fetchWithRetry]: Fetching ${url}`);
const res = await (0, node_fetch_1.default)(url, options);
if (res.ok)
return res;
this.log(`[fetchWithRetry] Response not OK (status ${res.status})`);
}
catch (err) {
this.log(`[fetchWithRetry] Fetch attempt ${attempt + 1} failed:`, err);
}
attempt++;
await new Promise(resolve => setTimeout(resolve, 3000));
}
throw new Error(`Failed to fetch ${url} after ${retries} attempts`);
}
log(...args) {
if (this.verbose) {
console.log('[ReteinSDK]', ...args);
}
}
reset() {
this.log('[reset] Resetting identity and session');
this.identityId = null;
this.sessionId = null;
this.distinctId = null;
}
}
exports.ReteinSDK = ReteinSDK;
exports.default = ReteinSDK;