// ========================================================================== // WebhooksController.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== using System; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; using NSwag.Annotations; using Squidex.Controllers.Api.Webhooks.Models; using Squidex.Domain.Apps.Read.Schemas.Repositories; using Squidex.Domain.Apps.Write.Schemas.Commands; using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Pipeline; namespace Squidex.Controllers.Api.Webhooks { /// /// Manages and retrieves information about schemas. /// [ApiExceptionFilter] [AppApi] [SwaggerTag("Webhooks")] [MustBeAppDeveloper] public class WebhooksController : ControllerBase { private readonly ISchemaWebhookRepository webhooksRepository; public WebhooksController(ICommandBus commandBus, ISchemaWebhookRepository webhooksRepository) : base(commandBus) { this.webhooksRepository = webhooksRepository; } /// /// Get webhooks. /// /// The name of the app. /// /// 200 => Webhooks returned. /// 404 => App not found. /// [HttpGet] [Route("apps/{app}/webhooks/")] [ProducesResponseType(typeof(WebhookDto[]), 200)] [ApiCosts(1)] public async Task GetWebhooks(string app) { var webhooks = await webhooksRepository.QueryByAppAsync(App.Id); Response.Headers["ETag"] = new StringValues(App.Version.ToString()); var response = webhooks.Select(w => { var count = w.TotalTimedout + w.TotalSucceeded + w.TotalFailed; var average = count == 0 ? 0 : w.TotalRequestTime / count; return SimpleMapper.Map(w, new WebhookDto { AverageRequestTimeMs = average, LastDumps = w.LastDumps.ToList() }); }); return Ok(response); } /// /// Create a new webhook. /// /// The name of the app. /// The name of the schema. /// The webhook object that needs to be added to the app. /// /// 201 => Webhook created. /// 400 => Webhook name or properties are not valid. /// 409 => Webhook name already in use. /// 404 => App or schema not found. /// /// /// All events for the specified app will be sent to the url. The timeout is 2 seconds. /// [HttpPost] [Route("apps/{app}/schemas/{name}/webhooks/")] [ProducesResponseType(typeof(WebhookCreatedDto), 201)] [ProducesResponseType(typeof(ErrorDto), 400)] [ProducesResponseType(typeof(ErrorDto), 409)] [ApiCosts(1)] public async Task PostWebhook(string app, string name, [FromBody] CreateWebhookDto request) { var command = new AddWebhook { Url = request.Url }; await CommandBus.PublishAsync(command); return CreatedAtAction(nameof(GetWebhooks), new { app }, SimpleMapper.Map(command, new WebhookCreatedDto { SchemaId = command.SchemaId.Id.ToString() })); } /// /// Delete a webhook. /// /// The name of the app. /// The name of the schema. /// The id of the webhook to delete. /// /// 204 => Webhook has been deleted. /// 404 => Webhook or shema or app not found. /// [HttpDelete] [Route("apps/{app}/schemas/{name}/webhooks/{id}")] [ApiCosts(1)] public async Task DeleteSchema(string app, string name, Guid id) { await CommandBus.PublishAsync(new DeleteWebhook { Id = id }); return NoContent(); } } }