From 4d4008fc28d7dea358892844e42963b62beac1e7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 4 Jun 2025 15:01:31 +0000
Subject: [PATCH 1/3] Initial plan for issue
From 1684eaee0cbde0a55e30cf0297d86653ecc6ce36 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 4 Jun 2025 15:30:19 +0000
Subject: [PATCH 2/3] Create core Mailchimp integration structure and basic
activities
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
---
Elsa.Extensions.sln | 17 ++
.../Activities/Campaigns/CreateCampaign.cs | 104 +++++++++++
.../Activities/Campaigns/GetCampaign.cs | 44 +++++
.../Activities/Events/WatchLists.cs | 54 ++++++
.../Activities/Events/WatchSubscribers.cs | 61 +++++++
.../Activities/Lists/CreateList.cs | 136 ++++++++++++++
.../Activities/Lists/GetList.cs | 44 +++++
.../Activities/MailchimpActivity.cs | 31 ++++
.../Activities/MailchimpTriggerActivity.cs | 28 +++
.../Activities/MakeAPICall.cs | 149 ++++++++++++++++
.../Activities/Members/AddUpdateListMember.cs | 112 ++++++++++++
.../Elsa.Integrations.Mailchimp.csproj | 15 ++
.../Extensions/ModuleExtensions.cs | 19 ++
.../Features/MailchimpFeature.cs | 19 ++
.../FodyWeavers.xml | 3 +
.../Elsa.Integrations.Mailchimp/README.md | 168 ++++++++++++++++++
.../Services/MailchimpClientFactory.cs | 39 ++++
.../Elsa.Integrations.Mailchimp.Tests.csproj | 29 +++
.../Features/MailchimpFeatureTests.cs | 50 ++++++
.../Services/MailchimpClientFactoryTests.cs | 52 ++++++
20 files changed, 1174 insertions(+)
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/CreateCampaign.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/GetCampaign.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchLists.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchSubscribers.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/CreateList.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/GetList.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpActivity.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpTriggerActivity.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/MakeAPICall.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Activities/Members/AddUpdateListMember.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Elsa.Integrations.Mailchimp.csproj
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Extensions/ModuleExtensions.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Features/MailchimpFeature.cs
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/FodyWeavers.xml
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/README.md
create mode 100644 src/integrations/Elsa.Integrations.Mailchimp/Services/MailchimpClientFactory.cs
create mode 100644 test/unit/Elsa.Integrations.Mailchimp.Tests/Elsa.Integrations.Mailchimp.Tests.csproj
create mode 100644 test/unit/Elsa.Integrations.Mailchimp.Tests/Features/MailchimpFeatureTests.cs
create mode 100644 test/unit/Elsa.Integrations.Mailchimp.Tests/Services/MailchimpClientFactoryTests.cs
diff --git a/Elsa.Extensions.sln b/Elsa.Extensions.sln
index 63ef530a..a5db0833 100644
--- a/Elsa.Extensions.sln
+++ b/Elsa.Extensions.sln
@@ -257,6 +257,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "devops", "devops", "{9B6DFC
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.DevOps.GitHub", "src\devops\Elsa.DevOps.GitHub\Elsa.DevOps.GitHub.csproj", "{4E8D5DEA-6FB5-8878-0029-584C8F0D2D68}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "integrations", "integrations", "{1DAA7FA3-95BE-49F8-B989-0457DBD6CF3F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Integrations.Mailchimp", "src\integrations\Elsa.Integrations.Mailchimp\Elsa.Integrations.Mailchimp.csproj", "{FE2BCFD7-D6B6-4429-B964-2209F56AD06C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Integrations.Mailchimp.Tests", "test\unit\Elsa.Integrations.Mailchimp.Tests\Elsa.Integrations.Mailchimp.Tests.csproj", "{C57C6B43-DAE4-4C38-AD27-FC021AA2F4A6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -603,6 +609,14 @@ Global
{4E8D5DEA-6FB5-8878-0029-584C8F0D2D68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E8D5DEA-6FB5-8878-0029-584C8F0D2D68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E8D5DEA-6FB5-8878-0029-584C8F0D2D68}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FE2BCFD7-D6B6-4429-B964-2209F56AD06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE2BCFD7-D6B6-4429-B964-2209F56AD06C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE2BCFD7-D6B6-4429-B964-2209F56AD06C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE2BCFD7-D6B6-4429-B964-2209F56AD06C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C57C6B43-DAE4-4C38-AD27-FC021AA2F4A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C57C6B43-DAE4-4C38-AD27-FC021AA2F4A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C57C6B43-DAE4-4C38-AD27-FC021AA2F4A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C57C6B43-DAE4-4C38-AD27-FC021AA2F4A6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -717,6 +731,9 @@ Global
{59C29BC8-ED95-8F0B-323E-A988EADF3D38} = {AF041BAE-B45A-428B-B7F5-921CCB895558}
{9B6DFC6C-2514-4784-9952-9B0B913434F9} = {527248D6-B851-4C8D-8667-E2FB0A91DABF}
{4E8D5DEA-6FB5-8878-0029-584C8F0D2D68} = {9B6DFC6C-2514-4784-9952-9B0B913434F9}
+ {1DAA7FA3-95BE-49F8-B989-0457DBD6CF3F} = {527248D6-B851-4C8D-8667-E2FB0A91DABF}
+ {FE2BCFD7-D6B6-4429-B964-2209F56AD06C} = {1DAA7FA3-95BE-49F8-B989-0457DBD6CF3F}
+ {C57C6B43-DAE4-4C38-AD27-FC021AA2F4A6} = {AF041BAE-B45A-428B-B7F5-921CCB895558}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {11A771DA-B728-445E-8A88-AE1C84C3B3A6}
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/CreateCampaign.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/CreateCampaign.cs
new file mode 100644
index 00000000..09e7aecc
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/CreateCampaign.cs
@@ -0,0 +1,104 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using MailChimp.Net.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Campaigns;
+
+///
+/// Creates a new campaign in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Campaigns",
+ "Mailchimp Campaigns",
+ "Creates a new campaign in Mailchimp.",
+ DisplayName = "Create Campaign")]
+[UsedImplicitly]
+public class CreateCampaign : MailchimpActivity
+{
+ ///
+ /// The type of campaign (regular, plaintext, absplit, rss, variate).
+ ///
+ [Input(Description = "The type of campaign (regular, plaintext, absplit, rss, variate).")]
+ public Input Type { get; set; } = new("regular");
+
+ ///
+ /// The list ID to send the campaign to.
+ ///
+ [Input(Description = "The list ID to send the campaign to.")]
+ public Input ListId { get; set; } = null!;
+
+ ///
+ /// The subject line for the campaign.
+ ///
+ [Input(Description = "The subject line for the campaign.")]
+ public Input SubjectLine { get; set; } = null!;
+
+ ///
+ /// The title of the campaign.
+ ///
+ [Input(Description = "The title of the campaign.")]
+ public Input Title { get; set; } = default!;
+
+ ///
+ /// The from name for the campaign.
+ ///
+ [Input(Description = "The from name for the campaign.")]
+ public Input FromName { get; set; } = default!;
+
+ ///
+ /// The reply-to email address for the campaign.
+ ///
+ [Input(Description = "The reply-to email address for the campaign.")]
+ public Input ReplyTo { get; set; } = default!;
+
+ ///
+ /// The preview text for the campaign.
+ ///
+ [Input(Description = "The preview text for the campaign.")]
+ public Input PreviewText { get; set; } = default!;
+
+ ///
+ /// The created campaign.
+ ///
+ [Output(Description = "The created campaign.")]
+ public Output CreatedCampaign { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var type = context.Get(Type) ?? "regular";
+ var listId = context.Get(ListId)!;
+ var subjectLine = context.Get(SubjectLine)!;
+ var title = context.Get(Title);
+ var fromName = context.Get(FromName);
+ var replyTo = context.Get(ReplyTo);
+ var previewText = context.Get(PreviewText);
+
+ var client = GetClient(context);
+
+ var campaign = new Campaign
+ {
+ Type = Enum.Parse(type, true),
+ Recipients = new Recipient
+ {
+ ListId = listId
+ },
+ Settings = new Setting
+ {
+ SubjectLine = subjectLine,
+ Title = title,
+ FromName = fromName,
+ ReplyTo = replyTo,
+ PreviewText = previewText
+ }
+ };
+
+ var result = await client.Campaigns.AddAsync(campaign);
+ context.Set(CreatedCampaign, result);
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/GetCampaign.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/GetCampaign.cs
new file mode 100644
index 00000000..48ac4397
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/GetCampaign.cs
@@ -0,0 +1,44 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using MailChimp.Net.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Campaigns;
+
+///
+/// Retrieves metadata of a specified campaign from Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Campaigns",
+ "Mailchimp Campaigns",
+ "Retrieves metadata of a specified campaign from Mailchimp.",
+ DisplayName = "Get Campaign")]
+[UsedImplicitly]
+public class GetCampaign : MailchimpActivity
+{
+ ///
+ /// The ID of the campaign to retrieve.
+ ///
+ [Input(Description = "The ID of the campaign to retrieve.")]
+ public Input CampaignId { get; set; } = null!;
+
+ ///
+ /// The retrieved campaign.
+ ///
+ [Output(Description = "The retrieved campaign.")]
+ public Output RetrievedCampaign { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var campaignId = context.Get(CampaignId)!;
+ var client = GetClient(context);
+
+ var campaign = await client.Campaigns.GetAsync(campaignId);
+ context.Set(RetrievedCampaign, campaign);
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchLists.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchLists.cs
new file mode 100644
index 00000000..639138cb
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchLists.cs
@@ -0,0 +1,54 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using MailChimp.Net.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Events;
+
+///
+/// Triggers when a new list is created in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Events",
+ "Mailchimp Events",
+ "Triggers when a new list is created in Mailchimp.",
+ DisplayName = "Watch Lists")]
+[UsedImplicitly]
+public class WatchLists : MailchimpTriggerActivity
+{
+ ///
+ /// The received list event.
+ ///
+ [Output(Description = "The received list event.")]
+ public Output ReceivedList { get; set; } = null!;
+
+ ///
+ /// Returns the trigger type identifier.
+ ///
+ public override string GetTriggerType() => "mailchimp.list.created";
+
+ ///
+ /// Returns the payloads to index.
+ ///
+ /// The trigger indexing context.
+ public override ValueTask> GetTriggerPayloadsAsync(TriggerIndexingContext context)
+ {
+ var apiKey = context.Get(ApiKey);
+ var eventType = context.Get(EventType) ?? "list.created";
+
+ return new ValueTask>(new object[] { new { ApiKey = apiKey, EventType = eventType } });
+ }
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ // This would be triggered by a webhook event
+ // The actual implementation would depend on webhook infrastructure
+ // For now, this is a placeholder that shows the expected structure
+ throw new NotImplementedException("Webhook trigger implementation requires webhook infrastructure setup.");
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchSubscribers.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchSubscribers.cs
new file mode 100644
index 00000000..6ec1b369
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchSubscribers.cs
@@ -0,0 +1,61 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using MailChimp.Net.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Events;
+
+///
+/// Triggers when a new subscriber joins a list or is updated in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Events",
+ "Mailchimp Events",
+ "Triggers when a new subscriber joins a list or is updated in Mailchimp.",
+ DisplayName = "Watch Subscribers")]
+[UsedImplicitly]
+public class WatchSubscribers : MailchimpTriggerActivity
+{
+ ///
+ /// The list ID to watch for subscriber events.
+ ///
+ [Input(Description = "The list ID to watch for subscriber events.")]
+ public Input ListId { get; set; } = default!;
+
+ ///
+ /// The received subscriber event.
+ ///
+ [Output(Description = "The received subscriber event.")]
+ public Output ReceivedSubscriber { get; set; } = null!;
+
+ ///
+ /// Returns the trigger type identifier.
+ ///
+ public override string GetTriggerType() => "mailchimp.subscriber.updated";
+
+ ///
+ /// Returns the payloads to index.
+ ///
+ /// The trigger indexing context.
+ public override ValueTask> GetTriggerPayloadsAsync(TriggerIndexingContext context)
+ {
+ var apiKey = context.Get(ApiKey);
+ var listId = context.Get(ListId);
+ var eventType = context.Get(EventType) ?? "subscriber.updated";
+
+ return new ValueTask>(new object[] { new { ApiKey = apiKey, ListId = listId, EventType = eventType } });
+ }
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ // This would be triggered by a webhook event
+ // The actual implementation would depend on webhook infrastructure
+ // For now, this is a placeholder that shows the expected structure
+ throw new NotImplementedException("Webhook trigger implementation requires webhook infrastructure setup.");
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/CreateList.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/CreateList.cs
new file mode 100644
index 00000000..40108c52
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/CreateList.cs
@@ -0,0 +1,136 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using MailChimp.Net.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Lists;
+
+///
+/// Creates a new list in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Lists",
+ "Mailchimp Lists",
+ "Creates a new list in Mailchimp.",
+ DisplayName = "Create List")]
+[UsedImplicitly]
+public class CreateList : MailchimpActivity
+{
+ ///
+ /// The name of the list.
+ ///
+ [Input(Description = "The name of the list.")]
+ public Input Name { get; set; } = null!;
+
+ ///
+ /// The contact information for this list.
+ ///
+ [Input(Description = "The company name associated with the list.")]
+ public Input CompanyName { get; set; } = null!;
+
+ ///
+ /// The contact address for this list.
+ ///
+ [Input(Description = "The contact address for this list.")]
+ public Input Address1 { get; set; } = null!;
+
+ ///
+ /// The city for the contact address.
+ ///
+ [Input(Description = "The city for the contact address.")]
+ public Input City { get; set; } = null!;
+
+ ///
+ /// The state for the contact address.
+ ///
+ [Input(Description = "The state for the contact address.")]
+ public Input State { get; set; } = null!;
+
+ ///
+ /// The zip code for the contact address.
+ ///
+ [Input(Description = "The zip code for the contact address.")]
+ public Input Zip { get; set; } = null!;
+
+ ///
+ /// The country for the contact address.
+ ///
+ [Input(Description = "The country for the contact address.")]
+ public Input Country { get; set; } = null!;
+
+ ///
+ /// The permission reminder for the list.
+ ///
+ [Input(Description = "The permission reminder for the list.")]
+ public Input PermissionReminder { get; set; } = null!;
+
+ ///
+ /// The 'from' name for campaigns sent to this list.
+ ///
+ [Input(Description = "The 'from' name for campaigns sent to this list.")]
+ public Input FromName { get; set; } = null!;
+
+ ///
+ /// The 'from' email address for campaigns sent to this list.
+ ///
+ [Input(Description = "The 'from' email address for campaigns sent to this list.")]
+ public Input FromEmail { get; set; } = null!;
+
+ ///
+ /// The language for this list.
+ ///
+ [Input(Description = "The language for this list.")]
+ public Input Language { get; set; } = new("en");
+
+ ///
+ /// The created list.
+ ///
+ [Output(Description = "The created list.")]
+ public Output CreatedList { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var name = context.Get(Name)!;
+ var companyName = context.Get(CompanyName)!;
+ var address1 = context.Get(Address1)!;
+ var city = context.Get(City)!;
+ var state = context.Get(State)!;
+ var zip = context.Get(Zip)!;
+ var country = context.Get(Country)!;
+ var permissionReminder = context.Get(PermissionReminder)!;
+ var fromName = context.Get(FromName)!;
+ var fromEmail = context.Get(FromEmail)!;
+ var language = context.Get(Language) ?? "en";
+
+ var client = GetClient(context);
+
+ var list = new List
+ {
+ Name = name,
+ Contact = new Contact
+ {
+ Company = companyName,
+ Address1 = address1,
+ City = city,
+ State = state,
+ Zip = zip,
+ Country = country
+ },
+ PermissionReminder = permissionReminder,
+ CampaignDefaults = new CampaignDefaults
+ {
+ FromName = fromName,
+ FromEmail = fromEmail,
+ Language = language
+ }
+ };
+
+ var result = await client.Lists.AddAsync(list);
+ context.Set(CreatedList, result);
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/GetList.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/GetList.cs
new file mode 100644
index 00000000..0903f848
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/GetList.cs
@@ -0,0 +1,44 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using MailChimp.Net.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Lists;
+
+///
+/// Retrieves metadata of a specified list from Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Lists",
+ "Mailchimp Lists",
+ "Retrieves metadata of a specified list from Mailchimp.",
+ DisplayName = "Get List")]
+[UsedImplicitly]
+public class GetList : MailchimpActivity
+{
+ ///
+ /// The ID of the list to retrieve.
+ ///
+ [Input(Description = "The ID of the list to retrieve.")]
+ public Input ListId { get; set; } = null!;
+
+ ///
+ /// The retrieved list.
+ ///
+ [Output(Description = "The retrieved list.")]
+ public Output RetrievedList { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var listId = context.Get(ListId)!;
+ var client = GetClient(context);
+
+ var list = await client.Lists.GetAsync(listId);
+ context.Set(RetrievedList, list);
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpActivity.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpActivity.cs
new file mode 100644
index 00000000..aa8af7a6
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpActivity.cs
@@ -0,0 +1,31 @@
+using Elsa.Integrations.Mailchimp.Services;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using MailChimp.Net.Interfaces;
+
+namespace Elsa.Integrations.Mailchimp.Activities;
+
+///
+/// Generic base class inherited by all Mailchimp activities.
+///
+public abstract class MailchimpActivity : Activity
+{
+ ///
+ /// The Mailchimp API key.
+ ///
+ [Input(Description = "The Mailchimp API key.")]
+ public Input ApiKey { get; set; } = null!;
+
+ ///
+ /// Gets the Mailchimp API client.
+ ///
+ /// The current context to get the client.
+ /// The Mailchimp API client.
+ protected IMailChimpManager GetClient(ActivityExecutionContext context)
+ {
+ MailchimpClientFactory mailchimpClientFactory = context.GetRequiredService();
+ string apiKey = context.Get(ApiKey)!;
+ return mailchimpClientFactory.GetClient(apiKey);
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpTriggerActivity.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpTriggerActivity.cs
new file mode 100644
index 00000000..7694d1ea
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/MailchimpTriggerActivity.cs
@@ -0,0 +1,28 @@
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+
+namespace Elsa.Integrations.Mailchimp.Activities;
+
+///
+/// Base class for Mailchimp event trigger activities.
+///
+public abstract class MailchimpTriggerActivity : MailchimpActivity, ITrigger
+{
+ ///
+ /// The webhook event type to listen for.
+ ///
+ [Input(Description = "The webhook event type to listen for.")]
+ public Input EventType { get; set; } = null!;
+
+ ///
+ /// Returns the trigger type identifier.
+ ///
+ public abstract string GetTriggerType();
+
+ ///
+ /// Returns the payloads to index.
+ ///
+ /// The trigger indexing context.
+ public abstract ValueTask> GetTriggerPayloadsAsync(TriggerIndexingContext context);
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/MakeAPICall.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/MakeAPICall.cs
new file mode 100644
index 00000000..8588a297
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/MakeAPICall.cs
@@ -0,0 +1,149 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+using System.Text.Json;
+
+namespace Elsa.Integrations.Mailchimp.Activities;
+
+///
+/// Performs an arbitrary authorized API call to Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Core",
+ "Mailchimp Core",
+ "Performs an arbitrary authorized API call to Mailchimp.",
+ DisplayName = "Make API Call")]
+[UsedImplicitly]
+public class MakeAPICall : MailchimpActivity
+{
+ ///
+ /// The HTTP method to use (GET, POST, PUT, DELETE, PATCH).
+ ///
+ [Input(Description = "The HTTP method to use (GET, POST, PUT, DELETE, PATCH).")]
+ public Input Method { get; set; } = new("GET");
+
+ ///
+ /// The API endpoint path (e.g., 'lists', 'campaigns').
+ ///
+ [Input(Description = "The API endpoint path (e.g., 'lists', 'campaigns').")]
+ public Input Endpoint { get; set; } = null!;
+
+ ///
+ /// The request body as JSON (for POST, PUT, PATCH methods).
+ ///
+ [Input(Description = "The request body as JSON (for POST, PUT, PATCH methods).")]
+ public Input RequestBody { get; set; } = default!;
+
+ ///
+ /// Query parameters as JSON object.
+ ///
+ [Input(Description = "Query parameters as JSON object.")]
+ public Input QueryParameters { get; set; } = default!;
+
+ ///
+ /// The API response.
+ ///
+ [Output(Description = "The API response.")]
+ public Output