327 lines
9.6 KiB
C#
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
|