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/DeleteCampaign.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/DeleteCampaign.cs
new file mode 100644
index 00000000..56d24bba
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/DeleteCampaign.cs
@@ -0,0 +1,50 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Campaigns;
+
+///
+/// Deletes a campaign in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Campaigns",
+ "Mailchimp Campaigns",
+ "Deletes a campaign in Mailchimp.",
+ DisplayName = "Delete Campaign")]
+[UsedImplicitly]
+public class DeleteCampaign : MailchimpActivity
+{
+ ///
+ /// The ID of the campaign to delete.
+ ///
+ [Input(Description = "The ID of the campaign to delete.")]
+ public Input CampaignId { get; set; } = null!;
+
+ ///
+ /// Indicates whether the operation was successful.
+ ///
+ [Output(Description = "Indicates whether the operation was successful.")]
+ public Output Success { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var campaignId = context.Get(CampaignId)!;
+ var client = GetClient(context);
+
+ try
+ {
+ await client.Campaigns.DeleteAsync(campaignId);
+ context.Set(Success, true);
+ }
+ catch
+ {
+ context.Set(Success, false);
+ }
+ }
+}
\ 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/Campaigns/UpdateCampaign.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/UpdateCampaign.cs
new file mode 100644
index 00000000..c206e40c
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Campaigns/UpdateCampaign.cs
@@ -0,0 +1,97 @@
+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;
+
+///
+/// Updates an existing campaign in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Campaigns",
+ "Mailchimp Campaigns",
+ "Updates an existing campaign in Mailchimp.",
+ DisplayName = "Update Campaign")]
+[UsedImplicitly]
+public class UpdateCampaign : MailchimpActivity
+{
+ ///
+ /// The ID of the campaign to update.
+ ///
+ [Input(Description = "The ID of the campaign to update.")]
+ public Input CampaignId { get; set; } = null!;
+
+ ///
+ /// The subject line for the campaign.
+ ///
+ [Input(Description = "The subject line for the campaign.")]
+ public Input SubjectLine { get; set; } = default!;
+
+ ///
+ /// 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 updated campaign.
+ ///
+ [Output(Description = "The updated campaign.")]
+ public Output UpdatedCampaign { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var campaignId = context.Get(CampaignId)!;
+ 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
+ {
+ Id = campaignId,
+ Settings = new Setting()
+ };
+
+ if (!string.IsNullOrEmpty(subjectLine))
+ campaign.Settings.SubjectLine = subjectLine;
+ if (!string.IsNullOrEmpty(title))
+ campaign.Settings.Title = title;
+ if (!string.IsNullOrEmpty(fromName))
+ campaign.Settings.FromName = fromName;
+ if (!string.IsNullOrEmpty(replyTo))
+ campaign.Settings.ReplyTo = replyTo;
+ if (!string.IsNullOrEmpty(previewText))
+ campaign.Settings.PreviewText = previewText;
+
+ var result = await client.Campaigns.UpdateAsync(campaignId, campaign);
+ context.Set(UpdatedCampaign, result);
+ }
+}
\ No newline at end of file
diff --git a/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchCampaigns.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchCampaigns.cs
new file mode 100644
index 00000000..71eae533
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Events/WatchCampaigns.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 campaign is created or sent in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Events",
+ "Mailchimp Events",
+ "Triggers when a new campaign is created or sent in Mailchimp.",
+ DisplayName = "Watch Campaigns")]
+[UsedImplicitly]
+public class WatchCampaigns : MailchimpTriggerActivity
+{
+ ///
+ /// The list ID to watch for campaign events (optional).
+ ///
+ [Input(Description = "The list ID to watch for campaign events (optional).")]
+ public Input ListId { get; set; } = default!;
+
+ ///
+ /// The received campaign event.
+ ///
+ [Output(Description = "The received campaign event.")]
+ public Output ReceivedCampaign { get; set; } = null!;
+
+ ///
+ /// Returns the trigger type identifier.
+ ///
+ public override string GetTriggerType() => "mailchimp.campaign.event";
+
+ ///
+ /// 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) ?? "campaign.created";
+
+ 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/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/DeleteList.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/DeleteList.cs
new file mode 100644
index 00000000..5789dcb9
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/DeleteList.cs
@@ -0,0 +1,50 @@
+using Elsa.Integrations.Mailchimp.Activities;
+using Elsa.Workflows;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Models;
+using JetBrains.Annotations;
+
+namespace Elsa.Integrations.Mailchimp.Activities.Lists;
+
+///
+/// Deletes a list in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Lists",
+ "Mailchimp Lists",
+ "Deletes a list in Mailchimp.",
+ DisplayName = "Delete List")]
+[UsedImplicitly]
+public class DeleteList : MailchimpActivity
+{
+ ///
+ /// The ID of the list to delete.
+ ///
+ [Input(Description = "The ID of the list to delete.")]
+ public Input ListId { get; set; } = null!;
+
+ ///
+ /// Indicates whether the operation was successful.
+ ///
+ [Output(Description = "Indicates whether the operation was successful.")]
+ public Output Success { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var listId = context.Get(ListId)!;
+ var client = GetClient(context);
+
+ try
+ {
+ await client.Lists.DeleteAsync(listId);
+ context.Set(Success, true);
+ }
+ catch
+ {
+ context.Set(Success, false);
+ }
+ }
+}
\ 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/Lists/UpdateList.cs b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/UpdateList.cs
new file mode 100644
index 00000000..b40e379e
--- /dev/null
+++ b/src/integrations/Elsa.Integrations.Mailchimp/Activities/Lists/UpdateList.cs
@@ -0,0 +1,93 @@
+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;
+
+///
+/// Updates an existing list in Mailchimp.
+///
+[Activity(
+ "Elsa.Mailchimp.Lists",
+ "Mailchimp Lists",
+ "Updates an existing list in Mailchimp.",
+ DisplayName = "Update List")]
+[UsedImplicitly]
+public class UpdateList : MailchimpActivity
+{
+ ///
+ /// The ID of the list to update.
+ ///
+ [Input(Description = "The ID of the list to update.")]
+ public Input ListId { get; set; } = null!;
+
+ ///
+ /// The name of the list.
+ ///
+ [Input(Description = "The name of the list.")]
+ public Input Name { get; set; } = default!;
+
+ ///
+ /// The permission reminder for the list.
+ ///
+ [Input(Description = "The permission reminder for the list.")]
+ public Input PermissionReminder { get; set; } = default!;
+
+ ///
+ /// 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; } = default!;
+
+ ///
+ /// 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; } = default!;
+
+ ///
+ /// The updated list.
+ ///
+ [Output(Description = "The updated list.")]
+ public Output UpdatedList { get; set; } = default!;
+
+ ///
+ /// Executes the activity.
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var listId = context.Get(ListId)!;
+ var name = context.Get(Name);
+ var permissionReminder = context.Get(PermissionReminder);
+ var fromName = context.Get(FromName);
+ var fromEmail = context.Get(FromEmail);
+
+ var client = GetClient(context);
+
+ var list = new List
+ {
+ Id = listId
+ };
+
+ if (!string.IsNullOrEmpty(name))
+ list.Name = name;
+
+ if (!string.IsNullOrEmpty(permissionReminder))
+ list.PermissionReminder = permissionReminder;
+
+ if (!string.IsNullOrEmpty(fromName) || !string.IsNullOrEmpty(fromEmail))
+ {
+ list.CampaignDefaults = new CampaignDefaults();
+ if (!string.IsNullOrEmpty(fromName))
+ list.CampaignDefaults.FromName = fromName;
+ if (!string.IsNullOrEmpty(fromEmail))
+ list.CampaignDefaults.FromEmail = fromEmail;
+ }
+
+ var result = await client.Lists.UpdateAsync(listId, list);
+ context.Set(UpdatedList, result);
+ }
+}
\ 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