diff --git a/src/Postmark.Tests/ClientTriggersTests.cs b/src/Postmark.Tests/ClientTriggersTests.cs index 1517eb5..04308ae 100644 --- a/src/Postmark.Tests/ClientTriggersTests.cs +++ b/src/Postmark.Tests/ClientTriggersTests.cs @@ -17,26 +17,19 @@ protected override void Setup() _client = new PostmarkClient(WRITE_TEST_SERVER_TOKEN); } - public ClientTriggersTests(): base(){ + public ClientTriggersTests() : base() + { this.Cleanup().Wait(); } private Task Cleanup() { - return Task.Run(async() => + return Task.Run(async () => { try { - var triggers = await _client.SearchTaggedTriggers(); var tasks = new List(); - foreach (var trigger in triggers.Tags) - { - if (trigger.MatchName.StartsWith(_triggerPrefix)) - { - var dt = _client.DeleteTagTrigger(trigger.ID); - tasks.Add(dt); - } - } + var inboundTriggers = await _client.GetAllInboundRuleTriggers(); foreach (var inboundRule in inboundTriggers.InboundRules) { @@ -56,70 +49,6 @@ private Task Cleanup() }); } - [Theory] - [InlineData("qwerty", false)] - [InlineData("pdq", true)] - public async void Client_CanCreateTagTrigger(string matchName, bool trackOpens) - { - var trigger = await _client.CreateTagTriggerAsync(_triggerPrefix + matchName, trackOpens); - var savedTrigger = await _client.GetTagTriggerAsync(trigger.ID); - - Assert.Equal(trigger.MatchName, savedTrigger.MatchName); - Assert.Equal(trigger.TrackOpens, savedTrigger.TrackOpens); - Assert.Equal(trigger.ID, savedTrigger.ID); - Assert.Equal(_triggerPrefix + matchName, savedTrigger.MatchName); - Assert.Equal(trackOpens, savedTrigger.TrackOpens); - } - - [Fact] - public async void Client_CanGetTagTrigger() - { - var trigger = await _client.CreateTagTriggerAsync(_triggerPrefix + "new-trigger" + DateTime.Now.Ticks); - var savedTrigger = await _client.GetTagTriggerAsync(trigger.ID); - - Assert.NotNull(savedTrigger); - } - - [Fact] - public async void Client_CanEditTagTrigger() - { - var trigger = await _client.CreateTagTriggerAsync(_triggerPrefix + "new-trigger" + DateTime.Now.Ticks, false); - var updatedTrigger = await _client.UpdateTagTriggerAsync(trigger.ID, _triggerPrefix + "updated" + DateTime.Now.Ticks, true); - - Assert.NotEqual(trigger.MatchName, updatedTrigger.MatchName); - Assert.NotEqual(trigger.TrackOpens, updatedTrigger.TrackOpens); - } - - [Fact] - public async void Client_CanDeleteTagTrigger() - { - var trigger = await _client.CreateTagTriggerAsync(_triggerPrefix + "new-trigger"); - var result = await _client.DeleteTagTrigger(trigger.ID); - - Assert.NotNull(result); - Assert.Equal(0, result.ErrorCode); - Assert.Equal(PostmarkStatus.Success, result.Status); - } - - [Fact] - public async void Client_CanSearchTagTriggers() - { - var nameprefix = _triggerPrefix + "-tag-" + TESTING_DATE.ToString("o"); - var names = Enumerable.Range(0, 10).Select(k => nameprefix + Guid.NewGuid()).ToArray(); - - var awaitables = names.Select(name => _client.CreateTagTriggerAsync(name)); - var results = await Task.WhenAll(awaitables); - - foreach (var name in names) - { - var result = (await _client.SearchTaggedTriggers(0, 100, name)).Tags; - Assert.Equal(name, result.Single().MatchName); - } - - var allTriggers = await _client.SearchTaggedTriggers(); - Assert.Equal(names.Count(), allTriggers.Tags.Count(k => k.MatchName.StartsWith(nameprefix))); - } - [Fact] public async void Client_CanCreateInboundTrigger() { diff --git a/src/Postmark.Tests/ClientWebhookTests.cs b/src/Postmark.Tests/ClientWebhookTests.cs new file mode 100644 index 0000000..03f6b1f --- /dev/null +++ b/src/Postmark.Tests/ClientWebhookTests.cs @@ -0,0 +1,149 @@ +using Xunit; +using PostmarkDotNet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using PostmarkDotNet.Exceptions; +using PostmarkDotNet.Model; +using PostmarkDotNet.Model.Webhooks; + +namespace Postmark.Tests +{ + public class ClientWebhookTests : ClientBaseFixture, IDisposable + { + private PostmarkAdminClient _adminClient; + private PostmarkServer _server; + + protected override void Setup() + { + _adminClient = new PostmarkAdminClient(WRITE_ACCOUNT_TOKEN, BASE_URL); + _server = _adminClient.CreateServerAsync($"integration-test-webhooks-{Guid.NewGuid()}").Result; + _client = new PostmarkClient(_server.ApiTokens.First(), BASE_URL); + } + + [Fact] + public async Task ClientCanCreateConfiguration() + { + var url = "http://www.test.com/webhook"; + var messageStream = "outbound"; + var httpAuth = new HttpAuth { Username = "testUser", Password = "testPassword" }; + var httpHeaders = new List { new HttpHeader { Name = "testName", Value = "testValue" } }; + var triggers = new WebhookConfigurationTriggers + { + Bounce = new WebhookConfigurationBounceTrigger { Enabled = true, IncludeContent = true }, + Click = new WebhookConfigurationClickTrigger { Enabled = true }, + Open = new WebhookConfigurationOpenTrigger { Enabled = true, PostFirstOpenOnly = true }, + Delivery = new WebhookConfigurationDeliveryTrigger { Enabled = true }, + SpamComplaint = new WebhookConfigurationSpamComplaintTrigger { Enabled = true, IncludeContent = true } + }; + var newConfiguration = await _client.CreateWebhookConfigurationAsync(url, messageStream, httpAuth, httpHeaders, triggers); + + Assert.NotNull(newConfiguration.ID); + Assert.Equal(url, newConfiguration.Url); + Assert.Equal(messageStream, newConfiguration.MessageStream); + Assert.Equal(httpAuth.Username, newConfiguration.HttpAuth.Username); + Assert.Equal(httpAuth.Password, newConfiguration.HttpAuth.Password); + Assert.Equal(httpHeaders.First().Name, newConfiguration.HttpHeaders.First().Name); + Assert.Equal(httpHeaders.First().Value, newConfiguration.HttpHeaders.First().Value); + Assert.Equal(triggers.Bounce.Enabled, newConfiguration.Triggers.Bounce.Enabled); + Assert.Equal(triggers.Bounce.IncludeContent, newConfiguration.Triggers.Bounce.IncludeContent); + Assert.Equal(triggers.Open.Enabled, newConfiguration.Triggers.Open.Enabled); + Assert.Equal(triggers.Open.PostFirstOpenOnly, newConfiguration.Triggers.Open.PostFirstOpenOnly); + Assert.Equal(triggers.Click.Enabled, newConfiguration.Triggers.Click.Enabled); + Assert.Equal(triggers.Delivery.Enabled, newConfiguration.Triggers.Delivery.Enabled); + Assert.Equal(triggers.SpamComplaint.Enabled, newConfiguration.Triggers.SpamComplaint.Enabled); + Assert.Equal(triggers.SpamComplaint.IncludeContent, newConfiguration.Triggers.SpamComplaint.IncludeContent); + } + + [Fact] + public async Task ClientCanGetWebhookConfiguration() + { + var url = "http://www.test123.com/webhook"; + + var expectedConfiguration = await _client.CreateWebhookConfigurationAsync(url); + + var actualConfiguration = await _client.GetWebhookConfigurationAsync(expectedConfiguration.ID.Value); + + Assert.Equal(expectedConfiguration.ID, actualConfiguration.ID); + Assert.Equal(expectedConfiguration.Url, actualConfiguration.Url); + Assert.Equal("outbound", actualConfiguration.MessageStream); + } + + [Fact] + public async Task ClientCanListWebhookConfigurations() + { + var url1 = "http://www.test1.com/hook" + Guid.NewGuid(); + var url2 = "http://www.test2.com/hook" + Guid.NewGuid(); + await _client.CreateWebhookConfigurationAsync(url1); + await _client.CreateWebhookConfigurationAsync(url2); + + var configurations = await _client.GetWebhookConfigurationsAsync(); + + Assert.Equal(2, configurations.Webhooks.Count()); + Assert.Contains(configurations.Webhooks, k => k.Url == url1); + Assert.Contains(configurations.Webhooks, k => k.Url == url2); + } + + [Fact] + public async Task ClientCanDeleteWebhookConfigurations() + { + var createdResponse = await _client.CreateWebhookConfigurationAsync("http://www.test.com/delete-hook"); + var configuration = await _client.GetWebhookConfigurationAsync(createdResponse.ID.Value); + + var response = await _client.DeleteWebhookConfigurationAsync(configuration.ID.Value); + + Assert.Equal(PostmarkStatus.Success, response.Status); + + await Assert.ThrowsAsync(async () => + await _client.GetWebhookConfigurationAsync(configuration.ID.Value)); + } + + [Fact] + public async Task ClientCanEditConfiguration() + { + var url = "http://www.test.com/webhook"; + var messageStream = "outbound"; + var httpAuth = new HttpAuth { Username = "testUser", Password = "testPassword" }; + var httpHeaders = new List { new HttpHeader { Name = "testName", Value = "testValue" } }; + var triggers = new WebhookConfigurationTriggers + { + Bounce = new WebhookConfigurationBounceTrigger { Enabled = true, IncludeContent = true }, + Click = new WebhookConfigurationClickTrigger { Enabled = true }, + }; + var oldConfig = await _client.CreateWebhookConfigurationAsync(url, messageStream, httpAuth, httpHeaders, triggers); + + var newUrl = "http://www.test.com/new-webhook"; + var newHttpAuth = new HttpAuth { Username = "updatedUser", Password = "updatedPassword" }; + var newHeaders = new List(); + var triggersUpdate = new WebhookConfigurationTriggers + { + Click = new WebhookConfigurationClickTrigger { Enabled = false } + }; + var updatedConfig = await _client.EditWebhookConfigurationAsync(oldConfig.ID.Value, newUrl, newHttpAuth, + newHeaders, triggersUpdate); + + Assert.Equal(oldConfig.ID, updatedConfig.ID); + Assert.Equal(oldConfig.MessageStream, updatedConfig.MessageStream); + Assert.Equal(newHttpAuth.Username, updatedConfig.HttpAuth.Username); + Assert.Equal(newHttpAuth.Password, updatedConfig.HttpAuth.Password); + Assert.Equal(newUrl, updatedConfig.Url); + Assert.Equal(newHeaders, updatedConfig.HttpHeaders); + Assert.Equal(triggersUpdate.Click.Enabled, updatedConfig.Triggers.Click.Enabled); + Assert.Equal(triggers.Bounce.Enabled, updatedConfig.Triggers.Bounce.Enabled); + } + + private Task Cleanup() + { + return Task.Run(async () => + { + await _adminClient.DeleteServerAsync(_server.ID); + }); + } + + public void Dispose() + { + Cleanup().Wait(); + } + } +} diff --git a/src/Postmark.Tests/Postmark.Tests.csproj b/src/Postmark.Tests/Postmark.Tests.csproj index 50218b9..a4cc6b8 100755 --- a/src/Postmark.Tests/Postmark.Tests.csproj +++ b/src/Postmark.Tests/Postmark.Tests.csproj @@ -1,19 +1,11 @@  - - exe - - - exe - netcoreapp2.0 - exe + library - - diff --git a/src/Postmark/Model/PostmarkTaggedTriggerInfo.cs b/src/Postmark/Model/PostmarkTaggedTriggerInfo.cs deleted file mode 100644 index 269a111..0000000 --- a/src/Postmark/Model/PostmarkTaggedTriggerInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ - -namespace PostmarkDotNet.Model -{ - public class PostmarkTaggedTriggerInfo - { - public int ID { get; set; } - public string MatchName { get; set; } - public bool TrackOpens { get; set; } - } -} diff --git a/src/Postmark/Model/PostmarkTaggedTriggerList.cs b/src/Postmark/Model/PostmarkTaggedTriggerList.cs deleted file mode 100644 index 48ae764..0000000 --- a/src/Postmark/Model/PostmarkTaggedTriggerList.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace PostmarkDotNet.Model -{ - public class PostmarkTaggedTriggerList - { - public int TotalCount { get; set; } - - public IEnumerable Tags { get; set; } - } -} diff --git a/src/Postmark/Model/Webhooks/HttpAuth.cs b/src/Postmark/Model/Webhooks/HttpAuth.cs new file mode 100644 index 0000000..32e89f8 --- /dev/null +++ b/src/Postmark/Model/Webhooks/HttpAuth.cs @@ -0,0 +1,12 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Basic HTTP Authentication + /// + public class HttpAuth + { + public string Username { get; set; } + + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/HttpHeader.cs b/src/Postmark/Model/Webhooks/HttpHeader.cs new file mode 100644 index 0000000..1b241e6 --- /dev/null +++ b/src/Postmark/Model/Webhooks/HttpHeader.cs @@ -0,0 +1,12 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Custom HTTP Header + /// + public class HttpHeader + { + public string Name { get; set; } + + public string Value { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfiguration.cs b/src/Postmark/Model/Webhooks/WebhookConfiguration.cs new file mode 100644 index 0000000..d0ef6ee --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfiguration.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; + +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// The webhook configuration for a specific Server and Message Stream + /// + public class WebhookConfiguration + { + /// + /// ID of the webhook configuration. + /// + public long? ID { get; set; } + + /// + /// The webhook URL + /// + public string Url { get; set; } + + /// + /// MessageStream identifier that this configuration belongs to + /// + public string MessageStream { get; set; } + + /// + /// Optional Basic HTTP Authentication credentials + /// + public HttpAuth HttpAuth { get; set; } + + /// + /// Optional list of custom HttpHeaders to be included + /// + public IEnumerable HttpHeaders { get; set; } = new List(); + + /// + /// Configuration for the webhook triggers + /// + public WebhookConfigurationTriggers Triggers { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationBounceTrigger.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationBounceTrigger.cs new file mode 100644 index 0000000..3fbdd2f --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationBounceTrigger.cs @@ -0,0 +1,18 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Settings for Bounce webhooks + /// + public class WebhookConfigurationBounceTrigger + { + /// + /// Specifies whether or not webhooks will be triggered by Bounce events + /// + public bool Enabled { get; set; } + + /// + /// Specifies whether or not the full content of the email bounce is included in webhook POST. + /// + public bool IncludeContent { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationClickTrigger.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationClickTrigger.cs new file mode 100644 index 0000000..915bb60 --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationClickTrigger.cs @@ -0,0 +1,13 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Settings for Click webhooks + /// + public class WebhookConfigurationClickTrigger + { + /// + /// Specifies whether or not webhooks will be triggered by Click events + /// + public bool Enabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationDeliveryTrigger.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationDeliveryTrigger.cs new file mode 100644 index 0000000..966da08 --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationDeliveryTrigger.cs @@ -0,0 +1,13 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Settings for Delivery webhooks + /// + public class WebhookConfigurationDeliveryTrigger + { + /// + /// Specifies whether or not webhooks will be triggered by Delivery events + /// + public bool Enabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationListingResponse.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationListingResponse.cs new file mode 100644 index 0000000..8a84fa0 --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationListingResponse.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// The response for listing webhook configurations + /// + public class WebhookConfigurationListingResponse + { + /// + /// Collection of WebHookConfigurations matching the query + /// + public IEnumerable Webhooks { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationOpenTrigger.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationOpenTrigger.cs new file mode 100644 index 0000000..fe7b872 --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationOpenTrigger.cs @@ -0,0 +1,18 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Settings for Open webhooks + /// + public class WebhookConfigurationOpenTrigger + { + /// + /// Specifies whether or not webhooks will be triggered by Open events + /// + public bool Enabled { get; set; } + + /// + /// If enabled, open webhook will only POST on first open. + /// + public bool PostFirstOpenOnly { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationSpamComplaintTrigger.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationSpamComplaintTrigger.cs new file mode 100644 index 0000000..ef55a4c --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationSpamComplaintTrigger.cs @@ -0,0 +1,18 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// Settings for SpamComplaint webhooks + /// + public class WebhookConfigurationSpamComplaintTrigger + { + /// + /// Specifies whether or not webhooks will be triggered by SpamComplaint events + /// + public bool Enabled { get; set; } + + /// + /// Specifies whether or not the full content of the spam complaint is included in webhook POST. + /// + public bool IncludeContent { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/Model/Webhooks/WebhookConfigurationTriggers.cs b/src/Postmark/Model/Webhooks/WebhookConfigurationTriggers.cs new file mode 100644 index 0000000..b02d591 --- /dev/null +++ b/src/Postmark/Model/Webhooks/WebhookConfigurationTriggers.cs @@ -0,0 +1,33 @@ +namespace PostmarkDotNet.Model.Webhooks +{ + /// + /// All triggers available for a WebhookConfiguration + /// + public class WebhookConfigurationTriggers + { + /// + /// Settings for Open webhooks + /// + public WebhookConfigurationOpenTrigger Open { get; set; } + + /// + /// Settings for Click webhooks + /// + public WebhookConfigurationClickTrigger Click { get; set; } + + /// + /// Settings for Delivery webhooks + /// + public WebhookConfigurationDeliveryTrigger Delivery { get; set; } + + /// + /// Settings for Bounce webhooks + /// + public WebhookConfigurationBounceTrigger Bounce { get; set; } + + /// + /// Settings for SpamComplaint webhooks + /// + public WebhookConfigurationSpamComplaintTrigger SpamComplaint { get; set; } + } +} \ No newline at end of file diff --git a/src/Postmark/PostmarkClient.cs b/src/Postmark/PostmarkClient.cs index 611b40c..449f354 100644 --- a/src/Postmark/PostmarkClient.cs +++ b/src/Postmark/PostmarkClient.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Net.Http; using System.Threading.Tasks; +using PostmarkDotNet.Model.Webhooks; namespace PostmarkDotNet { @@ -685,85 +686,7 @@ public async Task GetOutboundReadtimeStatsAsync(strin } #endregion - #region Triggers - - /// - /// Create a new Tag Trigger. - /// - /// - /// - /// - public async Task CreateTagTriggerAsync(string matchName, bool trackOpens = true) - { - var parameters = new Dictionary(); - parameters["MatchName"] = matchName; - parameters["TrackOpens"] = trackOpens; - - return await this.ProcessRequestAsync, PostmarkTaggedTriggerInfo> - ("/triggers/tags", HttpMethod.Post, parameters); - } - - /// - /// Retrieve a tag trigger. - /// - /// - /// - public async Task GetTagTriggerAsync(int triggerId) - { - var result = await this.ProcessNoBodyRequestAsync("/triggers/tags/" + triggerId); - result.ID = triggerId; - return result; - } - - /// - /// Modify a Tag Trigger. - /// - /// - /// - /// - /// - public async Task UpdateTagTriggerAsync(int triggerId, string matchName = null, bool? trackOpens = null) - { - var parameters = new Dictionary(); - parameters["MatchName"] = matchName; - parameters["TrackOpens"] = trackOpens; - - var result = await this - .ProcessRequestAsync, PostmarkTaggedTriggerInfo>("/triggers/tags/" + triggerId, - HttpMethod.Put, parameters); - - result.ID = triggerId; - return result; - } - - /// - /// Delete a Tag Trigger based on the ID. - /// - /// - /// - public async Task DeleteTagTrigger(int triggerId) - { - return await this - .ProcessNoBodyRequestAsync("/triggers/tags/" + triggerId, - verb: HttpMethod.Delete); - } - - /// - /// Find all tag triggers, optionall filtering by "matchName". - /// - /// - /// - /// - /// - public async Task SearchTaggedTriggers(int offset = 0, int count = 100, string matchName = null) - { - var parameters = new Dictionary(); - parameters["offset"] = offset; - parameters["count"] = count; - parameters["match_name"] = matchName; - - return await this.ProcessNoBodyRequestAsync("/triggers/tags/", parameters); - } + #region Inbound Triggers /// /// Define a new Inbound Rule Trigger @@ -1032,5 +955,86 @@ public async Task ValidateTemplateAsync(string su return await ProcessRequestAsync, TemplateValidationResponse>("/templates/validate", HttpMethod.Post, body); } #endregion + + #region Webhooks + + /// + /// Gets the webhook configuration for the provided configuration id + /// + /// Configuration Id to search for + /// + public async Task GetWebhookConfigurationAsync(long configurationId) + { + return await ProcessNoBodyRequestAsync($"/webhooks/{configurationId}", null, HttpMethod.Get); + } + + /// + /// Gets a listing of webhook configurations for the provided server + /// + /// Optional message stream to search for. + /// If not provided, all configurations for the server will be returned. + /// + public async Task GetWebhookConfigurationsAsync(string messageStream = null) + { + var query = new Dictionary { ["MessageStream"] = messageStream }; + + return await ProcessNoBodyRequestAsync("/webhooks/", query, HttpMethod.Get); + } + + /// + /// Delete a webhook configuration from the server. + /// + /// Configuration id to search for + /// + public async Task DeleteWebhookConfigurationAsync(long configurationId) + { + return await ProcessNoBodyRequestAsync($"/webhooks/{configurationId}", null, HttpMethod.Delete); + } + + /// + /// Creates a new webhook configuration + /// + /// The webhook URL + /// Message stream this configuration should belong to. + /// If not provided, it will belong to the default transactional stream. + /// Optional Basic HTTP Authentication + /// Optional list of custom HTTP headers + /// Optional triggers for this webhook configuration + /// + public async Task CreateWebhookConfigurationAsync(string url, string messageStream = null, + HttpAuth httpAuth = null, IEnumerable httpHeaders = null, WebhookConfigurationTriggers triggers = null) + { + var body = new Dictionary(); + body["Url"] = url; + body["MessageStream"] = messageStream; + body["HttpAuth"] = httpAuth; + body["HttpHeaders"] = httpHeaders; + body["Triggers"] = triggers; + + return await ProcessRequestAsync, WebhookConfiguration>("/webhooks/", HttpMethod.Post, body); + } + + /// + /// Update a webhook configuration for the provided configuration id. + /// + /// Configuration id to search for + /// The webhook URL + /// Optional Basic HTTP Authentication + /// Optional list of custom HTTP headers + /// Optional triggers for this webhook configuration + /// + public async Task EditWebhookConfigurationAsync(long configurationId, string url, + HttpAuth httpAuth = null, IEnumerable httpHeaders = null, WebhookConfigurationTriggers triggers = null) + { + var body = new Dictionary(); + body["Url"] = url; + body["HttpAuth"] = httpAuth; + body["HttpHeaders"] = httpHeaders; + body["Triggers"] = triggers; + + return await ProcessRequestAsync, WebhookConfiguration>($"/webhooks/{configurationId}", + HttpMethod.Put, body); + } + #endregion } }