diff --git a/.gitattributes b/.gitattributes index 83fb9913..1a414a6a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ # Declare files that will always have CRLF line endings on checkout. -* text eol=lf 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/NuGet.Config b/src/NuGet.Config new file mode 100644 index 00000000..abc5b137 --- /dev/null +++ b/src/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file 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/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.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/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/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/IMessageEvents.cs b/src/SparkPost/IMessageEvents.cs index a4a58cd9..4e073225 100644 --- a/src/SparkPost/IMessageEvents.cs +++ b/src/SparkPost/IMessageEvents.cs @@ -5,7 +5,8 @@ namespace SparkPost public interface IMessageEvents { Task List(); - Task List(object query); + Task List(MessageEventsQuery query); + Task List(string url); Task SamplesOf(string events); } } \ No newline at end of file diff --git a/src/SparkPost/ListMessageEventsResponse.cs b/src/SparkPost/ListMessageEventsResponse.cs index eaa1d913..11827a60 100644 --- a/src/SparkPost/ListMessageEventsResponse.cs +++ b/src/SparkPost/ListMessageEventsResponse.cs @@ -7,12 +7,12 @@ public class ListMessageEventsResponse : Response public ListMessageEventsResponse() { MessageEvents = new MessageEvent[] {}; - Links = new PageLink[] {}; + 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..52657f32 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 @@ -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. diff --git a/src/SparkPost/MessageEvents.cs b/src/SparkPost/MessageEvents.cs index 2afbaee9..42f84e98 100644 --- a/src/SparkPost/MessageEvents.cs +++ b/src/SparkPost/MessageEvents.cs @@ -1,8 +1,8 @@ -using System.Collections.Generic; using SparkPost.RequestSenders; +using SparkPost.Utilities; +using System.Collections.Generic; using System.Net; using System.Threading.Tasks; -using SparkPost.Utilities; namespace SparkPost { @@ -19,18 +19,26 @@ public MessageEvents(IClient client, IRequestSender requestSender) public async Task List() { - return await List(null); + return await List((MessageEventsQuery)null); } - public async Task List(object messageEventsQuery) + public async Task List(MessageEventsQuery messageEventsQuery) { - if (messageEventsQuery == null) messageEventsQuery = new { }; + return await this.List($"/api/{client.Version}/events/message", messageEventsQuery); + } + public async Task List(string url) + { + return await this.List(url, null); + } + + public async Task List(string url, MessageEventsQuery messageEventsQuery) + { var request = new Request { - Url = $"/api/{client.Version}/message-events", + Url = url, Method = "GET", - Data = messageEventsQuery + Data = (object)messageEventsQuery ?? new { } }; var response = await requestSender.Send(request); @@ -55,7 +63,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 +78,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 +131,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..ead8871d 100644 --- a/src/SparkPost/MessageEventsQuery.cs +++ b/src/SparkPost/MessageEventsQuery.cs @@ -1,7 +1,5 @@ -using SparkPost.Utilities; using System; using System.Collections.Generic; -using System.Linq; namespace SparkPost { @@ -13,7 +11,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 +27,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 +38,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,22 +50,23 @@ 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; } /// - /// page : number : The results page number to return. Used with per_page for paging through results. - /// Example: 25. - /// Default: 1. + /// cursor : String : Results cursor for pagination. Used in conjunction with per_page parameter. See Pagination section for details. + /// Example: WycyMDE4LTExLTA1VDIyOjQ1OjM5LjAwMFonLCAnc3BjLTM4MTQ1MjY3MjMyNTA2NTEwJ10=. + /// Default: initial. /// - public int? Page { get; set; } + public string Cursor { get; set; } /// - /// per_page : Number : Number of results to return per page. Must be between 1 and 10,000 (inclusive). - /// Example: 100. + /// per_page : Number : Maximum number of results to return per page. Must be between 1 and 10,000. + /// Example: 5000. /// Default: 1000. + /// Note: Pagination requests count towards the number of requests allowed by rate limiting, the same as non-paginated requests. /// public int? PerPage { get; set; } @@ -90,7 +89,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 +109,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