mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-12 02:08:32 +01:00
Attempt to solve webhooks disappearing (#2178)
This commit is contained in:
parent
aaf85216eb
commit
0929857b12
3 changed files with 64 additions and 43 deletions
|
@ -36,36 +36,39 @@ namespace BTCPayServer.Controllers.GreenField
|
||||||
public WebhookNotificationManager WebhookNotificationManager { get; }
|
public WebhookNotificationManager WebhookNotificationManager { get; }
|
||||||
|
|
||||||
[HttpGet("~/api/v1/stores/{storeId}/webhooks/{webhookId?}")]
|
[HttpGet("~/api/v1/stores/{storeId}/webhooks/{webhookId?}")]
|
||||||
public async Task<IActionResult> ListWebhooks(string storeId, string webhookId)
|
public async Task<IActionResult> ListWebhooks(string webhookId)
|
||||||
{
|
{
|
||||||
if (webhookId is null)
|
if (webhookId is null)
|
||||||
{
|
{
|
||||||
var store = HttpContext.GetStoreData();
|
return Ok((await StoreRepository.GetWebhooks(CurrentStoreId))
|
||||||
if (store == null)
|
|
||||||
return NotFound();
|
|
||||||
return Ok((await StoreRepository.GetWebhooks(storeId))
|
|
||||||
.Select(o => FromModel(o, false))
|
.Select(o => FromModel(o, false))
|
||||||
.ToList());
|
.ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var w = await StoreRepository.GetWebhook(storeId, webhookId);
|
var w = await StoreRepository.GetWebhook(CurrentStoreId, webhookId);
|
||||||
if (w is null)
|
if (w is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return Ok(FromModel(w, false));
|
return Ok(FromModel(w, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[HttpPost("~/api/v1/stores/{storeId}/webhooks")]
|
|
||||||
public async Task<IActionResult> CreateWebhook(string storeId, Client.Models.CreateStoreWebhookRequest create)
|
string CurrentStoreId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.HttpContext.GetStoreData()?.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("~/api/v1/stores/{storeId}/webhooks")]
|
||||||
|
public async Task<IActionResult> CreateWebhook(Client.Models.CreateStoreWebhookRequest create)
|
||||||
{
|
{
|
||||||
var store = HttpContext.GetStoreData();
|
|
||||||
if (store == null)
|
|
||||||
return NotFound();
|
|
||||||
ValidateWebhookRequest(create);
|
ValidateWebhookRequest(create);
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
var webhookId = await StoreRepository.CreateWebhook(storeId, ToModel(create));
|
var webhookId = await StoreRepository.CreateWebhook(CurrentStoreId, ToModel(create));
|
||||||
var w = await StoreRepository.GetWebhook(storeId, webhookId);
|
var w = await StoreRepository.GetWebhook(CurrentStoreId, webhookId);
|
||||||
if (w is null)
|
if (w is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return Ok(FromModel(w, true));
|
return Ok(FromModel(w, true));
|
||||||
|
@ -83,25 +86,19 @@ namespace BTCPayServer.Controllers.GreenField
|
||||||
ValidateWebhookRequest(update);
|
ValidateWebhookRequest(update);
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return this.CreateValidationError(ModelState);
|
return this.CreateValidationError(ModelState);
|
||||||
var store = HttpContext.GetStoreData();
|
var w = await StoreRepository.GetWebhook(CurrentStoreId, webhookId);
|
||||||
if (store == null)
|
|
||||||
return NotFound();
|
|
||||||
var w = await StoreRepository.GetWebhook(storeId, webhookId);
|
|
||||||
if (w is null)
|
if (w is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
await StoreRepository.UpdateWebhook(storeId, webhookId, ToModel(update));
|
await StoreRepository.UpdateWebhook(storeId, webhookId, ToModel(update));
|
||||||
return await ListWebhooks(storeId, webhookId);
|
return await ListWebhooks(webhookId);
|
||||||
}
|
}
|
||||||
[HttpDelete("~/api/v1/stores/{storeId}/webhooks/{webhookId}")]
|
[HttpDelete("~/api/v1/stores/{storeId}/webhooks/{webhookId}")]
|
||||||
public async Task<IActionResult> DeleteWebhook(string storeId, string webhookId)
|
public async Task<IActionResult> DeleteWebhook(string webhookId)
|
||||||
{
|
{
|
||||||
var store = HttpContext.GetStoreData();
|
var w = await StoreRepository.GetWebhook(CurrentStoreId, webhookId);
|
||||||
if (store == null)
|
|
||||||
return NotFound();
|
|
||||||
var w = await StoreRepository.GetWebhook(storeId, webhookId);
|
|
||||||
if (w is null)
|
if (w is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
await StoreRepository.DeleteWebhook(storeId, webhookId);
|
await StoreRepository.DeleteWebhook(CurrentStoreId, webhookId);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
private WebhookBlob ToModel(StoreWebhookBaseData create)
|
private WebhookBlob ToModel(StoreWebhookBaseData create)
|
||||||
|
@ -124,41 +121,35 @@ namespace BTCPayServer.Controllers.GreenField
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("~/api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId?}")]
|
[HttpGet("~/api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId?}")]
|
||||||
public async Task<IActionResult> ListDeliveries(string storeId, string webhookId, string deliveryId, int? count = null)
|
public async Task<IActionResult> ListDeliveries(string webhookId, string deliveryId, int? count = null)
|
||||||
{
|
{
|
||||||
if (deliveryId is null)
|
if (deliveryId is null)
|
||||||
{
|
{
|
||||||
var store = HttpContext.GetStoreData();
|
return Ok((await StoreRepository.GetWebhookDeliveries(CurrentStoreId, webhookId, count))
|
||||||
if (store == null)
|
|
||||||
return NotFound();
|
|
||||||
return Ok((await StoreRepository.GetWebhookDeliveries(storeId, webhookId, count))
|
|
||||||
.Select(o => FromModel(o))
|
.Select(o => FromModel(o))
|
||||||
.ToList());
|
.ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var delivery = await StoreRepository.GetWebhookDelivery(storeId, webhookId, deliveryId);
|
var delivery = await StoreRepository.GetWebhookDelivery(CurrentStoreId, webhookId, deliveryId);
|
||||||
if (delivery is null)
|
if (delivery is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return Ok(FromModel(delivery));
|
return Ok(FromModel(delivery));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[HttpPost("~/api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver")]
|
[HttpPost("~/api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver")]
|
||||||
public async Task<IActionResult> RedeliverWebhook(string storeId, string webhookId, string deliveryId)
|
public async Task<IActionResult> RedeliverWebhook(string webhookId, string deliveryId)
|
||||||
{
|
{
|
||||||
var delivery = await StoreRepository.GetWebhookDelivery(HttpContext.GetStoreData().Id, webhookId, deliveryId);
|
var delivery = await StoreRepository.GetWebhookDelivery(CurrentStoreId, webhookId, deliveryId);
|
||||||
if (delivery is null)
|
if (delivery is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return this.Ok(new JValue(await WebhookNotificationManager.Redeliver(deliveryId)));
|
return this.Ok(new JValue(await WebhookNotificationManager.Redeliver(deliveryId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("~/api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request")]
|
[HttpGet("~/api/v1/stores/{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request")]
|
||||||
public async Task<IActionResult> GetDeliveryRequest(string storeId, string webhookId, string deliveryId)
|
public async Task<IActionResult> GetDeliveryRequest(string webhookId, string deliveryId)
|
||||||
{
|
{
|
||||||
var store = HttpContext.GetStoreData();
|
var delivery = await StoreRepository.GetWebhookDelivery(CurrentStoreId, webhookId, deliveryId);
|
||||||
if (store == null)
|
|
||||||
return NotFound();
|
|
||||||
var delivery = await StoreRepository.GetWebhookDelivery(storeId, webhookId, deliveryId);
|
|
||||||
if (delivery is null)
|
if (delivery is null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
return File(delivery.GetBlob().Request, "application/json");
|
return File(delivery.GetBlob().Request, "application/json");
|
||||||
|
|
|
@ -86,6 +86,8 @@ namespace BTCPayServer.HostedServices
|
||||||
public async Task<string> Redeliver(string deliveryId)
|
public async Task<string> Redeliver(string deliveryId)
|
||||||
{
|
{
|
||||||
var deliveryRequest = await CreateRedeliveryRequest(deliveryId);
|
var deliveryRequest = await CreateRedeliveryRequest(deliveryId);
|
||||||
|
if (deliveryRequest is null)
|
||||||
|
return null;
|
||||||
EnqueueDelivery(deliveryRequest);
|
EnqueueDelivery(deliveryRequest);
|
||||||
return deliveryRequest.Delivery.Id;
|
return deliveryRequest.Delivery.Id;
|
||||||
}
|
}
|
||||||
|
@ -208,8 +210,8 @@ namespace BTCPayServer.HostedServices
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ctx = originalCtx;
|
var ctx = originalCtx;
|
||||||
var wh = (await StoreRepository.GetWebhook(ctx.WebhookId)).GetBlob();
|
var wh = (await StoreRepository.GetWebhook(ctx.WebhookId))?.GetBlob();
|
||||||
if (!ShouldDeliver(ctx.WebhookEvent.Type, wh))
|
if (wh is null || !ShouldDeliver(ctx.WebhookEvent.Type, wh))
|
||||||
continue;
|
continue;
|
||||||
var result = await SendDelivery(ctx);
|
var result = await SendDelivery(ctx);
|
||||||
if (ctx.WebhookBlob.AutomaticRedelivery &&
|
if (ctx.WebhookBlob.AutomaticRedelivery &&
|
||||||
|
|
|
@ -206,6 +206,10 @@ namespace BTCPayServer.Services.Stores
|
||||||
|
|
||||||
public async Task<WebhookDeliveryData> GetWebhookDelivery(string storeId, string webhookId, string deliveryId)
|
public async Task<WebhookDeliveryData> GetWebhookDelivery(string storeId, string webhookId, string deliveryId)
|
||||||
{
|
{
|
||||||
|
if (webhookId == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookId));
|
||||||
|
if (storeId == null)
|
||||||
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
using var ctx = _ContextFactory.CreateContext();
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
return await ctx.StoreWebhooks
|
return await ctx.StoreWebhooks
|
||||||
.Where(d => d.StoreId == storeId && d.WebhookId == webhookId)
|
.Where(d => d.StoreId == storeId && d.WebhookId == webhookId)
|
||||||
|
@ -232,6 +236,10 @@ namespace BTCPayServer.Services.Stores
|
||||||
|
|
||||||
public async Task<WebhookDeliveryData[]> GetWebhookDeliveries(string storeId, string webhookId, int? count)
|
public async Task<WebhookDeliveryData[]> GetWebhookDeliveries(string storeId, string webhookId, int? count)
|
||||||
{
|
{
|
||||||
|
if (webhookId == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookId));
|
||||||
|
if (storeId == null)
|
||||||
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
using var ctx = _ContextFactory.CreateContext();
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
IQueryable<WebhookDeliveryData> req = ctx.StoreWebhooks
|
IQueryable<WebhookDeliveryData> req = ctx.StoreWebhooks
|
||||||
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
||||||
|
@ -245,6 +253,10 @@ namespace BTCPayServer.Services.Stores
|
||||||
|
|
||||||
public async Task<string> CreateWebhook(string storeId, WebhookBlob blob)
|
public async Task<string> CreateWebhook(string storeId, WebhookBlob blob)
|
||||||
{
|
{
|
||||||
|
if (storeId == null)
|
||||||
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
|
if (blob == null)
|
||||||
|
throw new ArgumentNullException(nameof(blob));
|
||||||
using var ctx = _ContextFactory.CreateContext();
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
WebhookData data = new WebhookData();
|
WebhookData data = new WebhookData();
|
||||||
data.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16));
|
data.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(16));
|
||||||
|
@ -262,7 +274,11 @@ namespace BTCPayServer.Services.Stores
|
||||||
|
|
||||||
public async Task<WebhookData> GetWebhook(string storeId, string webhookId)
|
public async Task<WebhookData> GetWebhook(string storeId, string webhookId)
|
||||||
{
|
{
|
||||||
var ctx = _ContextFactory.CreateContext();
|
if (webhookId == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookId));
|
||||||
|
if (storeId == null)
|
||||||
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
return await ctx.StoreWebhooks
|
return await ctx.StoreWebhooks
|
||||||
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
||||||
.Select(s => s.Webhook)
|
.Select(s => s.Webhook)
|
||||||
|
@ -270,7 +286,9 @@ namespace BTCPayServer.Services.Stores
|
||||||
}
|
}
|
||||||
public async Task<WebhookData> GetWebhook(string webhookId)
|
public async Task<WebhookData> GetWebhook(string webhookId)
|
||||||
{
|
{
|
||||||
var ctx = _ContextFactory.CreateContext();
|
if (webhookId == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookId));
|
||||||
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
return await ctx.StoreWebhooks
|
return await ctx.StoreWebhooks
|
||||||
.Where(s => s.WebhookId == webhookId)
|
.Where(s => s.WebhookId == webhookId)
|
||||||
.Select(s => s.Webhook)
|
.Select(s => s.Webhook)
|
||||||
|
@ -278,7 +296,11 @@ namespace BTCPayServer.Services.Stores
|
||||||
}
|
}
|
||||||
public async Task DeleteWebhook(string storeId, string webhookId)
|
public async Task DeleteWebhook(string storeId, string webhookId)
|
||||||
{
|
{
|
||||||
var ctx = _ContextFactory.CreateContext();
|
if (webhookId == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookId));
|
||||||
|
if (storeId == null)
|
||||||
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
var hook = await ctx.StoreWebhooks
|
var hook = await ctx.StoreWebhooks
|
||||||
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
||||||
.Select(s => s.Webhook)
|
.Select(s => s.Webhook)
|
||||||
|
@ -291,7 +313,13 @@ namespace BTCPayServer.Services.Stores
|
||||||
|
|
||||||
public async Task UpdateWebhook(string storeId, string webhookId, WebhookBlob webhookBlob)
|
public async Task UpdateWebhook(string storeId, string webhookId, WebhookBlob webhookBlob)
|
||||||
{
|
{
|
||||||
var ctx = _ContextFactory.CreateContext();
|
if (webhookId == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookId));
|
||||||
|
if (storeId == null)
|
||||||
|
throw new ArgumentNullException(nameof(storeId));
|
||||||
|
if (webhookBlob == null)
|
||||||
|
throw new ArgumentNullException(nameof(webhookBlob));
|
||||||
|
using var ctx = _ContextFactory.CreateContext();
|
||||||
var hook = await ctx.StoreWebhooks
|
var hook = await ctx.StoreWebhooks
|
||||||
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
.Where(s => s.StoreId == storeId && s.WebhookId == webhookId)
|
||||||
.Select(s => s.Webhook)
|
.Select(s => s.Webhook)
|
||||||
|
|
Loading…
Add table
Reference in a new issue