From 32e9e6bfa391096fec0f33c9f27a246ddcf75ad1 Mon Sep 17 00:00:00 2001 From: JM Date: Tue, 4 Jun 2019 16:41:00 -0400 Subject: [PATCH 1/3] Replace Message Events API with the new Events API The Events API will be discontinued on October 1. 2019. --- docker/readme.md | 34 +-- .../SparkPost.Portable.csproj | 224 +++++++++--------- .../MessageEventsQueryTests.cs | 2 +- src/SparkPost/DataMapper.cs | 11 +- src/SparkPost/ListMessageEventsResponse.cs | 3 +- src/SparkPost/MessageEvent.cs | 6 - src/SparkPost/MessageEventType.cs | 2 +- src/SparkPost/MessageEvents.cs | 19 +- src/SparkPost/MessageEventsQuery.cs | 14 +- src/SparkPost/PageLink.cs | 3 +- 10 files changed, 150 insertions(+), 168 deletions(-) diff --git a/docker/readme.md b/docker/readme.md index 9a0a62a7..99d9491c 100644 --- a/docker/readme.md +++ b/docker/readme.md @@ -1,17 +1,17 @@ -## Build & Deploy via Docker & Nuget - -This docker container will pull the latest version of this library, create a nuget package, and deploy it to Nuget. - -The only thing is needs is a valid Nuget API key, from someone that has rights to publish the package to Nuget. - -``` -cd docker -docker build . # this will produce a hash key, say 12345678 -docker run -e "APIKEY=your_nuget_key_here" 12345678 -``` - -This container has been registered on Docker Hub, and can be run like so: - -``` -docker run -e "APIKEY=your_nuget_key_here" darrencauthon/csharp-sparkpost -``` +## Build & Deploy via Docker & Nuget + +This docker container will pull the latest version of this library, create a nuget package, and deploy it to Nuget. + +The only thing is needs is a valid Nuget API key, from someone that has rights to publish the package to Nuget. + +``` +cd docker +docker build . # this will produce a hash key, say 12345678 +docker run -e "APIKEY=your_nuget_key_here" 12345678 +``` + +This container has been registered on Docker Hub, and can be run like so: + +``` +docker run -e "APIKEY=your_nuget_key_here" darrencauthon/csharp-sparkpost +``` diff --git a/src/SparkPost.Portable/SparkPost.Portable.csproj b/src/SparkPost.Portable/SparkPost.Portable.csproj index 4ba02806..377ceaae 100644 --- a/src/SparkPost.Portable/SparkPost.Portable.csproj +++ b/src/SparkPost.Portable/SparkPost.Portable.csproj @@ -1,113 +1,113 @@ - - - - Debug - AnyCPU - {2F7E9E0B-27BB-42AC-AB4A-B8249B64C654} - {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Library - SparkPost - SparkPost.Portable - v4.5 - Profile7 - - - true - full - false - bin\Debug - DEBUG;PORTABLE - prompt - 4 - false - false - - - true - bin\Release - PORTABLE - prompt - 4 - false - false - - - - Address.cs - - - Attachment.cs - - - CcHandling.cs - - - Client.cs - - - Content.cs - - - DataMapper.cs - - - File.cs - - - IClient.cs - - - InlineImage.cs - - - ITransmissions.cs - - - Options.cs - - - Recipient.cs - - - RecipientType.cs - - - Request.cs - - - RequestSender.cs - - - Response.cs - - - ResponseException.cs - - - SendTransmissionResponse.cs - - - Transmission.cs - - - Transmissions.cs - - - - Properties\AssemblyInfo.cs - - - - - ..\packages\Newtonsoft.Json.8.0.2\lib\portable-net45+wp80+win8+wpa81+dnxcore50\Newtonsoft.Json.dll - - - - - - SparkPost.nuspec - - - - + + + + Debug + AnyCPU + {2F7E9E0B-27BB-42AC-AB4A-B8249B64C654} + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + SparkPost + SparkPost.Portable + v4.5 + Profile7 + + + true + full + false + bin\Debug + DEBUG;PORTABLE + prompt + 4 + false + false + + + true + bin\Release + PORTABLE + prompt + 4 + false + false + + + + Address.cs + + + Attachment.cs + + + CcHandling.cs + + + Client.cs + + + Content.cs + + + DataMapper.cs + + + File.cs + + + IClient.cs + + + InlineImage.cs + + + ITransmissions.cs + + + Options.cs + + + Recipient.cs + + + RecipientType.cs + + + Request.cs + + + RequestSender.cs + + + Response.cs + + + ResponseException.cs + + + SendTransmissionResponse.cs + + + Transmission.cs + + + Transmissions.cs + + + + Properties\AssemblyInfo.cs + + + + + ..\packages\Newtonsoft.Json.8.0.2\lib\portable-net45+wp80+win8+wpa81+dnxcore50\Newtonsoft.Json.dll + + + + + + SparkPost.nuspec + + + + \ No newline at end of file diff --git a/src/SparkPost.Tests/MessageEventsQueryTests.cs b/src/SparkPost.Tests/MessageEventsQueryTests.cs index 9c3186ab..d9004d82 100644 --- a/src/SparkPost.Tests/MessageEventsQueryTests.cs +++ b/src/SparkPost.Tests/MessageEventsQueryTests.cs @@ -23,7 +23,7 @@ public void It_should_have_a_defualt_campaign_ids_list() [Test] public void It_should_have_a_default_friendly_froms_list() { - new MessageEventsQuery().FriendlyFroms.ShouldNotBeNull(); + new MessageEventsQuery().FromAddresses.ShouldNotBeNull(); } [Test] diff --git a/src/SparkPost/DataMapper.cs b/src/SparkPost/DataMapper.cs index ba94e6c0..defd3ac3 100644 --- a/src/SparkPost/DataMapper.cs +++ b/src/SparkPost/DataMapper.cs @@ -182,15 +182,14 @@ public IDictionary ToDictionary(MessageEventsQuery query) return WithCommonConventions(query, new Dictionary() { ["events"] = string.Join(",", query.Events), - ["campaign_ids"] = string.Join(",", query.CampaignIds), + ["campaigns"] = string.Join(",", query.CampaignIds), ["bounce_classes"] = string.Join(",", query.BounceClasses), - ["campaign_ids"] = string.Join(",", query.CampaignIds), - ["friendly_froms"] = string.Join(",", query.FriendlyFroms), - ["message_ids"] = string.Join(",", query.MessageIds), + ["from_addresses"] = string.Join(",", query.FromAddresses), + ["messages"] = string.Join(",", query.MessageIds), ["recipients"] = string.Join(",", query.Recipients), ["subaccounts"] = string.Join(",", query.Subaccounts), - ["template_ids"] = string.Join(",", query.TemplateIds), - ["transmission_ids"] = string.Join(",", query.TransmissionIds) + ["templates"] = string.Join(",", query.TemplateIds), + ["transmissions"] = string.Join(",", query.TransmissionIds) }); } diff --git a/src/SparkPost/ListMessageEventsResponse.cs b/src/SparkPost/ListMessageEventsResponse.cs index eaa1d913..2f52250a 100644 --- a/src/SparkPost/ListMessageEventsResponse.cs +++ b/src/SparkPost/ListMessageEventsResponse.cs @@ -7,12 +7,11 @@ public class ListMessageEventsResponse : Response public ListMessageEventsResponse() { MessageEvents = new MessageEvent[] {}; - Links = new PageLink[] {}; } public IEnumerable MessageEvents { get; set; } - public IList Links { get; set; } + public PageLink Links { get; set; } public int TotalCount { get; set; } } diff --git a/src/SparkPost/MessageEvent.cs b/src/SparkPost/MessageEvent.cs index 69f9e8b1..dceb807a 100644 --- a/src/SparkPost/MessageEvent.cs +++ b/src/SparkPost/MessageEvent.cs @@ -308,12 +308,6 @@ public BounceClass BounceClassEnum /// public string SendingIp { get; set; } - /// - /// Not documented. - /// "tdate": "2016-04-27T22:05:40.000Z", - /// - public DateTime TDate { get; set; } - /// /// Not documented. /// "transactional": "1", diff --git a/src/SparkPost/MessageEventType.cs b/src/SparkPost/MessageEventType.cs index c55ecf35..f423b283 100644 --- a/src/SparkPost/MessageEventType.cs +++ b/src/SparkPost/MessageEventType.cs @@ -1,7 +1,7 @@ namespace SparkPost { // Values taken from: - // https://developers.sparkpost.com/api/#/reference/message-events/message-events + // https://developers.sparkpost.com/api/events/ // Additional values and descriptions taken from: // https://support.sparkpost.com/customer/portal/articles/1976204-webhook-event-reference diff --git a/src/SparkPost/MessageEvents.cs b/src/SparkPost/MessageEvents.cs index 2afbaee9..5139e48b 100644 --- a/src/SparkPost/MessageEvents.cs +++ b/src/SparkPost/MessageEvents.cs @@ -28,7 +28,7 @@ public async Task List(object messageEventsQuery) var request = new Request { - Url = $"/api/{client.Version}/message-events", + Url = $"/api/{client.Version}/events/message", Method = "GET", Data = messageEventsQuery }; @@ -55,7 +55,7 @@ public async Task SamplesOf(string events) { var request = new Request { - Url = $"/api/{client.Version}/message-events/events/samples?events={events}", + Url = $"/api/{client.Version}/events/message/samples?events={events}", Method = "GET" }; @@ -70,20 +70,12 @@ public async Task SamplesOf(string events) }; } - private static IEnumerable ConvertToLinks(dynamic page_links) + private static PageLink ConvertToLinks(dynamic page_links) { - var links = new List(); + var links = new PageLink(); - if (page_links == null) return links; + if (page_links != null) links.Next = page_links.next; - foreach (var page_link in page_links) - { - links.Add(new PageLink - { - Href = page_link.href, - Type = page_link.rel - }); - } return links; } @@ -131,7 +123,6 @@ private static IEnumerable ConvertResultsToAListOfMessageEvents(dy QueueTime = result.queue_time, RawRecipientTo = result.raw_rcpt_to, SendingIp = result.sending_ip, - TDate = result.tdate, Transactional = result.transactional, RemoteAddress = result.remote_addr, Metadata = metadata, diff --git a/src/SparkPost/MessageEventsQuery.cs b/src/SparkPost/MessageEventsQuery.cs index 03912fc5..87ba93f5 100644 --- a/src/SparkPost/MessageEventsQuery.cs +++ b/src/SparkPost/MessageEventsQuery.cs @@ -13,7 +13,7 @@ public MessageEventsQuery() this.Events = new List(); this.BounceClasses = new List(); this.CampaignIds = new List(); - this.FriendlyFroms = new List(); + this.FromAddresses = new List(); this.MessageIds = new List(); this.Recipients = new List(); this.Subaccounts = new List(); @@ -29,7 +29,7 @@ public MessageEventsQuery() public IList BounceClasses { get; set; } /// - /// campaign_ids : ? : (optional, string, `Example Campaign Name`) ... Comma-delimited list of campaign ID's to search (i.e. campaign_id used during creation of a transmission). + /// campaigns : ? : (optional, string, `Example Campaign Name`) ... Comma-delimited list of campaign ID's to search (i.e. campaign_id used during creation of a transmission). /// public IList CampaignIds { get; set; } @@ -40,9 +40,9 @@ public MessageEventsQuery() public IList Events { get; set; } /// - /// friendly_froms : ? : (optional, list, `sender@mail.example.com`) ... Comma-delimited list of friendly_froms to search. + /// from_addresses : ? : (optional, list, `sender@mail.example.com`) ... Comma-delimited list of friendly_froms to search. /// - public IList FriendlyFroms { get; set; } + public IList FromAddresses { get; set; } /// /// from : Datetime : Datetime in format of YYYY-MM-DDTHH:MM. @@ -52,7 +52,7 @@ public MessageEventsQuery() public DateTime? From { get; set; } /// - /// message_ids : List : Comma-delimited list of message ID's to search. + /// messages : List : Comma-delimited list of message ID's to search. /// Example: 0e0d94b7-9085-4e3c-ab30-e3f2cd9c273e. /// public IList MessageIds { get; set; } @@ -90,7 +90,7 @@ public MessageEventsQuery() public IList Subaccounts { get; set; } /// - /// template_ids : List : Comma-delimited list of template ID's to search. + /// templates : List : Comma-delimited list of template ID's to search. /// Example: templ-1234. /// public IList TemplateIds { get; set; } @@ -110,7 +110,7 @@ public MessageEventsQuery() public DateTime? To { get; set; } /// - /// transmission_ids : List : Comma-delimited list of transmission ID's to search (i.e. id generated during creation of a transmission). + /// transmissions : List : Comma-delimited list of transmission ID's to search (i.e. id generated during creation of a transmission). /// Example: 65832150921904138. /// public IList TransmissionIds { get; set; } diff --git a/src/SparkPost/PageLink.cs b/src/SparkPost/PageLink.cs index e8cdd63d..6bafe19c 100644 --- a/src/SparkPost/PageLink.cs +++ b/src/SparkPost/PageLink.cs @@ -2,7 +2,6 @@ { public class PageLink { - public string Href { get; set; } - public string Type { get; set; } + public string Next { get; set; } } } \ No newline at end of file From b306e94dd977070de39a301d65f877ff68b6d3fd Mon Sep 17 00:00:00 2001 From: JM Date: Wed, 5 Jun 2019 19:31:25 -0400 Subject: [PATCH 2/3] Fix failed tests --- src/SparkPost.Tests/ClientTests.cs | 2 +- src/SparkPost/ListMessageEventsResponse.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SparkPost.Tests/ClientTests.cs b/src/SparkPost.Tests/ClientTests.cs index d5001cd6..759d1903 100644 --- a/src/SparkPost.Tests/ClientTests.cs +++ b/src/SparkPost.Tests/ClientTests.cs @@ -75,7 +75,7 @@ public void Setup() [Test] public void It_should_default_to_the_library_version() { - Subject.UserAgent.ShouldEqual($"csharp-sparkpost/1.14.0"); + Subject.UserAgent.ShouldEqual($"csharp-sparkpost/1.15.0"); } [Test] diff --git a/src/SparkPost/ListMessageEventsResponse.cs b/src/SparkPost/ListMessageEventsResponse.cs index 2f52250a..11827a60 100644 --- a/src/SparkPost/ListMessageEventsResponse.cs +++ b/src/SparkPost/ListMessageEventsResponse.cs @@ -7,6 +7,7 @@ public class ListMessageEventsResponse : Response public ListMessageEventsResponse() { MessageEvents = new MessageEvent[] {}; + Links = new PageLink(); } public IEnumerable MessageEvents { get; set; } From be81cf170f9f6973a7a0c3aa88b79862f1ff240b Mon Sep 17 00:00:00 2001 From: JM Date: Wed, 12 Jun 2019 21:13:41 -0400 Subject: [PATCH 3/3] Add missing MessageEventType and BounceClass enum values Add InitialOpen, AmpClick, AmpOpen, AmpInitialOpen to MessageEventType Add SmartSendSuppression to BounceClass --- src/SparkPost/BounceClass.cs | 7 +++++++ src/SparkPost/MessageEventType.cs | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/SparkPost/BounceClass.cs b/src/SparkPost/BounceClass.cs index a570cf7d..736d1671 100644 --- a/src/SparkPost/BounceClass.cs +++ b/src/SparkPost/BounceClass.cs @@ -66,6 +66,13 @@ public enum BounceClass /// AdminFailure = 25, + /// + /// Smart Send Suppression + /// The message was suppressed by Smart Send policy. + /// Category: Admin. + /// + SmartSendSuppression = 26, + /// /// Generic Bounce: No RCPT /// No recipient could be determined for the message. diff --git a/src/SparkPost/MessageEventType.cs b/src/SparkPost/MessageEventType.cs index f423b283..52657f32 100644 --- a/src/SparkPost/MessageEventType.cs +++ b/src/SparkPost/MessageEventType.cs @@ -61,6 +61,34 @@ public enum MessageEventType /// Open, + /// + /// initial_open + /// Initial Open. + /// Recipient opened a message in a mail client, thus rendering a tracking pixel at the top of the message. + /// + InitialOpen, + + /// + /// amp_click + /// AMP Click. + /// Recipient clicked a tracked link in an AMP message, thus prompting a redirect through the SparkPost click-tracking server to the link's destination. + /// + AmpClick, + + /// + /// amp_open + /// AMP Open. + /// Recipient opened an AMP message in a mail client, thus rendering a tracking pixel at the bottom of the message. + /// + AmpOpen, + + /// + /// amp_initial_open + /// AMP Initial Open. + /// Recipient opened an AMP message in a mail client, thus rendering a tracking pixel at the top of the message. + /// + AmpInitialOpen, + /// /// click /// Click.