From 354d7638fec3d3057707d0a8d8ac977160fa6da1 Mon Sep 17 00:00:00 2001 From: Lala Sabathil Date: Thu, 19 Dec 2024 15:10:56 +0100 Subject: [PATCH] Enhance Vimeo OTT project with new features and attributes Updated project file to include new ASP.NET Core package references for improved web utilities, authorization, and OpenAPI support. Added multiple properties to the `OttCustomer` class for better customer data handling. Introduced `MapVimeoOttWebhook` method in `ExtensionMethods.cs` for enhanced routing of webhook events. Created `VimeoOttWebhookAttribute` to mark methods handling OTT webhooks, facilitating structured event management. Added `OttWebhook` class to represent webhook events from Vimeo, including properties for embedded data and event details. --- AITSYS.Vimeo.Ott/AITSYS.Vimeo.Ott.csproj | 4 ++ .../Attributes/VimeoOttWebhookAttribute.cs | 22 ++++++ .../Entities/Customers/OttCustomer.cs | 72 +++++++++++++++++++ AITSYS.Vimeo.Ott/Entities/OttWebhook.cs | 29 ++++++++ AITSYS.Vimeo.Ott/ExtensionMethods.cs | 44 +++++++++++- 5 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 AITSYS.Vimeo.Ott/Attributes/VimeoOttWebhookAttribute.cs create mode 100644 AITSYS.Vimeo.Ott/Entities/OttWebhook.cs diff --git a/AITSYS.Vimeo.Ott/AITSYS.Vimeo.Ott.csproj b/AITSYS.Vimeo.Ott/AITSYS.Vimeo.Ott.csproj index 5177cc5..8819b51 100644 --- a/AITSYS.Vimeo.Ott/AITSYS.Vimeo.Ott.csproj +++ b/AITSYS.Vimeo.Ott/AITSYS.Vimeo.Ott.csproj @@ -68,6 +68,10 @@ + + + + diff --git a/AITSYS.Vimeo.Ott/Attributes/VimeoOttWebhookAttribute.cs b/AITSYS.Vimeo.Ott/Attributes/VimeoOttWebhookAttribute.cs new file mode 100644 index 0000000..9ec28e8 --- /dev/null +++ b/AITSYS.Vimeo.Ott/Attributes/VimeoOttWebhookAttribute.cs @@ -0,0 +1,22 @@ +namespace AITSYS.Vimeo.Ott.Attributes; + +/// +/// Marks a method to handle a topic for incoming ott webhooks. +/// +[AttributeUsage(AttributeTargets.Method)] +public sealed class VimeoOttWebhookAttribute : Attribute +{ + /// + /// Marks a method to handle a topic for incoming ott webhooks. + /// + /// The topic to handle. + public VimeoOttWebhookAttribute(string topic) + { + this.Topic = topic; + } + + /// + /// Gets the webhooks topic. + /// + public string Topic { get; } +} diff --git a/AITSYS.Vimeo.Ott/Entities/Customers/OttCustomer.cs b/AITSYS.Vimeo.Ott/Entities/Customers/OttCustomer.cs index d80765e..fbaf8df 100644 --- a/AITSYS.Vimeo.Ott/Entities/Customers/OttCustomer.cs +++ b/AITSYS.Vimeo.Ott/Entities/Customers/OttCustomer.cs @@ -86,6 +86,78 @@ public sealed class OttCustomer : OttIdObject + /// The campaign associated with the customer. + /// + [JsonProperty("campaign", NullValueHandling = NullValueHandling.Ignore)] + public string? Campaign { get; set; } + + /// + /// The coupon code used by the customer. + /// + [JsonProperty("coupon_code", NullValueHandling = NullValueHandling.Ignore)] + public string? CouponCode { get; set; } + + /// + /// The first name of the customer. + /// + [JsonProperty("first_name", NullValueHandling = NullValueHandling.Ignore)] + public string FirstName { get; set; } + + /// + /// The last name of the customer. + /// + [JsonProperty("last_name", NullValueHandling = NullValueHandling.Ignore)] + public string LastName { get; set; } + + /// + /// The date of the last payment made by the customer. + /// + [JsonProperty("last_payment_date", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? LastPaymentDate { get; set; } + + /// + /// The date of the next payment due from the customer. + /// + [JsonProperty("next_payment_date", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? NextPaymentDate { get; set; } + + /// + /// The end date of the customer's subscription pause. + /// + [JsonProperty("pause_end_date", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? PauseEndDate { get; set; } + + /// + /// The promotion code used by the customer. + /// + [JsonProperty("promotion_code", NullValueHandling = NullValueHandling.Ignore)] + public string? PromotionCode { get; set; } + + /// + /// The referrer of the customer. + /// + [JsonProperty("referrer", NullValueHandling = NullValueHandling.Ignore)] + public string? Referrer { get; set; } + + /// + /// The subscription frequency of the customer. + /// + [JsonProperty("subscription_frequency", NullValueHandling = NullValueHandling.Ignore)] + public string? SubscriptionFrequency { get; set; } + + /// + /// The subscription price of the customer. + /// + [JsonProperty("subscription_price", NullValueHandling = NullValueHandling.Ignore)] + public int? SubscriptionPrice { get; set; } + + /// + /// The subscription status of the customer. + /// + [JsonProperty("subscription_status", NullValueHandling = NullValueHandling.Ignore)] + public string SubscriptionStatus { get; set; } + /// /// The customers notification settings. /// diff --git a/AITSYS.Vimeo.Ott/Entities/OttWebhook.cs b/AITSYS.Vimeo.Ott/Entities/OttWebhook.cs new file mode 100644 index 0000000..0e4c1aa --- /dev/null +++ b/AITSYS.Vimeo.Ott/Entities/OttWebhook.cs @@ -0,0 +1,29 @@ +using AITSYS.Vimeo.Ott.Entities.EmbeddedData; + +using Newtonsoft.Json; + +namespace AITSYS.Vimeo.Ott.Entities; + +/// +/// Represents a webhook event from Vimeo OTT. +/// +public sealed class OttWebhook +{ + /// + /// Gets the embedded data related to the webhook event. + /// + [JsonProperty("_embedded", NullValueHandling = NullValueHandling.Ignore)] + public OttCustomerProductEmbeddedData Embedded { get; set; } + + /// + /// Gets the topic of the webhook event. + /// + [JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)] + public string Topic { get; set; } + + /// + /// Gets the date and time when the webhook event was created. + /// + [JsonProperty("created_at", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? CreatedAt { get; set; } +} diff --git a/AITSYS.Vimeo.Ott/ExtensionMethods.cs b/AITSYS.Vimeo.Ott/ExtensionMethods.cs index ff1f29e..73a08cd 100644 --- a/AITSYS.Vimeo.Ott/ExtensionMethods.cs +++ b/AITSYS.Vimeo.Ott/ExtensionMethods.cs @@ -1,12 +1,19 @@ -// Copyright 2025 Aiko IT Systems. See https://github.com/Aiko-IT-Systems/AITSYS.Vimeo.OTT/blob/main/LICENSE.md for the license. +using System.Reflection; +using AITSYS.Vimeo.Ott.Attributes; using AITSYS.Vimeo.Ott.Clients; using AITSYS.Vimeo.Ott.Logging; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; namespace AITSYS.Vimeo.Ott; +/// +/// Represents various extension methods. +/// public static class ExtensionMethods { /// @@ -29,4 +36,39 @@ public static VimeoOttClient GetClientForCustomer(this VimeoOttClient baseClient baseClient.Logger.LogDebug(LoggerEvents.Library, "Creating a new client bound to {customer}", customerHref); return new(shadowConfig); } + + /// + /// Maps methods marked with the to a specified pattern and applies the + /// provided authentication scheme. + /// + /// The to add the route to. + /// The URL pattern of the webhook endpoint. + /// The authentication scheme to apply to the endpoint. + /// The with the mapped webhook endpoint. + public static IEndpointRouteBuilder MapVimeoOttWebhook(this IEndpointRouteBuilder endpoints, string pattern, string authenticationScheme) + { + var methods = Assembly.GetExecutingAssembly() + .GetTypes() + .SelectMany(t => t.GetMethods()) + .Where(m => m.GetCustomAttributes(typeof(VimeoOttWebhookAttribute), false).Length > 0) + .ToArray(); + + foreach (var method in methods) + { + var attribute = method.GetCustomAttribute(); + if (attribute != null) + endpoints.MapPost(pattern, async context => + { + var instance = Activator.CreateInstance(method.DeclaringType); + var parameters = method.GetParameters().Select(p => context.RequestServices.GetService(p.ParameterType)).ToArray(); + await (Task)method.Invoke(instance, parameters); + }) + .RequireAuthorization(new AuthorizeAttribute + { + AuthenticationSchemes = authenticationScheme + }); + } + + return endpoints; + } }