Files
AdPlatform-Server/TikTokApi/Models/OperationPayloads.cs
2026-03-14 13:50:09 -07:00

327 lines
9.6 KiB
C#

using System.Text.Json.Serialization;
namespace TikTokApi.Models;
#region Campaign Payloads
/// <summary>
/// Create a TikTok campaign.
/// TikTok hierarchy: Campaign → Ad Group → Ad (same as Google, unlike Meta's Ad Set).
/// Campaign sets the objective and budget type.
/// </summary>
public sealed class CreateCampaignPayload
{
public string Name { get; set; } = string.Empty;
public TikTokObjective Objective { get; set; } = TikTokObjective.Traffic;
/// <summary>
/// Budget mode. TikTok supports BUDGET_MODE_DAY and BUDGET_MODE_TOTAL at campaign level.
/// </summary>
public TikTokBudgetMode BudgetMode { get; set; } = TikTokBudgetMode.Day;
/// <summary>
/// Budget amount in account currency (float, e.g., 50.00).
/// Minimum varies by country (typically $50/day for campaign-level budget).
/// Null = no campaign budget (budget set at ad group level).
/// </summary>
public decimal? Budget { get; set; }
/// <summary>
/// Special industry categories: HOUSING, CREDIT, EMPLOYMENT.
/// Empty = none (most campaigns).
/// </summary>
public List<string> SpecialIndustries { get; set; } = new();
public TikTokCampaignStatus Status { get; set; } = TikTokCampaignStatus.Disable;
}
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 TikTokCampaignStatus? Status { get; set; }
public decimal? Budget { get; set; }
}
public sealed class ListCampaignsPayload
{
/// <summary>
/// Filter by status. Null = return all.
/// TikTok supports filtering by multiple statuses.
/// </summary>
public TikTokCampaignStatus? StatusFilter { get; set; }
public int PageSize { get; set; } = 50;
public int Page { get; set; } = 1;
}
#endregion
#region Ad Group Payloads
/// <summary>
/// Create a TikTok Ad Group (equivalent to Google Ad Group / Meta Ad Set).
/// Ad Groups define targeting, budget, schedule, placement, and bid strategy.
/// </summary>
public sealed class CreateAdGroupPayload
{
public string CampaignId { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
/// <summary>Budget amount in account currency (float).</summary>
public decimal Budget { get; set; }
public TikTokBudgetMode BudgetMode { get; set; } = TikTokBudgetMode.Day;
/// <summary>Schedule start time in UTC (ISO 8601 / "yyyy-MM-dd HH:mm:ss").</summary>
public string? ScheduleStartTime { get; set; }
/// <summary>Schedule end time in UTC. Null = no end date.</summary>
public string? ScheduleEndTime { get; set; }
public TikTokOptimizationGoal OptimizationGoal { get; set; } = TikTokOptimizationGoal.Click;
public TikTokBillingEvent BillingEvent { get; set; } = TikTokBillingEvent.CPC;
/// <summary>Bid amount in account currency. Required for non-auto-bid strategies.</summary>
public decimal? BidPrice { get; set; }
/// <summary>
/// Placement: list of placements. Default = automatic (PLACEMENT_TYPE_AUTOMATIC).
/// Options: PLACEMENT_TIKTOK, PLACEMENT_PANGLE, PLACEMENT_GLOBALAPP_BUNDLE
/// </summary>
public List<string> Placements { get; set; } = new();
/// <summary>Target location codes (country/region codes).</summary>
public List<string> LocationIds { get; set; } = new();
public TikTokCampaignStatus Status { get; set; } = TikTokCampaignStatus.Disable;
}
#endregion
#region Ad Account (Advertiser) Payloads
/// <summary>
/// Create a new advertiser account under USIM's Business Center.
/// Endpoint: POST /bc/advertiser/create
/// Requires BC admin access.
/// </summary>
public sealed class CreateAdvertiserPayload
{
/// <summary>Display name for the new advertiser 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 string. TikTok uses Olson/IANA format.
/// e.g., "America/Los_Angeles", "UTC", "Europe/London"
/// </summary>
public string Timezone { get; set; } = "America/Los_Angeles";
/// <summary>Advertiser's company name.</summary>
public string Company { get; set; } = string.Empty;
/// <summary>Industry ID. Use /tool/industry/ endpoint to get valid IDs.</summary>
public string? IndustryId { get; set; }
/// <summary>Advertiser's contact email.</summary>
public string? ContactEmail { get; set; }
/// <summary>Advertiser's contact phone number.</summary>
public string? ContactPhone { get; set; }
}
/// <summary>
/// List advertiser accounts under the Business Center.
/// Endpoint: GET /bc/advertiser/get
/// </summary>
public sealed class ListAdvertisersPayload
{
public int PageSize { get; set; } = 50;
public int Page { get; set; } = 1;
}
#endregion
#region Insights / Reporting Payloads
/// <summary>
/// Retrieve campaign/ad group/ad performance metrics.
/// TikTok Reporting API: POST /report/integrated/get/
/// </summary>
public sealed class ReportPayload
{
/// <summary>
/// Report type: BASIC, AUDIENCE, PLAYABLE_MATERIAL, CATALOG
/// </summary>
public string ReportType { get; set; } = "BASIC";
/// <summary>
/// Data level: AUCTION_CAMPAIGN, AUCTION_ADGROUP, AUCTION_AD
/// </summary>
public string DataLevel { get; set; } = "AUCTION_CAMPAIGN";
/// <summary>
/// Dimensions to group by (e.g., ["campaign_id", "stat_time_day"]).
/// </summary>
public List<string> Dimensions { get; set; } = new() { "campaign_id", "stat_time_day" };
/// <summary>
/// Metrics to query (e.g., ["spend", "impressions", "clicks", "cpc", "ctr"]).
/// </summary>
public List<string> Metrics { get; set; } = new() { "spend", "impressions", "clicks", "cpc", "ctr", "cpm" };
/// <summary>Start date in format "YYYY-MM-DD".</summary>
public string? StartDate { get; set; }
/// <summary>End date in format "YYYY-MM-DD".</summary>
public string? EndDate { get; set; }
/// <summary>Use lifetime stats instead of date range.</summary>
public bool Lifetime { get; set; } = false;
/// <summary>
/// Filters (e.g., [{"field_name":"campaign_ids","filter_type":"IN","filter_value":"[\"123\"]"}]).
/// </summary>
public List<ReportFilter>? Filters { get; set; }
public int PageSize { get; set; } = 50;
public int Page { get; set; } = 1;
}
public sealed class ReportFilter
{
public string FieldName { get; set; } = string.Empty;
public string FilterType { get; set; } = "IN";
public string FilterValue { get; set; } = string.Empty;
}
#endregion
#region Fund Management Payloads
/// <summary>
/// Transfer funds to/from an advertiser account in the Business Center.
/// Endpoint: POST /bc/transfer/
/// This is a unique TikTok feature — direct fund management via API.
/// </summary>
public sealed class TransferFundsPayload
{
/// <summary>Target advertiser account ID.</summary>
public string AdvertiserId { get; set; } = string.Empty;
/// <summary>Transfer type: "RECHARGE" (add funds) or "DEDUCT" (remove funds).</summary>
public string TransferType { get; set; } = "RECHARGE";
/// <summary>Amount to transfer in account currency.</summary>
public decimal Amount { get; set; }
}
#endregion
#region Enums
/// <summary>
/// TikTok campaign objectives.
/// See: https://business-api.tiktok.com/portal/docs?id=1739381516454913
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TikTokObjective
{
/// <summary>REACH - Maximize ad reach</summary>
Reach = 0,
/// <summary>TRAFFIC - Drive traffic to website/app</summary>
Traffic = 1,
/// <summary>VIDEO_VIEWS - Maximize video views</summary>
VideoViews = 2,
/// <summary>LEAD_GENERATION - Collect leads via instant forms</summary>
LeadGeneration = 3,
/// <summary>COMMUNITY_INTERACTION - Grow followers and profile visits</summary>
CommunityInteraction = 4,
/// <summary>APP_PROMOTION - Drive app installs/re-engagement</summary>
AppPromotion = 5,
/// <summary>WEB_CONVERSIONS - Drive website conversions</summary>
WebConversions = 6,
/// <summary>PRODUCT_SALES - Drive catalog/shop sales</summary>
ProductSales = 7
}
/// <summary>
/// TikTok campaign/ad group status values.
/// TikTok uses ENABLE/DISABLE rather than ACTIVE/PAUSED.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TikTokCampaignStatus
{
/// <summary>ENABLE - Running/active</summary>
Enable = 0,
/// <summary>DISABLE - Paused</summary>
Disable = 1,
/// <summary>DELETE - Soft-deleted</summary>
Delete = 2
}
/// <summary>
/// TikTok budget modes.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TikTokBudgetMode
{
/// <summary>BUDGET_MODE_DAY - Daily budget</summary>
Day = 0,
/// <summary>BUDGET_MODE_TOTAL - Lifetime/total budget</summary>
Total = 1,
/// <summary>BUDGET_MODE_INFINITE - No budget limit (budget at ad group level)</summary>
Infinite = 2
}
/// <summary>
/// TikTok billing events for ad groups.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TikTokBillingEvent
{
CPC = 0,
CPM = 1,
CPV = 2,
OCPM = 3
}
/// <summary>
/// TikTok optimization goals for ad groups.
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum TikTokOptimizationGoal
{
Click = 0,
Impression = 1,
Reach = 2,
VideoView = 3,
Landing_Page_View = 4,
Lead_Generation = 5,
Convert = 6,
Install = 7,
Value = 8
}
#endregion