diff --git a/Dobbs Campaign Manager API Key.txt b/Dobbs Campaign Manager API Key.txt
new file mode 100644
index 0000000..5d72964
--- /dev/null
+++ b/Dobbs Campaign Manager API Key.txt
@@ -0,0 +1,5 @@
+Client ID:
+6f7f08a5dcc30e18d41888c47dc6c276
+
+API Key:
+7cb8625ed34fbc298521f66b9e491ec3df53859a892c92d3
\ No newline at end of file
diff --git a/OptOutFetcher.csproj b/OptOutFetcher.csproj
new file mode 100644
index 0000000..c5baf53
--- /dev/null
+++ b/OptOutFetcher.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/OptOutFetcher.sln b/OptOutFetcher.sln
new file mode 100644
index 0000000..0e644d3
--- /dev/null
+++ b/OptOutFetcher.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34723.18
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OptOutFetcher", "OptOutFetcher.csproj", "{2FBB934D-7099-4C05-BF0F-5C044B9F3B7E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2FBB934D-7099-4C05-BF0F-5C044B9F3B7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2FBB934D-7099-4C05-BF0F-5C044B9F3B7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2FBB934D-7099-4C05-BF0F-5C044B9F3B7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2FBB934D-7099-4C05-BF0F-5C044B9F3B7E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4E45E6B3-8352-473C-BAFC-997B649FA663}
+ EndGlobalSection
+EndGlobal
diff --git a/Program.cs b/Program.cs
new file mode 100644
index 0000000..9c24b61
--- /dev/null
+++ b/Program.cs
@@ -0,0 +1,95 @@
+using RestSharp;
+using System.Text.Json.Nodes;
+using System.Text.Json;
+using System.Net;
+using RestSharp.Authenticators;
+
+/*
+ Campaign Monitor API reference: https://www.campaignmonitor.com/api/v3-3/getting-started/
+ Dobbs API key/client ID available from Josh in \\KM202401\c$\Users\joshdeck.KEYMTV\Documents\Misc\OptOutFetcher
+ */
+
+internal class Program
+{
+ static void Main(string[] args)
+ {
+ Console.Write("Date to start at (leave blank for all entries): ");
+
+ // Add to list testing
+ //var data = AddNewSubscribers("");
+ //Console.WriteLine(data);
+
+ // Unsubscribe testing
+ //UnsubscribeUser("");
+
+ // Opt Out Testing
+ string date = Console.ReadLine();
+ var data = GetOptOuts(date);
+
+ // Output the data; TODO replace with writing to a service or something
+ Console.WriteLine(data);
+ }
+
+
+
+ private static RestClient InitializeAndGetClient()
+ {
+ var cookieJar = new CookieContainer();
+ var options = new RestClientOptions("https://api.createsend.com")
+ {
+ Authenticator = new HttpBasicAuthenticator("7cb8625ed34fbc298521f66b9e491ec3df53859a892c92d3", "x")
+ };
+ return new RestClient(options);
+ }
+
+
+
+ private static JsonNode? GetOptOuts(string fromDate)
+ {
+ var client = InitializeAndGetClient();
+ var request = new RestRequest();
+ if (fromDate != "")
+ request = new RestRequest("api/v3.3/lists/3bb5109cdf3265eac26b3fa34ffae379/unsubscribed.json?date=" + fromDate);
+ else
+ request = new RestRequest("api/v3.3/lists/3bb5109cdf3265eac26b3fa34ffae379/unsubscribed.json");
+
+ var response = client.ExecuteGet(request);
+
+ return JsonSerializer.Deserialize(response.Content!)!;
+ }
+
+
+
+ private static JsonNode? AddNewSubscribers(string fileName)
+ {
+ // TODO: for testing we just use a dummy list, but once we actually merge the two lists we are going to want to read from file/service
+ string add_request_params = "{ \"EmailAddress\": \"joshdeck@keymotive.net\", \"Name\": \"Joshua Deck\",\"MobileNumber\":\"+8884227390\",\"CustomFields\": [ ], \"Resubscribe\": true,\"RestartSubscriptionBasedAutoresponders\": true, \"ConsentToTrack\": \"No\", \"ConsentToSendSms\":\"No\"}";
+
+
+ var client = InitializeAndGetClient();
+
+ // This is only adding one. To add multiple, format body as: https://www.campaignmonitor.com/api/v3-3/subscribers/#importing-many-subscribers
+ // and POST this url: https://api.createsend.com/api/v3.3/subscribers/3bb5109cdf3265eac26b3fa34ffae379/import.json
+ var request = new RestRequest("api/v3.3/subscribers/3bb5109cdf3265eac26b3fa34ffae379.json");
+
+ request.AddBody(add_request_params);
+ var response = client.ExecutePost(request);
+
+ return JsonSerializer.Deserialize(response.Content!)!;
+ }
+
+
+
+ private static void UnsubscribeUser(string fileName)
+ {
+ // TODO: change this to a file
+ string unsub_request_params = "{ \"EmailAddress\": \"joshdeck@keymotive.net\" }";
+
+ var client = InitializeAndGetClient();
+ var request = new RestRequest("api/v3.3/subscribers/3bb5109cdf3265eac26b3fa34ffae379/unsubscribe.json");
+ request.AddBody(unsub_request_params);
+ var response = client.ExecutePost(request);
+
+ Console.WriteLine(response.Content + "Done unsubscribing");
+ }
+}
\ No newline at end of file