Initial import into Gitea
This commit is contained in:
205
MetaApi/Models/OperationPayloads.cs
Normal file
205
MetaApi/Models/OperationPayloads.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MetaApi.Models;
|
||||
|
||||
#region Campaign Payloads
|
||||
|
||||
/// <summary>
|
||||
/// Create a Meta campaign.
|
||||
/// Meta hierarchy: Campaign → Ad Set → Ad
|
||||
/// With Advantage+ (v25.0+), this uses the unified campaign API.
|
||||
/// </summary>
|
||||
public sealed class CreateCampaignPayload
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public MetaObjective Objective { get; set; } = MetaObjective.Conversions;
|
||||
|
||||
/// <summary>
|
||||
/// Campaign spending limit in account currency (in cents).
|
||||
/// Null = no campaign spending limit.
|
||||
/// </summary>
|
||||
public long? SpendCapCents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Special ad categories required by Meta for housing, employment, credit, etc.
|
||||
/// Empty = none (most campaigns).
|
||||
/// </summary>
|
||||
public List<string> SpecialAdCategories { get; set; } = new();
|
||||
|
||||
public MetaCampaignStatus Status { get; set; } = MetaCampaignStatus.Paused;
|
||||
}
|
||||
|
||||
public sealed class GetCampaignPayload
|
||||
{
|
||||
public string CampaignId { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class UpdateCampaignPayload
|
||||
{
|
||||
public string CampaignId { get; set; } = string.Empty;
|
||||
public string? Name { get; set; }
|
||||
public MetaCampaignStatus? Status { get; set; }
|
||||
public long? SpendCapCents { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ListCampaignsPayload
|
||||
{
|
||||
public MetaCampaignStatus? StatusFilter { get; set; }
|
||||
public int Limit { get; set; } = 50;
|
||||
public string? After { get; set; } // Cursor-based pagination
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ad Set Payloads
|
||||
|
||||
/// <summary>
|
||||
/// Create a Meta Ad Set (equivalent to Google Ad Group).
|
||||
/// Ad Sets define targeting, budget, schedule, and bid strategy.
|
||||
/// </summary>
|
||||
public sealed class CreateAdSetPayload
|
||||
{
|
||||
public string CampaignId { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Daily budget in account currency cents.</summary>
|
||||
public long DailyBudgetCents { get; set; }
|
||||
|
||||
/// <summary>Lifetime budget in cents (alternative to daily). Null = use daily.</summary>
|
||||
public long? LifetimeBudgetCents { get; set; }
|
||||
|
||||
public string? StartTime { get; set; } // ISO 8601
|
||||
public string? EndTime { get; set; } // ISO 8601
|
||||
|
||||
public MetaBillingEvent BillingEvent { get; set; } = MetaBillingEvent.Impressions;
|
||||
public MetaOptimizationGoal OptimizationGoal { get; set; } = MetaOptimizationGoal.LinkClicks;
|
||||
|
||||
/// <summary>Target CPA bid amount in cents (for CPA bidding).</summary>
|
||||
public long? BidAmountCents { get; set; }
|
||||
|
||||
public MetaCampaignStatus Status { get; set; } = MetaCampaignStatus.Paused;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ad Account Payloads
|
||||
|
||||
/// <summary>
|
||||
/// Create a new ad account under USIM's Business Manager.
|
||||
/// Requires Advanced Access to business_management permission.
|
||||
/// </summary>
|
||||
public sealed class CreateAdAccountPayload
|
||||
{
|
||||
/// <summary>Display name for the new ad account.</summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>Currency code (e.g. "USD"). ISO 4217.</summary>
|
||||
public string Currency { get; set; } = "USD";
|
||||
|
||||
/// <summary>Timezone (IANA format, e.g. "America/Los_Angeles"). Numeric TZ ID also accepted.</summary>
|
||||
public int TimezoneId { get; set; } = 1; // Default: America/Los_Angeles
|
||||
|
||||
/// <summary>End advertiser name/business for the account.</summary>
|
||||
public string? EndAdvertiser { get; set; }
|
||||
|
||||
/// <summary>Media agency managing the account.</summary>
|
||||
public string? MediaAgency { get; set; }
|
||||
|
||||
/// <summary>Partner (USIM).</summary>
|
||||
public string? Partner { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Insights Payloads
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve campaign performance metrics (Meta Insights API).
|
||||
/// </summary>
|
||||
public sealed class CampaignInsightsPayload
|
||||
{
|
||||
public string CampaignId { get; set; } = string.Empty;
|
||||
public string? DatePreset { get; set; } // e.g., "last_7d", "last_30d", "this_month"
|
||||
public string? StartDate { get; set; } // YYYY-MM-DD (time_range)
|
||||
public string? EndDate { get; set; } // YYYY-MM-DD (time_range)
|
||||
public string Level { get; set; } = "campaign"; // campaign, adset, ad
|
||||
}
|
||||
|
||||
public sealed class AccountInsightsPayload
|
||||
{
|
||||
public string? DatePreset { get; set; }
|
||||
public string? StartDate { get; set; }
|
||||
public string? EndDate { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Enums
|
||||
|
||||
/// <summary>
|
||||
/// Meta campaign objectives.
|
||||
/// As of API v25.0, Meta is consolidating to Outcome-Driven Ad Experiences (ODAX).
|
||||
/// These map to the Advantage+ unified campaign objectives.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum MetaObjective
|
||||
{
|
||||
/// <summary>OUTCOME_AWARENESS - Brand awareness and reach</summary>
|
||||
Awareness = 0,
|
||||
|
||||
/// <summary>OUTCOME_TRAFFIC - Drive traffic to a destination</summary>
|
||||
Traffic = 1,
|
||||
|
||||
/// <summary>OUTCOME_ENGAGEMENT - Get more engagement (likes, comments, shares)</summary>
|
||||
Engagement = 2,
|
||||
|
||||
/// <summary>OUTCOME_LEADS - Generate leads</summary>
|
||||
Leads = 3,
|
||||
|
||||
/// <summary>OUTCOME_APP_PROMOTION - Drive app installs</summary>
|
||||
AppPromotion = 4,
|
||||
|
||||
/// <summary>OUTCOME_SALES - Drive conversions/sales</summary>
|
||||
Conversions = 5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Meta campaign/ad set status values.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum MetaCampaignStatus
|
||||
{
|
||||
Active = 0,
|
||||
Paused = 1,
|
||||
Deleted = 2,
|
||||
Archived = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Meta billing events for ad sets.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum MetaBillingEvent
|
||||
{
|
||||
Impressions = 0,
|
||||
LinkClicks = 1,
|
||||
ThruPlay = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Meta optimization goals for ad sets.
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum MetaOptimizationGoal
|
||||
{
|
||||
None = 0,
|
||||
LinkClicks = 1,
|
||||
Impressions = 2,
|
||||
Reach = 3,
|
||||
LandingPageViews = 4,
|
||||
LeadGeneration = 5,
|
||||
Conversions = 6,
|
||||
Value = 7
|
||||
}
|
||||
|
||||
#endregion
|
||||
96
MetaApi/Models/ProviderModels.cs
Normal file
96
MetaApi/Models/ProviderModels.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MetaApi.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Request from Gateway to MetaApi.
|
||||
/// Identical contract to GoogleApi.Models.ProviderRequest for Gateway compatibility.
|
||||
/// </summary>
|
||||
public sealed class ProviderRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Operation to execute (e.g., "Ping", "CreateCampaign", "GetCampaignInsights")
|
||||
/// </summary>
|
||||
public string Operation { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Tenant/account ID - maps to Meta ad account ID (act_XXXXXXX).
|
||||
/// Populated by Gateway from tbAdAccount.accExternalAccountId where accNetwork='meta'.
|
||||
/// </summary>
|
||||
public string? TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Login customer ID - maps to Meta Business Manager ID.
|
||||
/// In Meta's agency model, the BM owns and manages client ad accounts.
|
||||
/// Populated by Gateway from tbAdAccount.accLoginAccountId.
|
||||
/// </summary>
|
||||
public string? LoginCustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Correlation ID for request tracing
|
||||
/// </summary>
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Operation-specific payload
|
||||
/// </summary>
|
||||
public JsonElement? Payload { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize payload to strongly-typed object
|
||||
/// </summary>
|
||||
public T GetPayload<T>() where T : new()
|
||||
{
|
||||
if (Payload == null || Payload.Value.ValueKind == JsonValueKind.Null || Payload.Value.ValueKind == JsonValueKind.Undefined)
|
||||
return new T();
|
||||
|
||||
try
|
||||
{
|
||||
return JsonSerializer.Deserialize<T>(Payload.Value.GetRawText(), JsonOptions.Default) ?? new T();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Response from MetaApi to Gateway.
|
||||
/// Identical contract to GoogleApi.Models.ProviderResponse.
|
||||
/// </summary>
|
||||
public sealed class ProviderResponse
|
||||
{
|
||||
public bool Ok { get; set; }
|
||||
public string? RequestId { get; set; }
|
||||
public object? Data { get; set; }
|
||||
public ProviderError? Error { get; set; }
|
||||
|
||||
public static ProviderResponse Success(string? requestId, object? data = null)
|
||||
=> new() { Ok = true, RequestId = requestId, Data = data };
|
||||
|
||||
public static ProviderResponse Fail(string? requestId, string code, string message, object? detail = null)
|
||||
=> new()
|
||||
{
|
||||
Ok = false,
|
||||
RequestId = requestId,
|
||||
Error = new ProviderError { Code = code, Message = message, Detail = detail }
|
||||
};
|
||||
}
|
||||
|
||||
public sealed class ProviderError
|
||||
{
|
||||
public string Code { get; set; } = "ERROR";
|
||||
public string Message { get; set; } = "Unknown error";
|
||||
public object? Detail { get; set; }
|
||||
}
|
||||
|
||||
internal static class JsonOptions
|
||||
{
|
||||
public static readonly JsonSerializerOptions Default = new(JsonSerializerDefaults.Web)
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user