From 09144ddb528b34ac770b91bffda2c1576f2d4c2e Mon Sep 17 00:00:00 2001 From: Daniel James Smith Date: Tue, 23 May 2023 14:43:44 +0200 Subject: [PATCH] [PM-153] Extend Freshdesk integration (#2939) * Move keys into FreshDeskSettings class * Add configurable custom fields for user and org In FreshDesk we currently use the custom fields `cf_user` and `cf_org`. - For the US instance these will be set to those values. - For the EU instance these will likely be configured to `cf_user_eu` and `cf_org_eu` * Fix file encoding * Add region to notes * Use customizable org field value in condition check --- src/Billing/BillingSettings.cs | 15 +++++++++++++-- src/Billing/Controllers/FreshdeskController.cs | 13 +++++++------ src/Billing/appsettings.json | 6 ++++++ .../Controllers/FreshdeskControllerTests.cs | 11 ++++++++--- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/Billing/BillingSettings.cs b/src/Billing/BillingSettings.cs index 5be6b205f..fe829dc3d 100644 --- a/src/Billing/BillingSettings.cs +++ b/src/Billing/BillingSettings.cs @@ -8,8 +8,7 @@ public class BillingSettings public virtual bool StripeEventParseThrowMismatch { get; set; } = true; public virtual string BitPayWebhookKey { get; set; } public virtual string AppleWebhookKey { get; set; } - public virtual string FreshdeskWebhookKey { get; set; } - public virtual string FreshdeskApiKey { get; set; } + public virtual FreshDeskSettings FreshDesk { get; set; } = new FreshDeskSettings(); public virtual string FreshsalesApiKey { get; set; } public virtual PayPalSettings PayPal { get; set; } = new PayPalSettings(); @@ -19,4 +18,16 @@ public class BillingSettings public virtual string BusinessId { get; set; } public virtual string WebhookKey { get; set; } } + + public class FreshDeskSettings + { + public virtual string ApiKey { get; set; } + public virtual string WebhookKey { get; set; } + /// + /// Indicates the data center region. Valid values are "US" and "EU" + /// + public virtual string Region { get; set; } + public virtual string UserFieldName { get; set; } + public virtual string OrgFieldName { get; set; } + } } diff --git a/src/Billing/Controllers/FreshdeskController.cs b/src/Billing/Controllers/FreshdeskController.cs index 05dbcf0f6..c45407b53 100644 --- a/src/Billing/Controllers/FreshdeskController.cs +++ b/src/Billing/Controllers/FreshdeskController.cs @@ -43,7 +43,7 @@ public class FreshdeskController : Controller public async Task PostWebhook([FromQuery, Required] string key, [FromBody, Required] FreshdeskWebhookModel model) { - if (string.IsNullOrWhiteSpace(key) || !CoreHelpers.FixedTimeEquals(key, _billingSettings.FreshdeskWebhookKey)) + if (string.IsNullOrWhiteSpace(key) || !CoreHelpers.FixedTimeEquals(key, _billingSettings.FreshDesk.WebhookKey)) { return new BadRequestResult(); } @@ -60,13 +60,14 @@ public class FreshdeskController : Controller var updateBody = new Dictionary(); var note = string.Empty; + note += $"
  • Region: {_billingSettings.FreshDesk.Region}
  • "; var customFields = new Dictionary(); var user = await _userRepository.GetByEmailAsync(ticketContactEmail); if (user != null) { var userLink = $"{_globalSettings.BaseServiceUri.Admin}/users/edit/{user.Id}"; note += $"
  • User, {user.Email}: {userLink}
  • "; - customFields.Add("cf_user", userLink); + customFields.Add(_billingSettings.FreshDesk.UserFieldName, userLink); var tags = new HashSet(); if (user.Premium) { @@ -79,13 +80,13 @@ public class FreshdeskController : Controller var orgNote = $"{org.Name} ({org.Seats.GetValueOrDefault()}): " + $"{_globalSettings.BaseServiceUri.Admin}/organizations/edit/{org.Id}"; note += $"
  • Org, {orgNote}
  • "; - if (!customFields.Any(kvp => kvp.Key == "cf_org")) + if (!customFields.Any(kvp => kvp.Key == _billingSettings.FreshDesk.OrgFieldName)) { - customFields.Add("cf_org", orgNote); + customFields.Add(_billingSettings.FreshDesk.OrgFieldName, orgNote); } else { - customFields["cf_org"] += $"\n{orgNote}"; + customFields[_billingSettings.FreshDesk.OrgFieldName] += $"\n{orgNote}"; } var planName = GetAttribute(org.PlanType).Name.Split(" ").FirstOrDefault(); @@ -145,7 +146,7 @@ public class FreshdeskController : Controller { try { - var freshdeskAuthkey = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_billingSettings.FreshdeskApiKey}:X")); + var freshdeskAuthkey = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_billingSettings.FreshDesk.ApiKey}:X")); var httpClient = _httpClientFactory.CreateClient("FreshdeskApi"); request.Headers.Add("Authorization", $"Basic {freshdeskAuthkey}"); var response = await httpClient.SendAsync(request); diff --git a/src/Billing/appsettings.json b/src/Billing/appsettings.json index 01d777774..1cd86c042 100644 --- a/src/Billing/appsettings.json +++ b/src/Billing/appsettings.json @@ -69,6 +69,12 @@ "production": false, "businessId": "AD3LAUZSNVPJY", "webhookKey": "SECRET" + }, + "freshdesk": { + "apiKey": "SECRET", + "webhookKey": "SECRET", + "userFieldName": "cf_user", + "orgFieldName": "cf_org" } } } diff --git a/test/Billing.Test/Controllers/FreshdeskControllerTests.cs b/test/Billing.Test/Controllers/FreshdeskControllerTests.cs index 354c2db2a..97c7434ea 100644 --- a/test/Billing.Test/Controllers/FreshdeskControllerTests.cs +++ b/test/Billing.Test/Controllers/FreshdeskControllerTests.cs @@ -19,6 +19,9 @@ public class FreshdeskControllerTests private const string ApiKey = "TESTFRESHDESKAPIKEY"; private const string WebhookKey = "TESTKEY"; + private const string UserFieldName = "cf_user"; + private const string OrgFieldName = "cf_org"; + [Theory] [BitAutoData((string)null, null)] [BitAutoData((string)null)] @@ -26,7 +29,7 @@ public class FreshdeskControllerTests public async Task PostWebhook_NullRequiredParameters_BadRequest(string freshdeskWebhookKey, FreshdeskWebhookModel model, BillingSettings billingSettings, SutProvider sutProvider) { - sutProvider.GetDependency>().Value.FreshdeskWebhookKey.Returns(billingSettings.FreshdeskWebhookKey); + sutProvider.GetDependency>().Value.FreshDesk.WebhookKey.Returns(billingSettings.FreshDesk.WebhookKey); var response = await sutProvider.Sut.PostWebhook(freshdeskWebhookKey, model); @@ -52,8 +55,10 @@ public class FreshdeskControllerTests sutProvider.GetDependency().CreateClient("FreshdeskApi").Returns(httpClient); - sutProvider.GetDependency>().Value.FreshdeskWebhookKey.Returns(WebhookKey); - sutProvider.GetDependency>().Value.FreshdeskApiKey.Returns(ApiKey); + sutProvider.GetDependency>().Value.FreshDesk.WebhookKey.Returns(WebhookKey); + sutProvider.GetDependency>().Value.FreshDesk.ApiKey.Returns(ApiKey); + sutProvider.GetDependency>().Value.FreshDesk.UserFieldName.Returns(UserFieldName); + sutProvider.GetDependency>().Value.FreshDesk.OrgFieldName.Returns(OrgFieldName); var response = await sutProvider.Sut.PostWebhook(WebhookKey, model);