mirror of
https://github.com/bitwarden/server.git
synced 2025-02-01 23:31:41 +01:00
freshdesk webhook endpoint
This commit is contained in:
parent
b6274ac728
commit
7dddf9fd8b
@ -7,6 +7,8 @@
|
||||
public virtual string StripeWebhookSecret { get; set; }
|
||||
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 PayPalSettings PayPal { get; set; } = new PayPalSettings();
|
||||
|
||||
public class PayPalSettings
|
||||
|
150
src/Billing/Controllers/FreshdeskController.cs
Normal file
150
src/Billing/Controllers/FreshdeskController.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using Bit.Core;
|
||||
using Bit.Core.Repositories;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Bit.Billing.Controllers
|
||||
{
|
||||
[Route("freshdesk")]
|
||||
public class FreshdeskController : Controller
|
||||
{
|
||||
private readonly BillingSettings _billingSettings;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly ILogger<AppleController> _logger;
|
||||
private readonly HttpClient _httpClient = new HttpClient();
|
||||
|
||||
public FreshdeskController(
|
||||
IUserRepository userRepository,
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IOptions<BillingSettings> billingSettings,
|
||||
ILogger<AppleController> logger)
|
||||
{
|
||||
_billingSettings = billingSettings?.Value;
|
||||
_userRepository = userRepository;
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost("webhook")]
|
||||
public async Task<IActionResult> PostWebhook()
|
||||
{
|
||||
if(HttpContext?.Request?.Query == null)
|
||||
{
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
var key = HttpContext.Request.Query.ContainsKey("key") ?
|
||||
HttpContext.Request.Query["key"].ToString() : null;
|
||||
if(key != _billingSettings.FreshdeskWebhookKey)
|
||||
{
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
string body = null;
|
||||
using(var reader = new StreamReader(HttpContext.Request.Body, Encoding.UTF8))
|
||||
{
|
||||
body = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
if(string.IsNullOrWhiteSpace(body))
|
||||
{
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dynamic data = JsonConvert.DeserializeObject(body);
|
||||
string ticketId = data.ticket_id;
|
||||
string ticketContactEmail = data.ticket_contact_email;
|
||||
if(string.IsNullOrWhiteSpace(ticketId) || string.IsNullOrWhiteSpace(ticketContactEmail))
|
||||
{
|
||||
return new BadRequestResult();
|
||||
}
|
||||
|
||||
var updateBody = new Dictionary<string, object>();
|
||||
var user = await _userRepository.GetByEmailAsync(ticketContactEmail);
|
||||
if(user != null)
|
||||
{
|
||||
var tags = new List<string>();
|
||||
if(user.Premium)
|
||||
{
|
||||
tags.Add("Premium");
|
||||
}
|
||||
var orgs = await _organizationRepository.GetManyByUserIdAsync(user.Id);
|
||||
if(orgs.Any())
|
||||
{
|
||||
foreach(var org in orgs)
|
||||
{
|
||||
tags.Add("Org:" + GetAttribute<DisplayAttribute>(org.PlanType).Name);
|
||||
}
|
||||
}
|
||||
var hasPaidOrg = orgs.Any(o => o.PlanType != Core.Enums.PlanType.Free);
|
||||
if(user.Premium || hasPaidOrg)
|
||||
{
|
||||
updateBody.Add("priority", 3);
|
||||
}
|
||||
if(tags.Any())
|
||||
{
|
||||
updateBody.Add("tags", tags);
|
||||
}
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Put,
|
||||
string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}", ticketId));
|
||||
request.Content = new StringContent(JsonConvert.SerializeObject(updateBody),
|
||||
Encoding.UTF8, "application/json");
|
||||
await CallFreshdeskApiAsync(request);
|
||||
}
|
||||
|
||||
return new OkResult();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Error processing freshdesk webhook.");
|
||||
return new BadRequestResult();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<HttpResponseMessage> CallFreshdeskApiAsync(HttpRequestMessage request, int retriedCount = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var authKey = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_billingSettings.FreshdeskApiKey}:X"));
|
||||
request.Headers.Add("Authorization", authKey);
|
||||
var response = await _httpClient.SendAsync(request);
|
||||
if(response.StatusCode != System.Net.HttpStatusCode.TooManyRequests || retriedCount > 3)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if(retriedCount > 3)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
await Task.Delay(60000 * (retriedCount + 1));
|
||||
return await CallFreshdeskApiAsync(request, retriedCount++);
|
||||
}
|
||||
|
||||
private TAttribute GetAttribute<TAttribute>(Enum enumValue) where TAttribute : Attribute
|
||||
{
|
||||
return enumValue.GetType().GetMember(enumValue.ToString()).First().GetCustomAttribute<TAttribute>();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user