Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,393 @@
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
import { PieceAuth, Property } from '@activepieces/pieces-framework';
import { OAuth2GrantType } from '@activepieces/shared';
import * as properties from './properties';
import * as schemas from './schemas';
import {
AddContactToMailingListParams,
AddTagToContactParams,
AddUpdateContactParams,
AuthorizationParams,
CloneCampaignParams,
CreateCampaignParams,
CreateCampaignResponse,
CreateTagParams,
ListCampaignParams,
ListCampaignResponse,
ListContactsParams,
ListContactsResponse,
ListMailingListsParams,
ListMailingListsResponse,
ListTagsResponse,
ListTopicsResponse,
RemoveTagParams,
SendCampaignParams,
UnsubscribeContactParams,
} from './types';
export const zohoCampaignsAuth = PieceAuth.OAuth2({
props: {
location: Property.StaticDropdown({
displayName: 'Data Center',
description: 'The data center location of your Zoho Campaigns account',
required: true,
options: {
options: [
{
label: 'zoho.com (United States)',
value: 'zoho.com',
},
{
label: 'zoho.eu (Europe)',
value: 'zoho.eu',
},
{
label: 'zoho.in (India)',
value: 'zoho.in',
},
{
label: 'zoho.com.au (Australia)',
value: 'zoho.com.au',
},
{
label: 'zoho.jp (Japan)',
value: 'zoho.jp',
},
{
label: 'zoho.com.cn (China)',
value: 'zoho.com.cn',
},
],
},
}),
},
description: 'Connect your Zoho Campaigns account using OAuth2',
grantType: OAuth2GrantType.AUTHORIZATION_CODE,
required: true,
authUrl: 'https://accounts.{location}/oauth/v2/auth',
tokenUrl: 'https://accounts.{location}/oauth/v2/token',
scope: ['ZohoCampaigns.campaign.ALL', 'ZohoCampaigns.contact.ALL'],
});
export const zohoCampaignsCommon = {
baseUrl: (location = 'zoho.com') => {
return `https://campaigns.${location}/api/v1.1`;
},
endpoints: {
createCampaign: '/createCampaign',
createTag: '/tag/add',
cloneCampaign: '/json/clonecampaign',
sendCampaign: '/sendcampaign',
addUpdateContact: '/json/listsubscribe',
addTagToContact: '/tag/associate',
removeTag: '/tag/deassociate',
unsubscribeContact: '/json/listunsubscribe',
addContactToMailingList: '/addlistsubscribersinbulk',
listContacts: '/getlistsubscribers',
listCampaigns: '/recentcampaigns',
listMailingLists: '/getmailinglists',
listTopics: '/topics',
listTags: '/tag/getalltags',
},
baseHeaders: (accessToken: string) => {
return {
Authorization: `Zoho-oauthtoken ${accessToken}`,
'Content-Type': 'application/json',
};
},
baseParams: {
resfmt: 'JSON',
},
// Properties
createCampaignProperties: properties.createCampaign,
cloneCampaignProperties: properties.cloneCampaign,
sendCampaignProperties: properties.sendCampaign,
addUpdateContactProperties: properties.addUpdateContact,
addTagToContactProperties: properties.addTagToContact,
removeTagProperties: properties.removeTag,
unsubscribeContactProperties: properties.unsubscribeContact,
addContactToMailingListProperties: properties.addContactToMailingList,
findContactProperties: properties.findContact,
findCampaignProperties: properties.findCampaign,
newContactProperties: properties.newContact,
unsubscribeProperties: properties.unsubscribe,
// Schemas
createCampaignSchema: schemas.createCampaign,
cloneCampaignSchema: schemas.cloneCampaign,
sendCampaignSchema: schemas.sendCampaign,
addUpdateContactSchema: schemas.addUpdateContact,
addTagToContactSchema: schemas.addTagToContact,
removeTagSchema: schemas.removeTag,
unsubscribeContactSchema: schemas.unsubscribeContact,
addContactToMailingListSchema: schemas.addContactToMailingList,
findContactSchema: schemas.findContact,
findCampaignSchema: schemas.findCampaign,
// Methods
createCampaign: async ({
accessToken,
location = 'zoho.com',
...campaignParams
}: CreateCampaignParams & { location?: string }) => {
const {
list_details: listDetails,
topicId,
...restParams
} = campaignParams;
const list_details = JSON.stringify(listDetails);
const body = new URLSearchParams({
resfmt: 'json',
list_details,
...restParams,
...(topicId && { topicId }),
}).toString();
const response = await httpClient.sendRequest<CreateCampaignResponse>({
method: HttpMethod.POST,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.createCampaign}`,
headers: {
...zohoCampaignsCommon.baseHeaders(accessToken),
'Content-Type': 'application/x-www-form-urlencoded',
},
body,
});
return response.body;
},
createTag: async ({ accessToken, location = 'zoho.com', tagName }: CreateTagParams & { location?: string }) => {
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.createTag}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
tagName,
},
});
return response.body;
},
cloneCampaign: async ({ accessToken, location = 'zoho.com', campaigninfo }: CloneCampaignParams & { location?: string }) => {
const strCampaignInfo = JSON.stringify(campaigninfo);
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.cloneCampaign}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
campaigninfo: strCampaignInfo,
},
});
return response.body;
},
sendCampaign: async ({ accessToken, location = 'zoho.com', campaignkey }: SendCampaignParams & { location?: string }) => {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.sendCampaign}`,
headers: {
...zohoCampaignsCommon.baseHeaders(accessToken),
'Content-Type': 'application/x-www-form-urlencoded',
},
queryParams: {
...zohoCampaignsCommon.baseParams,
campaignkey,
},
});
return response.body;
},
addUpdateContact: async ({
accessToken,
location = 'zoho.com',
...contactParams
}: AddUpdateContactParams & { location?: string }) => {
const {
listkey,
contactinfo: contactInfoObj,
source,
topic_id,
} = contactParams;
const body = new URLSearchParams({
...zohoCampaignsCommon.baseParams,
listkey,
...(source && { source }),
...(topic_id && { topic_id }),
contactinfo: JSON.stringify(contactInfoObj),
}).toString();
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.addUpdateContact}`,
headers: {
...zohoCampaignsCommon.baseHeaders(accessToken),
'Content-Type': 'application/x-www-form-urlencoded',
},
body,
});
return response.body;
},
addTagToContact: async ({
accessToken,
location = 'zoho.com',
...tagParams
}: AddTagToContactParams & { location?: string }) => {
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.addTagToContact}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
...tagParams,
},
});
return response.body;
},
removeTag: async ({ accessToken, location = 'zoho.com', ...tagParams }: RemoveTagParams & { location?: string }) => {
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.removeTag}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
...tagParams,
},
});
return response.body;
},
unsubscribeContact: async ({
accessToken,
location = 'zoho.com',
...unsubscribeParams
}: UnsubscribeContactParams & { location?: string }) => {
const {
contactinfo: contactInfoObj,
listkey,
topic_id,
} = unsubscribeParams;
const body = new URLSearchParams({
...zohoCampaignsCommon.baseParams,
listkey,
...(topic_id && { topic_id }),
contactinfo: JSON.stringify(contactInfoObj),
}).toString();
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.unsubscribeContact}`,
headers: {
...zohoCampaignsCommon.baseHeaders(accessToken),
'Content-Type': 'application/x-www-form-urlencoded',
},
body,
});
return response.body;
},
addContactToMailingList: async ({
accessToken,
location = 'zoho.com',
...mailingListParams
}: AddContactToMailingListParams & { location?: string }) => {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.addContactToMailingList}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
...mailingListParams,
},
});
return response.body;
},
listContacts: async ({
accessToken,
location = 'zoho.com',
listkey,
...rest
}: ListContactsParams & { location?: string }) => {
const { fromindex, range, ...otherParams } = rest;
const strFromIndex =
typeof fromindex === 'number' ? String(fromindex) : undefined;
const strRange = typeof range === 'number' ? String(range) : undefined;
const queryParams = {
...zohoCampaignsCommon.baseParams,
listkey,
...(fromindex && { fromindex: strFromIndex }),
...(range && { range: strRange }),
...otherParams,
};
const response = await httpClient.sendRequest<ListContactsResponse>({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.listContacts}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams,
});
return response.body.list_of_details || [];
},
listCampaigns: async ({
accessToken,
location = 'zoho.com',
...filterParams
}: ListCampaignParams & { location?: string }) => {
const { fromindex, range, ...otherParams } = filterParams;
const strFromIndex =
typeof fromindex === 'number' ? String(fromindex) : undefined;
const strRange = typeof range === 'number' ? String(range) : undefined;
const queryParams = {
...zohoCampaignsCommon.baseParams,
...(fromindex && { fromindex: strFromIndex }),
...(range && { range: strRange }),
...otherParams,
};
const response = await httpClient.sendRequest<ListCampaignResponse>({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.listCampaigns}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams,
});
return response.body.recent_campaigns || [];
},
listMailingLists: async ({
accessToken,
location = 'zoho.com',
...filterParams
}: ListMailingListsParams & { location?: string }) => {
const { fromindex, range, ...otherParams } = filterParams;
const strFromIndex =
typeof fromindex === 'number' ? String(fromindex) : undefined;
const strRange = typeof range === 'number' ? String(range) : undefined;
const queryParams = {
...zohoCampaignsCommon.baseParams,
...(fromindex && { fromindex: strFromIndex }),
...(range && { range: strRange }),
...otherParams,
};
const response = await httpClient.sendRequest<ListMailingListsResponse>({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.listMailingLists}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams,
});
return response.body.list_of_details || [];
},
listTopics: async ({ accessToken, location = 'zoho.com' }: AuthorizationParams & { location?: string }) => {
const response = await httpClient.sendRequest<ListTopicsResponse>({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.listTopics}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
},
});
return response.body.topicDetails;
},
listTags: async ({ accessToken, location = 'zoho.com' }: AuthorizationParams & { location?: string }) => {
const response = await httpClient.sendRequest<ListTagsResponse>({
method: HttpMethod.GET,
url: `${zohoCampaignsCommon.baseUrl(location)}${zohoCampaignsCommon.endpoints.listTags}`,
headers: zohoCampaignsCommon.baseHeaders(accessToken),
queryParams: {
...zohoCampaignsCommon.baseParams,
},
});
return response.body.tags;
},
};

View File

@@ -0,0 +1,471 @@
import { PiecePropValueSchema, Property } from '@activepieces/pieces-framework';
import { zohoCampaignsAuth, zohoCampaignsCommon } from '.';
import { Tag } from './types';
// Custom Properties
const campaignDropdown = () =>
Property.Dropdown({
auth: zohoCampaignsAuth,
displayName: 'Campaign',
description: 'Select the campaign',
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
const authValue = auth as PiecePropValueSchema<typeof zohoCampaignsAuth>;
const location = authValue.props?.['location'] || 'zoho.com';
if (!auth) {
return {
disabled: true,
placeholder: 'Connect your Zoho Campaigns account first',
options: [],
};
}
const campaigns = await zohoCampaignsCommon.listCampaigns({
accessToken: authValue.access_token,
location,
});
if (campaigns.length === 0) {
return {
disabled: true,
placeholder: 'No campaigns found',
options: [],
};
}
return {
options: campaigns.map((campaign) => ({
label: campaign.campaign_name,
value: campaign.campaign_key,
})),
};
},
});
const tagDropdown = ({ required = true }: { required?: boolean }) =>
Property.Dropdown({
auth: zohoCampaignsAuth,
displayName: 'Tag',
description: 'Select the tag to associate with the contact',
required: required,
refreshers: ['auth'],
options: async ({
auth,
}): Promise<{
disabled?: boolean;
placeholder?: string;
options: Array<{ label: string; value: string }>;
}> => {
const authValue = auth as PiecePropValueSchema<typeof zohoCampaignsAuth>;
const location = authValue.props?.['location'] || 'zoho.com';
if (!auth) {
return {
disabled: true,
placeholder: 'Connect your Zoho Campaigns account first',
options: [],
};
}
const tags = await zohoCampaignsCommon.listTags({
accessToken: authValue.access_token,
location,
});
if (!tags || tags.length === 0) {
return {
disabled: true,
placeholder: 'No tags found',
options: [],
};
}
const tagOptions = tags.flatMap((tagMap: Tag) =>
Object.values(tagMap).map((tag: any) => ({
label: tag.tag_name,
value: tag.tag_name,
}))
);
return {
options: tagOptions,
};
},
});
const mailingListDropdown = ({ required = true }) =>
Property.Dropdown({
auth: zohoCampaignsAuth,
displayName: 'Mailing List',
description: 'Select the mailing list',
required: required,
refreshers: ['auth'],
options: async ({ auth }) => {
const authValue = auth as PiecePropValueSchema<typeof zohoCampaignsAuth>;
const location = authValue.props?.['location'] || 'zoho.com';
if (!auth) {
return {
disabled: true,
placeholder: 'Connect your Zoho Campaigns account first',
options: [],
};
}
const mailingLists = await zohoCampaignsCommon.listMailingLists({
accessToken: authValue.access_token,
location,
});
if (mailingLists.length === 0) {
return {
disabled: true,
placeholder: 'No mailing lists found',
options: [],
};
}
return {
options: mailingLists.map((list) => ({
label: list.listname,
value: list.listkey,
})),
};
},
});
const mailingListMultiSelectDropdown = ({ required = true }) =>
Property.MultiSelectDropdown({
auth: zohoCampaignsAuth,
displayName: 'Mailing Lists',
description: 'Select the mailing lists',
required: required,
refreshers: ['auth'],
options: async ({ auth }) => {
const authValue = auth as PiecePropValueSchema<typeof zohoCampaignsAuth>;
const location = authValue.props?.['location'] || 'zoho.com';
if (!auth) {
return {
disabled: true,
placeholder: 'Connect your Zoho Campaigns account first',
options: [],
};
}
const mailingLists = await zohoCampaignsCommon.listMailingLists({
accessToken: authValue.access_token,
location,
});
if (mailingLists.length === 0) {
return {
disabled: true,
placeholder: 'No mailing lists found',
options: [],
};
}
return {
options: mailingLists.map((list) => ({
label: list.listname,
value: list.listkey,
})),
};
},
});
const topicDropdown = ({ required = true }) =>
Property.Dropdown({
auth: zohoCampaignsAuth,
displayName: 'Topic',
description: 'Select the topic',
required: required,
refreshers: ['auth'],
options: async ({ auth }) => {
const authValue = auth as PiecePropValueSchema<typeof zohoCampaignsAuth>;
const location = authValue.props?.['location'] || 'zoho.com';
if (!auth) {
return {
disabled: true,
placeholder: 'Connect your Zoho Campaigns account first',
options: [],
};
}
const topics = await zohoCampaignsCommon.listTopics({
accessToken: authValue.access_token,
location,
});
if (topics.length === 0) {
return {
disabled: true,
placeholder: 'No topics found',
options: [],
};
}
return {
options: topics.map((topic) => ({
label: topic.topicName,
value: topic.topicId,
})),
};
},
});
const contactInformation = Property.DynamicProperties({
displayName: 'Contact Information',
description: 'Information about the contact',
required: true,
auth: zohoCampaignsAuth,
refreshers: ['auth'],
props: async () => ({
'Contact Email': Property.ShortText({
displayName: 'Contact Email',
description: 'Email address of the contact',
required: true,
}),
'First Name': Property.ShortText({
displayName: 'First Name',
description: 'First name of the contact',
required: false,
}),
'Last Name': Property.ShortText({
displayName: 'Last Name',
description: 'Last name of the contact',
required: false,
}),
Phone: Property.ShortText({
displayName: 'Phone',
description: 'Phone number of the contact',
required: false,
}),
'Company Name': Property.ShortText({
displayName: 'Company Name',
description: 'Company name of the contact',
required: false,
}),
additionalFields: Property.Object({
displayName: 'Additional Fields',
description:
'Additional fields for the contact in key-value pairs. For example, {"City": "New York", "State": "NY"}',
required: false,
}),
}),
});
// Action Properties
export const createCampaign = () => ({
campaignname: Property.ShortText({
displayName: 'Campaign Name',
description: 'A name to your campaign',
required: true,
}),
from_email: Property.ShortText({
displayName: 'From Email',
description: 'Sender email address for the campaign',
required: true,
}),
subject: Property.ShortText({
displayName: 'Subject',
description: 'The subject line of the campaign',
required: true,
}),
list_details: mailingListMultiSelectDropdown({ required: true }),
content_url: Property.ShortText({
displayName: 'Content URL',
description: 'Public URL containing the HTML content for your campaign',
required: false,
}),
topicId: topicDropdown({ required: false }),
});
export const cloneCampaign = () => ({
campaignkey: campaignDropdown(),
campaignname: Property.ShortText({
displayName: 'Campaign Name',
description: 'New name for the cloned campaign',
required: false,
}),
subject: Property.ShortText({
displayName: 'Subject',
description: 'New subject line for the cloned campaign',
required: false,
}),
from_name: Property.ShortText({
displayName: 'From Name',
description: 'Sender name for the cloned campaign',
required: false,
}),
from_add: Property.ShortText({
displayName: 'From Email',
description: 'Sender email address for the cloned campaign',
required: false,
}),
reply_to: Property.ShortText({
displayName: 'Reply-To Email',
description: 'Reply-to email address for the cloned campaign',
required: false,
}),
encode_type: Property.ShortText({
displayName: 'Encoding Type',
description: 'Email encoding type (e.g., UTF-8)',
required: false,
}),
});
export const sendCampaign = () => ({
campaignkey: campaignDropdown(),
});
export const addUpdateContact = () => ({
listkey: mailingListDropdown({ required: true }),
contactinfo: contactInformation,
source: Property.ShortText({
displayName: 'Source',
description: 'Contact source can be added.',
required: false,
}),
topic_id: topicDropdown({ required: false }),
});
export const addTagToContact: {
tagName: any;
lead_email: any;
} = {
tagName: tagDropdown({ required: true }),
lead_email: Property.ShortText({
displayName: 'Contact Email',
description: 'Email address of the contact to tag',
required: true,
}),
};
export const removeTag: {
tagName: any;
lead_email: any;
} = {
tagName: tagDropdown({ required: true }),
lead_email: Property.ShortText({
displayName: 'Contact Email',
description: 'Email address of the contact to remove the tag from',
required: true,
}),
};
export const unsubscribeContact = () => ({
listkey: mailingListDropdown({ required: true }),
contactinfo: contactInformation,
topic_id: topicDropdown({ required: false }),
});
export const addContactToMailingList = () => ({
listkey: mailingListDropdown({ required: true }),
emails: Property.Array({
displayName: 'Emails',
description:
'Contacts email addresses to be added to the mailing list (maximum 10 emails)',
required: true,
}),
});
export const findContact = () => ({
listkey: mailingListDropdown({ required: true }),
contactEmail: Property.ShortText({
displayName: 'Contact Email',
description: 'Email of the contact to be found (partial matches supported)',
required: true,
}),
status: Property.StaticDropdown({
displayName: 'Contact Status',
description: 'Filter contacts by status',
required: true,
options: {
options: [
{ label: 'Active', value: 'active' },
{ label: 'Recent', value: 'recent' },
{ label: 'Most Recent', value: 'most recent' },
{ label: 'Unsubscribed', value: 'unsub' },
{ label: 'Bounced', value: 'bounce' },
],
},
}),
sort: Property.StaticDropdown({
displayName: 'Sort Order',
description: 'Sort order for results',
required: true,
options: {
options: [
{ label: 'Ascending', value: 'asc' },
{ label: 'Descending', value: 'desc' },
],
},
}),
fromindex: Property.Number({
displayName: 'From Index',
description: 'Starting index for pagination (optional, default: 1)',
required: false,
}),
range: Property.Number({
displayName: 'Range',
description: 'Number of contacts to retrieve (optional, default: all)',
required: false,
}),
});
export const findCampaign = () => ({
campaignName: Property.ShortText({
displayName: 'Campaign Name',
description: 'Name of the campaign to be found (partial matches supported)',
required: true,
}),
status: Property.StaticDropdown({
displayName: 'Campaign Status',
description: 'Filter campaigns by status (optional)',
required: false,
options: {
options: [
{ label: 'All', value: 'all' },
{ label: 'All Campaigns', value: 'all campaigns' },
{ label: 'Drafts', value: 'drafts' },
{ label: 'Scheduled', value: 'scheduled' },
{ label: 'In Progress', value: 'inprogress' },
{ label: 'Sent', value: 'sent' },
{ label: 'Stopped', value: 'stopped' },
{ label: 'Canceled', value: 'canceled' },
{ label: 'To Be Reviewed', value: 'tobereviewed' },
{ label: 'Reviewed', value: 'reviewed' },
{ label: 'Paused', value: 'paused' },
{ label: 'In Testing', value: 'intesting' },
],
},
}),
sort: Property.StaticDropdown({
displayName: 'Sort Order',
description: 'Sort order for results (optional)',
required: false,
options: {
options: [
{ label: 'Ascending', value: 'asc' },
{ label: 'Descending', value: 'desc' },
],
},
}),
fromindex: Property.Number({
displayName: 'From Index',
description: 'Starting index for pagination (optional, default: 1)',
required: false,
}),
range: Property.Number({
displayName: 'Range',
description: 'Number of campaigns to retrieve (optional, default: 5)',
required: false,
}),
});
export const newContact = () => ({
listkey: mailingListDropdown({ required: true }),
});
export const unsubscribe = () => ({
listkey: mailingListDropdown({ required: true }),
status: Property.StaticDropdown({
displayName: 'Unsubscribe Type',
description: 'Type of contact removal to monitor (default: unsubscribed)',
required: false,
options: {
options: [
{ label: 'Unsubscribed', value: 'unsub' },
{ label: 'Bounced', value: 'bounce' },
],
},
}),
});

View File

@@ -0,0 +1,73 @@
import z from 'zod';
export const createCampaign = {
campaignname: z.string(),
from_email: z.string().email(),
subject: z.string(),
content_url: z.string().url().optional(),
list_details: z.array(z.string()),
topicId: z.string().nullable().optional(),
}
export const cloneCampaign = {
campaignkey: z.string(),
campaignname: z.string().optional(),
subject: z.string().optional(),
from_name: z.string().optional(),
from_add: z.string().email().optional(),
reply_to: z.string().email().optional(),
encode_type: z.string().optional(),
}
export const sendCampaign = {
campaignkey: z.string(),
}
export const addUpdateContact = {
listkey: z.string(),
contactinfo: z.object({
'Contact Email': z.string().email(),
}),
source: z.string().optional(),
topic_id: z.string().nullable().optional(),
}
export const addTagToContact = {
tagName: z.string(),
lead_email: z.string().email(),
}
export const removeTag = {
tagName: z.string(),
lead_email: z.string().email(),
}
export const unsubscribeContact = {
listkey: z.string(),
contactinfo: z.object({
'Contact Email': z.string().email(),
}),
topic_id: z.string().nullable().optional(),
}
export const addContactToMailingList = {
listkey: z.string(),
emails: z.array(z.string().email()).min(1).max(10),
}
export const findContact = {
listkey: z.string(),
contactEmail: z.string().email(),
status: z.enum(['active', 'recent', 'most recent', 'unsub', 'bounce']).optional(),
sort: z.enum(['asc', 'desc']).optional(),
fromindex: z.number().min(1).optional(),
range: z.number().min(1).optional(),
}
export const findCampaign = {
campaignName: z.string(),
status: z.enum(['all', 'all campaigns', 'drafts', 'scheduled', 'inprogress', 'sent', 'stopped', 'canceled', 'tobereviewed', 'reviewed', 'paused', 'intesting']).optional(),
sort: z.enum(['asc', 'desc']).optional(),
fromindex: z.number().min(1).optional(),
range: z.number().min(1).optional(),
}

View File

@@ -0,0 +1,224 @@
export interface AuthorizationParams {
accessToken: string;
}
export interface BaseCampaignKeyParams {
campaignkey: string;
}
export interface CreateCampaignParams extends AuthorizationParams {
campaignname: string;
from_email: string;
subject: string;
content_url?: string;
list_details: object;
topicId?: string;
}
export interface CreateTagParams extends AuthorizationParams {
tagName: string;
}
export interface CloneCampaignParams extends AuthorizationParams {
campaigninfo: object;
}
export interface SendCampaignParams
extends AuthorizationParams,
BaseCampaignKeyParams {}
export interface AddUpdateContactParams extends AuthorizationParams {
listkey: string;
contactinfo: object;
source?: string;
topic_id?: string;
}
export interface AddTagToContactParams extends AuthorizationParams {
tagName: string;
lead_email: string;
}
export interface RemoveTagParams extends AuthorizationParams {
tagName: string;
lead_email: string;
}
export interface UnsubscribeContactParams extends AuthorizationParams {
listkey: string;
contactinfo: object;
topic_id?: string;
}
export interface AddContactToMailingListParams extends AuthorizationParams {
listkey: string;
emailids: string;
}
export interface ListContactsParams extends AuthorizationParams {
listkey: string;
sort?: 'asc' | 'desc';
fromindex?: number;
range?: number;
status?: 'active' | 'recent' | 'most recent' | 'unsub' | 'bounce';
}
export interface ListCampaignParams extends AuthorizationParams {
sort?: 'asc' | 'desc';
fromindex?: number;
range?: number;
status?:
| 'all'
| 'all campaigns'
| 'drafts'
| 'scheduled'
| 'inprogress'
| 'sent'
| 'stopped'
| 'canceled'
| 'tobereviewed'
| 'reviewed'
| 'paused'
| 'intesting';
}
export interface ListMailingListsParams extends AuthorizationParams {
sort?: 'asc' | 'desc';
fromindex?: number;
range?: number;
}
// API Response types
export type Campaign = {
campaign_key: string;
campaign_name: string;
created_date_string: string;
campaign_status: string;
created_time: string;
campaign_preview: string;
};
export type Contact = {
firstname: string;
added_time: string;
phone: string;
companyname: string;
contact_email: string;
lastname: string;
zuid: string;
};
export type MailingList = {
date: string;
deletable: string;
segments: object;
updated_time_gmt: string;
listdesc: string;
created_time_gmt: string;
list_created_time: string;
noofunsubcnt: string;
lockstatus: string;
listkey: string;
listtype: string;
sentcnt: string;
owner: string;
list_campaigns_count: string;
created_time: string;
noofcontacts: string;
editable: string;
listname: string;
listdgs: string;
noofbouncecnt: string;
issmart: string;
list_created_date: string;
listnotifications: string;
listunino: string;
zuid: string;
servicetype: string;
sno: string;
is_public: string;
otherslist: string;
zx: string;
};
export type Topic = {
topicId: string;
topicName: string;
primaryList: number;
};
export type Tag = {
[key: string]: {
tagowner: string;
tag_created_time: string;
tag_name: string;
tag_color: string;
tag_desc: string;
tagged_contact_count: string;
is_crm_tag: string;
zuid: string;
};
};
export interface ListCampaignResponse {
fromindex: string;
total_record_count: string;
code: string;
recent_campaigns: Campaign[];
range: string;
campaign_count: string;
uri: string;
version: string;
requestdetails: string;
status: string;
}
export interface ListContactsResponse {
code: string;
uri: string;
version: string;
list_of_details: Contact[];
requestdetails: {
fromindex: number;
range: number;
sort: string;
status: string;
};
status: string;
}
export interface ListMailingListsResponse {
code: string;
uri: string;
version: string;
list_of_details: MailingList[];
requestdetails: {
fromindex: number;
range: number;
total_list_count: number;
sort: string;
};
status: string;
}
export interface ListTopicsResponse {
topicDetails: Topic[];
message: string;
code: string;
uri: string;
}
export interface CreateCampaignResponse {
message: string;
campaignKey: string;
code: string;
uri: string;
}
export interface ListTagsResponse {
uri: string;
version: string;
requestdetails: string;
tags?: Tag[];
}