diff --git a/packages/backend/src/apps/mailchimp/actions/create-campaign/index.js b/packages/backend/src/apps/mailchimp/actions/create-campaign/index.js
new file mode 100644
index 00000000..f622e150
--- /dev/null
+++ b/packages/backend/src/apps/mailchimp/actions/create-campaign/index.js
@@ -0,0 +1,180 @@
+import defineAction from '../../../../helpers/define-action.js';
+
+export default defineAction({
+ name: 'Create campaign',
+ key: 'createCampaign',
+ description: 'Creates a new campaign draft.',
+ arguments: [
+ {
+ label: 'Campaign Name',
+ key: 'campaignName',
+ type: 'string',
+ required: false,
+ description: '',
+ variables: true,
+ },
+ {
+ label: 'Audience',
+ key: 'audienceId',
+ type: 'dropdown',
+ required: true,
+ description: '',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listAudiences',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Segment or Tag',
+ key: 'segmentOrTagId',
+ type: 'dropdown',
+ required: false,
+ dependsOn: ['parameters.audienceId'],
+ description:
+ 'Choose the specific segment or tag to which you"d like to direct the campaign. If no segment or tag is chosen, the campaign will be distributed to the entire audience previously selected.',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listSegmentsOrTags',
+ },
+ {
+ name: 'parameters.audienceId',
+ value: '{parameters.audienceId}',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Email Subject',
+ key: 'emailSubject',
+ type: 'string',
+ required: true,
+ description: '',
+ variables: true,
+ },
+ {
+ label: 'Preview Text',
+ key: 'previewText',
+ type: 'string',
+ required: false,
+ description:
+ 'The snippet will be visible in the inbox following the subject line.',
+ variables: true,
+ },
+ {
+ label: 'From Name',
+ key: 'fromName',
+ type: 'string',
+ required: true,
+ description: 'The "from" name on the campaign (not an email address).',
+ variables: true,
+ },
+ {
+ label: 'From Email Address',
+ key: 'fromEmailAddress',
+ type: 'string',
+ required: true,
+ description: 'The reply-to email address for the campaign.',
+ variables: true,
+ },
+ {
+ label: 'To Name',
+ key: 'toName',
+ type: 'string',
+ required: false,
+ description:
+ 'Supports *|MERGETAGS|* for recipient name, such as *|FNAME|*, *|LNAME|*, *|FNAME|* *|LNAME|*, etc.',
+ variables: true,
+ },
+ {
+ label: 'Template',
+ key: 'templateId',
+ type: 'dropdown',
+ required: false,
+ description:
+ 'Select either a template or provide HTML email content, you cannot provide both. If both fields are left blank, the campaign draft will have no content.',
+ variables: true,
+ source: {
+ type: 'query',
+ name: 'getDynamicData',
+ arguments: [
+ {
+ name: 'key',
+ value: 'listTemplates',
+ },
+ ],
+ },
+ },
+ {
+ label: 'Email Content (HTML)',
+ key: 'emailContent',
+ type: 'string',
+ required: false,
+ description:
+ 'Select either a template or provide HTML email content, you cannot provide both. If both fields are left blank, the campaign draft will have no content.',
+ variables: true,
+ },
+ ],
+
+ async run($) {
+ const {
+ campaignName,
+ audienceId,
+ segmentOrTagId,
+ emailSubject,
+ previewText,
+ fromName,
+ fromEmailAddress,
+ toName,
+ templateId,
+ emailContent,
+ } = $.step.parameters;
+
+ const body = {
+ type: 'regular',
+ recipients: {
+ list_id: audienceId,
+ segment_opts: {
+ saved_segment_id: Number(segmentOrTagId),
+ },
+ },
+ settings: {
+ subject_line: emailSubject,
+ reply_to: fromEmailAddress,
+ title: campaignName,
+ preview_text: previewText,
+ from_name: fromName,
+ to_name: toName,
+ },
+ };
+
+ const { data: campaign } = await $.http.post('/3.0/campaigns', body);
+
+ const campaignBody = {
+ template: {
+ id: Number(templateId),
+ },
+ html: emailContent,
+ };
+
+ const { data } = await $.http.put(
+ `/3.0/campaigns/${campaign.id}/content`,
+ campaignBody
+ );
+
+ $.setActionItem({
+ raw: data,
+ });
+ },
+});
diff --git a/packages/backend/src/apps/mailchimp/actions/index.js b/packages/backend/src/apps/mailchimp/actions/index.js
new file mode 100644
index 00000000..25ce22d3
--- /dev/null
+++ b/packages/backend/src/apps/mailchimp/actions/index.js
@@ -0,0 +1,3 @@
+import createCampaign from './create-campaign/index.js';
+
+export default [createCampaign];
diff --git a/packages/backend/src/apps/mailchimp/dynamic-data/index.js b/packages/backend/src/apps/mailchimp/dynamic-data/index.js
index c9fd2e79..1e7045fa 100644
--- a/packages/backend/src/apps/mailchimp/dynamic-data/index.js
+++ b/packages/backend/src/apps/mailchimp/dynamic-data/index.js
@@ -1,4 +1,6 @@
import listAudiences from './list-audiences/index.js';
import listCampaigns from './list-campaigns/index.js';
+import listTags from './list-segments-or-tags/index.js';
+import listTemplates from './list-templates/index.js';
-export default [listAudiences, listCampaigns];
+export default [listAudiences, listCampaigns, listTags, listTemplates];
diff --git a/packages/backend/src/apps/mailchimp/dynamic-data/list-segments-or-tags/index.js b/packages/backend/src/apps/mailchimp/dynamic-data/list-segments-or-tags/index.js
new file mode 100644
index 00000000..282345cf
--- /dev/null
+++ b/packages/backend/src/apps/mailchimp/dynamic-data/list-segments-or-tags/index.js
@@ -0,0 +1,44 @@
+export default {
+ name: 'List segments or tags',
+ key: 'listSegmentsOrTags',
+
+ async run($) {
+ const segmentsOrTags = {
+ data: [],
+ };
+ const audienceId = $.step.parameters.audienceId;
+
+ if (!audienceId) {
+ return segmentsOrTags;
+ }
+
+ const {
+ data: { tags: allTags },
+ } = await $.http.get(`/3.0/lists/${audienceId}/tag-search`);
+
+ const {
+ data: { segments },
+ } = await $.http.get(`/3.0/lists/${audienceId}/segments`);
+
+ const mergedArray = [...allTags, ...segments].reduce(
+ (accumulator, current) => {
+ if (!accumulator.some((item) => item.id === current.id)) {
+ accumulator.push(current);
+ }
+ return accumulator;
+ },
+ []
+ );
+
+ if (mergedArray?.length) {
+ for (const tagOrSegment of mergedArray) {
+ segmentsOrTags.data.push({
+ value: tagOrSegment.id,
+ name: tagOrSegment.name,
+ });
+ }
+ }
+
+ return segmentsOrTags;
+ },
+};
diff --git a/packages/backend/src/apps/mailchimp/dynamic-data/list-templates/index.js b/packages/backend/src/apps/mailchimp/dynamic-data/list-templates/index.js
new file mode 100644
index 00000000..9f67f812
--- /dev/null
+++ b/packages/backend/src/apps/mailchimp/dynamic-data/list-templates/index.js
@@ -0,0 +1,30 @@
+export default {
+ name: 'List templates',
+ key: 'listTemplates',
+
+ async run($) {
+ const templates = {
+ data: [],
+ };
+
+ const params = {
+ sort_field: 'date_created',
+ sort_dir: 'DESC',
+ count: 1000,
+ offset: 0,
+ };
+
+ const { data } = await $.http.get('/3.0/templates', { params });
+
+ if (data?.templates) {
+ for (const template of data.templates) {
+ templates.data.push({
+ value: template.id,
+ name: template.name,
+ });
+ }
+ }
+
+ return templates;
+ },
+};
diff --git a/packages/backend/src/apps/mailchimp/index.js b/packages/backend/src/apps/mailchimp/index.js
index 9dd8a71e..c3b01e63 100644
--- a/packages/backend/src/apps/mailchimp/index.js
+++ b/packages/backend/src/apps/mailchimp/index.js
@@ -4,6 +4,7 @@ import setBaseUrl from './common/set-base-url.js';
import auth from './auth/index.js';
import triggers from './triggers/index.js';
import dynamicData from './dynamic-data/index.js';
+import actions from './actions/index.js';
export default defineApp({
name: 'Mailchimp',
@@ -18,4 +19,5 @@ export default defineApp({
auth,
triggers,
dynamicData,
+ actions,
});
diff --git a/packages/docs/pages/apps/mailchimp/actions.md b/packages/docs/pages/apps/mailchimp/actions.md
new file mode 100644
index 00000000..1b20a1bb
--- /dev/null
+++ b/packages/docs/pages/apps/mailchimp/actions.md
@@ -0,0 +1,12 @@
+---
+favicon: /favicons/mailchimp.svg
+items:
+ - name: Create campaign
+ desc: Creates a new campaign draft.
+---
+
+
+
+