add campaign api (#274)

This commit is contained in:
KM Koushik
2025-10-18 10:31:43 +11:00
committed by GitHub
parent e631f16c85
commit a5ca3b2f87
31 changed files with 2093 additions and 187 deletions
+35
View File
@@ -49,3 +49,38 @@ usesend.emails.send({
text: "useSend is the best open source product to send emails",
});
```
## Campaigns
Create and manage email campaigns:
```javascript
import { UseSend } from "usesend";
const usesend = new UseSend("us_12345");
// Create a campaign
const campaign = await usesend.campaigns.create({
name: "Welcome Series",
from: "hello@company.com",
subject: "Welcome to our platform!",
contactBookId: "cb_12345",
html: "<h1>Welcome!</h1><p>Thanks for joining us.</p>",
sendNow: false,
});
// Schedule a campaign
await usesend.campaigns.schedule(campaign.data.id, {
scheduledAt: "2024-12-01T09:00:00Z",
batchSize: 1000,
});
// Get campaign details
const details = await usesend.campaigns.get(campaign.data.id);
// Pause a campaign
await usesend.campaigns.pause(campaign.data.id);
// Resume a campaign
await usesend.campaigns.resume(campaign.data.id);
```
+1
View File
@@ -1,2 +1,3 @@
export { UseSend } from "./src/usesend";
export { UseSend as Unsend } from "./src/usesend"; // deprecated alias
export { Campaigns } from "./src/campaign";
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "usesend-js",
"version": "1.5.5",
"version": "1.5.6",
"description": "",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
+94
View File
@@ -0,0 +1,94 @@
import { UseSend } from "./usesend";
import { paths } from "../types/schema";
import { ErrorResponse } from "../types";
type CreateCampaignPayload =
paths["/v1/campaigns"]["post"]["requestBody"]["content"]["application/json"];
type CreateCampaignResponse = {
data: CreateCampaignResponseSuccess | null;
error: ErrorResponse | null;
};
type CreateCampaignResponseSuccess =
paths["/v1/campaigns"]["post"]["responses"]["200"]["content"]["application/json"];
type GetCampaignResponseSuccess =
paths["/v1/campaigns/{campaignId}"]["get"]["responses"]["200"]["content"]["application/json"];
type GetCampaignResponse = {
data: GetCampaignResponseSuccess | null;
error: ErrorResponse | null;
};
type ScheduleCampaignPayload =
paths["/v1/campaigns/{campaignId}/schedule"]["post"]["requestBody"]["content"]["application/json"];
type ScheduleCampaignResponseSuccess =
paths["/v1/campaigns/{campaignId}/schedule"]["post"]["responses"]["200"]["content"]["application/json"];
type ScheduleCampaignResponse = {
data: ScheduleCampaignResponseSuccess | null;
error: ErrorResponse | null;
};
type CampaignActionResponseSuccess = { success: boolean };
type CampaignActionResponse = {
data: CampaignActionResponseSuccess | null;
error: ErrorResponse | null;
};
export class Campaigns {
constructor(private readonly usesend: UseSend) {
this.usesend = usesend;
}
async create(
payload: CreateCampaignPayload,
): Promise<CreateCampaignResponse> {
const data = await this.usesend.post<CreateCampaignResponseSuccess>(
`/campaigns`,
payload,
);
return data;
}
async get(campaignId: string): Promise<GetCampaignResponse> {
const data = await this.usesend.get<GetCampaignResponseSuccess>(
`/campaigns/${campaignId}`,
);
return data;
}
async schedule(
campaignId: string,
payload: ScheduleCampaignPayload,
): Promise<ScheduleCampaignResponse> {
const data = await this.usesend.post<ScheduleCampaignResponseSuccess>(
`/campaigns/${campaignId}/schedule`,
payload,
);
return data;
}
async pause(campaignId: string): Promise<CampaignActionResponse> {
const data = await this.usesend.post<CampaignActionResponseSuccess>(
`/campaigns/${campaignId}/pause`,
{},
);
return data;
}
async resume(campaignId: string): Promise<CampaignActionResponse> {
const data = await this.usesend.post<CampaignActionResponseSuccess>(
`/campaigns/${campaignId}/resume`,
{},
);
return data;
}
}
+2
View File
@@ -2,6 +2,7 @@ import { ErrorResponse } from "../types";
import { Contacts } from "./contact";
import { Emails } from "./email";
import { Domains } from "./domain";
import { Campaigns } from "./campaign";
const defaultBaseUrl = "https://app.usesend.com";
// eslint-disable-next-line turbo/no-undeclared-env-vars
@@ -18,6 +19,7 @@ export class UseSend {
readonly emails = new Emails(this);
readonly domains = new Domains(this);
readonly contacts = new Contacts(this);
readonly campaigns = new Campaigns(this);
url = baseUrl;
constructor(
+276
View File
@@ -959,6 +959,282 @@ export interface paths {
};
trace?: never;
};
"/v1/campaigns": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post: {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json": {
name: string;
from: string;
subject: string;
previewText?: string;
contactBookId: string;
content?: string;
html?: string;
replyTo?: string | string[];
cc?: string | string[];
bcc?: string | string[];
sendNow?: boolean;
/** @description Timestamp in ISO 8601 format or natural language (e.g., 'tomorrow 9am', 'next monday 10:30') */
scheduledAt?: string;
batchSize?: number;
};
};
};
responses: {
/** @description Create a campaign */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
id: string;
name: string;
from: string;
subject: string;
previewText: string | null;
contactBookId: string | null;
html: string | null;
content: string | null;
status: string;
/** Format: date-time */
scheduledAt: string | null;
batchSize: number;
batchWindowMinutes: number;
total: number;
sent: number;
delivered: number;
opened: number;
clicked: number;
unsubscribed: number;
bounced: number;
hardBounced: number;
complained: number;
replyTo: string[];
cc: string[];
bcc: string[];
/** Format: date-time */
createdAt: string;
/** Format: date-time */
updatedAt: string;
};
};
};
};
};
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/campaigns/{campaignId}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get: {
parameters: {
query?: never;
header?: never;
path: {
campaignId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Get campaign details */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
id: string;
name: string;
from: string;
subject: string;
previewText: string | null;
contactBookId: string | null;
html: string | null;
content: string | null;
status: string;
/** Format: date-time */
scheduledAt: string | null;
batchSize: number;
batchWindowMinutes: number;
total: number;
sent: number;
delivered: number;
opened: number;
clicked: number;
unsubscribed: number;
bounced: number;
hardBounced: number;
complained: number;
replyTo: string[];
cc: string[];
bcc: string[];
/** Format: date-time */
createdAt: string;
/** Format: date-time */
updatedAt: string;
};
};
};
};
};
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/campaigns/{campaignId}/schedule": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post: {
parameters: {
query?: never;
header?: never;
path: {
campaignId: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": {
/** @description Timestamp in ISO 8601 format or natural language (e.g., 'tomorrow 9am', 'next monday 10:30') */
scheduledAt?: string;
batchSize?: number;
};
};
};
responses: {
/** @description Schedule a campaign */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
success: boolean;
};
};
};
};
};
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/campaigns/{campaignId}/pause": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post: {
parameters: {
query?: never;
header?: never;
path: {
campaignId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Pause a campaign */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
success: boolean;
};
};
};
};
};
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/v1/campaigns/{campaignId}/resume": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post: {
parameters: {
query?: never;
header?: never;
path: {
campaignId: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Resume a campaign */
200: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": {
success: boolean;
};
};
};
};
};
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
}
export type webhooks = Record<string, never>;
export interface components {