Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for /api/v2/batch #136

Open
samygch opened this issue Feb 14, 2023 · 6 comments
Open

Support for /api/v2/batch #136

samygch opened this issue Feb 14, 2023 · 6 comments

Comments

@samygch
Copy link

samygch commented Feb 14, 2023

Hi, I was wondering if there's support for the Track V2 API, more specifically https://track.customer.io/api/v2/batch. If not, is there any workaround that we could use to send data through batch calls for identify and destroy functions?

@mike-engel
Copy link
Collaborator

Hey @samygch, right now this library doesn't have any support for v2 of the track api. The workaround for now would be to make the request manually using an request library of your choice until we add support for it within the client library

@TimeTerminal
Copy link

@mike-engel is there a public backlog or another place where we can track when this would be made available? Or get an estimation for it?

@mike-engel
Copy link
Collaborator

@TimeTerminal unfortunately we don't have a public backlog, nor can I give any kind of timeline for when we'll be able to get this in ourselves

@Zambonilli
Copy link

A hacky but working way to use some of the v2 Track events before there are strongly typed signatures is to pass in the v2 url as part of the defaults constructor and dispatch on the TrackClient's request object directly.

For example, I needed to use track event v2 for dedup and back dating.

const cioV2 = new TrackClient(
  siteId
  apiKey,
  { url: 'https://track.customer.io/api/v2' },
);

cioV2.request.post(`${cioV2.trackRoot}/entity`, {
  type: 'person',
  identifiers: {
    id,
  },
  action: 'event',
  name: 'my-custom-event-name',  
  id: ulid,
  timestamp: eventUnixTime,
  attributes: {}
});

@frankiecio
Copy link

+1 from our friends at Novelcrafter. 😄

@nenorrell
Copy link

nenorrell commented Nov 5, 2024

If anyone else is looking for an interim solution for things like entity support, I threw together this:

View typings
export type CioEntity = "person" | "object" | "delivery";

// Common Types
type CioRelationshipIdentifier = {
    id?: string;
    email?: string;
    object_type_id?: string;
    object_id?: string;
};

type CioRelationshipAttributes = {
    role?: string;
    date_created?: number;
};

type CioRelationship = {
    identifiers: CioRelationshipIdentifier;
    relationship_attributes?: CioRelationshipAttributes;
};

// Attribute Types for Different Types
type CioPersonAttributes = {
    cio_subscription_preferences?: {
        topics: Record<string, boolean>;
    };
};

type CioObjectAttributes = Record<string, any>;

type CioDeliveryAttributes = {
    device_token: string;
};

// Actions for Different Types
type CioPersonActions =
    | "identify"
    | "unsuppress"
    | "suppress"
    | "merge"
    | "delete_device"
    | "add_device"
    | "delete_relationships"
    | "add_relationships"
    | "page"
    | "screen"
    | "event"
    | "delete";

type CioObjectActions =
    | "delete_relationships"
    | "add_relationships"
    | "delete"
    | "identify_anonymous"
    | "identify";

type CioDeliveryActions = "event";

// Identifier Types for Each `type`
type CioPersonIdentifier = {
    id: string;
};

type CioObjectIdentifier = {
    object_type_id: string;
    object_id: string;
};

// Base Type for "person" and "object"
interface CioBaseType<
    TType extends CioEntity,
    TAction,
    TIdentifier,
    TAttributes,
> {
    type: TType;
    action: TAction;
    identifiers: TIdentifier;
    attributes: TAttributes;
    cio_relationships?: CioRelationship[];
}

// Specific Types for Each Type of Payload
type CioPersonPayload = CioBaseType<
    "person",
    CioPersonActions,
    CioPersonIdentifier,
    CioPersonAttributes
>;

type CioObjectPayload = CioBaseType<
    "object",
    CioObjectActions,
    CioObjectIdentifier,
    CioObjectAttributes
>;

// Separate CioDeliveryPayload Without Identifiers
type CioDeliveryPayload = {
    type: "delivery";
    action: CioDeliveryActions;
    name: string;
    attributes: CioDeliveryAttributes;
    cio_relationships?: CioRelationship[];
};

// Discriminated Union Type
export type CioEntityPayload =
    | CioPersonPayload
    | CioObjectPayload
    | CioDeliveryPayload;

// Mapping Type: CioEntityData
export type CioEntityData = {
    person: Omit<CioPersonPayload, "type">;
    object: Omit<CioObjectPayload, "type">;
    delivery: Omit<CioDeliveryPayload, "type">;
};

export type CioError = {
    errors: {
        reason: string;
        field: string;
        message: string;
    }[];
};
import type { CioEntity, CioEntityData } from "./cio.types";
import axios from "axios";
import { Buffer } from "buffer"; // Import Buffer to handle Base64 encoding

/**
 * Customer.io's Node SDK doesn't support their v2 tracking API,
 * so we just use their REST API directly.
 * https://github.com/customerio/customerio-node/issues/136
 */
export class CioTrackV2 {
    private baseUrl = "https://track.customer.io/api/v2";
    private authHeader: string;

    constructor(
        private siteId: NexusEnvKeys["CUSTOMERIO_TRACKING_SITE_ID"],
        private apiKey: NexusEnvKeys["CUSTOMERIO_TRACKING_API_KEY"],
    ) {
        // Set up Basic Auth header using Base64 encoding of API_key:
        const credentials = `${this.siteId}:${this.apiKey}`;
        this.authHeader = Buffer.from(credentials).toString("base64");
    }

    public async createEntity<T extends CioEntity>(
        entity: T,
        data: CioEntityData[T],
    ): Promise<void> {
        await axios.post(
            `${this.baseUrl}/entity`,
            {
                type: entity,
                ...data,
            },
            {
                headers: {
                    "Content-Type": "application/json",
                    Authorization: `Basic ${this.authHeader}`,
                },
            },
        );
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants