@openpets/bento
Version:
Bento email marketing platform integration - manage subscribers, track events, send broadcasts, and analyze engagement
224 lines (186 loc) • 6.94 kB
text/typescript
interface BentoConfig {
publishableKey: string
secretKey: string
siteUuid: string
baseUrl?: string
}
class BentoClient {
private headers: Record<string, string>
private baseUrl: string
private siteUuid: string
constructor(config: BentoConfig) {
this.baseUrl = config.baseUrl || "https://app.bentonow.com/api/v1"
this.siteUuid = config.siteUuid
const authString = Buffer.from(`${config.publishableKey}:${config.secretKey}`).toString("base64")
this.headers = {
"Authorization": `Basic ${authString}`,
"User-Agent": `bento-node-${config.siteUuid}`,
"Content-Type": "application/json"
}
}
async get<T>(endpoint: string, params: Record<string, any> = {}): Promise<T> {
const queryParams = new URLSearchParams({
...params,
site_uuid: this.siteUuid
})
const response = await fetch(`${this.baseUrl}${endpoint}?${queryParams}`, {
method: "GET",
headers: this.headers
})
if (!response.ok) {
throw new Error(`Bento API Error: ${response.status} - ${await response.text()}`)
}
return response.json()
}
async post<T>(endpoint: string, data: Record<string, any> = {}): Promise<T> {
const body = JSON.stringify({
...data,
site_uuid: this.siteUuid
})
const response = await fetch(`${this.baseUrl}${endpoint}`, {
method: "POST",
headers: this.headers,
body
})
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Bento API Error: ${response.status} - ${errorText}`)
}
return response.json()
}
}
export class BentoAPI {
private client: BentoClient
constructor(config: BentoConfig) {
this.client = new BentoClient(config)
}
async importSubscribers(subscribers: any[]): Promise<number> {
if (subscribers.length === 0 || subscribers.length > 1000) {
throw new Error("Must send between 1 and 1,000 subscribers")
}
const result = await this.client.post<{ results: number }>("/batch/subscribers", { subscribers })
return result.results
}
async importEvents(events: any[]): Promise<number> {
if (events.length === 0 || events.length > 1000) {
throw new Error("Must send between 1 and 1,000 events")
}
const result = await this.client.post<{ results: number }>("/batch/events", { events })
return result.results
}
async sendTransactionalEmails(emails: any[]): Promise<number> {
if (emails.length === 0 || emails.length > 100) {
throw new Error("Must send between 1 and 100 emails")
}
const result = await this.client.post<{ results: number }>("/batch/emails", { emails })
return result.results
}
async getSubscriber(params: { email?: string; uuid?: string }): Promise<any> {
const result = await this.client.get<{ data: any }>("/fetch/subscribers", params)
return result.data || null
}
async createSubscriber(subscriber: any): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/subscribers", { subscriber })
return result.data || null
}
async getTags(): Promise<any> {
const result = await this.client.get<{ data: any }>("/fetch/tags")
return result.data
}
async createTag(params: { name: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/tags", { tag: params })
return result.data
}
async getFields(): Promise<any> {
const result = await this.client.get<{ data: any }>("/fetch/fields")
return result.data
}
async createField(params: { key: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/fields", { field: params })
return result.data
}
async getBroadcasts(): Promise<any> {
const result = await this.client.get<{ data: any }>("/fetch/broadcasts")
return result.data
}
async createBroadcast(broadcasts: any[]): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/broadcasts", { broadcasts })
return result.data
}
async getSiteStats(): Promise<any> {
const result = await this.client.get<{ data: any }>("/fetch/site_stats")
return result.data
}
async getSegmentStats(segmentId: string): Promise<any> {
const result = await this.client.get<{ data: any }>(`/fetch/segments/${segmentId}/stats`)
return result.data
}
async getReportStats(reportId: string): Promise<any> {
const result = await this.client.get<{ data: any }>(`/fetch/reports/${reportId}/stats`)
return result.data
}
async getFormResponses(formId: string): Promise<any> {
const result = await this.client.get<{ data: any }>(`/fetch/forms/${formId}`)
return result.data
}
async addTag(params: { email: string; tagName: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/commands", {
command: {
command: "add_tag",
email: params.email,
query: params.tagName
}
})
return result.data
}
async removeTag(params: { email: string; tagName: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/commands", {
command: {
command: "remove_tag",
email: params.email,
query: params.tagName
}
})
return result.data
}
async addField(params: { email: string; field: { key: string; value: any } }): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/commands", {
command: {
command: "add_field",
email: params.email,
query: params.field
}
})
return result.data
}
async removeField(params: { email: string; fieldName: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/fetch/commands", {
command: {
command: "remove_field",
email: params.email,
query: params.fieldName
}
})
return result.data
}
async validateEmail(params: { email: string; ip?: string; name?: string; userAgent?: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/experimental/validation", params)
return result.data
}
async geoLocateIP(ip: string): Promise<any> {
const result = await this.client.get<{ data: any }>(`/experimental/geolocation/${ip}`)
return result.data
}
async getBlacklistStatus(params: { domain?: string; ipAddress?: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/experimental/blacklist", params)
return result.data
}
async getContentModeration(content: string): Promise<any> {
const result = await this.client.post<{ data: any }>("/experimental/content-moderation", { content })
return result.data
}
async guessGender(params: { name: string }): Promise<any> {
const result = await this.client.post<{ data: any }>("/experimental/gender", params)
return result.data
}
}