|
|
@@ -0,0 +1,249 @@
|
|
|
+using dodohold.core;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Xml.Serialization;
|
|
|
+using Top.Api;
|
|
|
+using Top.Api.Request;
|
|
|
+using Top.Api.Response;
|
|
|
+using Top.Api.Util;
|
|
|
+
|
|
|
+namespace molilian.core
|
|
|
+{
|
|
|
+ public partial class TaobaoOpenPlus
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 万能解析:解析淘宝链接或淘口令,返回物料类型、物料ID及原始链接。
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="materialUrl">待解析的链接或淘口令。</param>
|
|
|
+ /// <param name="relationId">可选的渠道管理ID。</param>
|
|
|
+ /// <param name="fields">可选返回字段,例如 origin_pid。</param>
|
|
|
+ public TbkDgGeneralLinkParseResponse GeneralLinkParseRequest(
|
|
|
+ string materialUrl, string? relationId = null, string? fields = null)
|
|
|
+ {
|
|
|
+ ArgumentException.ThrowIfNullOrWhiteSpace(materialUrl);
|
|
|
+ return GeneralLinkParseRequest(new[] { materialUrl }, relationId, fields);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 批量解析淘宝链接或淘口令,每个物料的解析结果独立返回。
|
|
|
+ /// </summary>
|
|
|
+ public TbkDgGeneralLinkParseResponse GeneralLinkParseRequest(
|
|
|
+ IEnumerable<string> materialUrls, string? relationId = null, string? fields = null)
|
|
|
+ {
|
|
|
+ ArgumentNullException.ThrowIfNull(materialUrls);
|
|
|
+
|
|
|
+ List<TbkDgGeneralLinkParseRequest.LkMaterialDtoDomain> materials = new();
|
|
|
+ foreach (string materialUrl in materialUrls)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(materialUrl))
|
|
|
+ {
|
|
|
+ throw new ArgumentException("materialUrls cannot contain empty values", nameof(materialUrls));
|
|
|
+ }
|
|
|
+
|
|
|
+ materials.Add(new TbkDgGeneralLinkParseRequest.LkMaterialDtoDomain
|
|
|
+ {
|
|
|
+ MaterialUrl = materialUrl
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (materials.Count == 0)
|
|
|
+ {
|
|
|
+ throw new ArgumentException("at least one material URL is required", nameof(materialUrls));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (string.IsNullOrWhiteSpace(_pid))
|
|
|
+ {
|
|
|
+ throw new ArgumentException("pid is required", nameof(_pid));
|
|
|
+ }
|
|
|
+
|
|
|
+ string[] pidParts = _pid.Split('_');
|
|
|
+ if (pidParts.Length != 4 || pidParts[0] != "mm" ||
|
|
|
+ string.IsNullOrWhiteSpace(pidParts[1]) || string.IsNullOrWhiteSpace(pidParts[2]) ||
|
|
|
+ !long.TryParse(pidParts[3], out long adzoneId) || adzoneId <= 0)
|
|
|
+ {
|
|
|
+ throw new ArgumentException("pid format is invalid", nameof(_pid));
|
|
|
+ }
|
|
|
+
|
|
|
+ var client = new DefaultTopClient(_server_url, _app_key, _app_secret, "json");
|
|
|
+ client.SetProxy(_proxy);
|
|
|
+
|
|
|
+ TbkDgGeneralLinkParseRequest req = new()
|
|
|
+ {
|
|
|
+ AdzoneId = adzoneId,
|
|
|
+ MaterialDto_ = materials,
|
|
|
+ RelationId = relationId,
|
|
|
+ Fields = fields
|
|
|
+ };
|
|
|
+
|
|
|
+ TbkDgGeneralLinkParseResponse rsp = client.Execute(req);
|
|
|
+ if (_debug)
|
|
|
+ {
|
|
|
+ var requestJson = req.Convert2Json();
|
|
|
+ var responseJson = rsp.Convert2Json();
|
|
|
+ new LoggerLibrary("debug", _pid).Info(requestJson, responseJson).Save();
|
|
|
+ }
|
|
|
+ return rsp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+namespace Top.Api.Request
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// TOP API: taobao.tbk.dg.general.link.parse
|
|
|
+ /// </summary>
|
|
|
+ public class TbkDgGeneralLinkParseRequest : BaseTopRequest<TbkDgGeneralLinkParseResponse>
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 推广位ID,mm_xx_xx_xx 中的最后一段。
|
|
|
+ /// </summary>
|
|
|
+ public long? AdzoneId { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 渠道管理ID。
|
|
|
+ /// </summary>
|
|
|
+ public string? RelationId { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 链接/口令物料列表的JSON数组。
|
|
|
+ /// </summary>
|
|
|
+ public string MaterialDto { get; set; } = string.Empty;
|
|
|
+
|
|
|
+ public List<LkMaterialDtoDomain> MaterialDto_
|
|
|
+ {
|
|
|
+ set { MaterialDto = TopUtils.ObjectToJson(value); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 可选返回字段,有 origin_pid 使用场景时传入 origin_pid。
|
|
|
+ /// </summary>
|
|
|
+ public string? Fields { get; set; }
|
|
|
+
|
|
|
+ public override string GetApiName()
|
|
|
+ {
|
|
|
+ return "taobao.tbk.dg.general.link.parse";
|
|
|
+ }
|
|
|
+
|
|
|
+ public override IDictionary<string, string> GetParameters()
|
|
|
+ {
|
|
|
+ TopDictionary parameters = new();
|
|
|
+ parameters.Add("adzone_id", AdzoneId?.ToString());
|
|
|
+ parameters.Add("relation_id", RelationId);
|
|
|
+ parameters.Add("material_dto", MaterialDto);
|
|
|
+ parameters.Add("fields", Fields);
|
|
|
+ return parameters;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void Validate()
|
|
|
+ {
|
|
|
+ RequestValidator.ValidateRequired("adzone_id", AdzoneId);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ public class LkMaterialDtoDomain : TopObject
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 物料链接,可以为URL或淘口令。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("material_url")]
|
|
|
+ public string MaterialUrl { get; set; } = string.Empty;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+namespace Top.Api.Response
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 淘宝客-推广者-万能解析响应。
|
|
|
+ /// </summary>
|
|
|
+ public class TbkDgGeneralLinkParseResponse : TopResponse
|
|
|
+ {
|
|
|
+ [XmlElement("data")]
|
|
|
+ public TbkLinkDtoDomain? Data { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 业务错误码。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("biz_error_desc")]
|
|
|
+ public long BizErrorDesc { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 业务结果描述。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("result_msg")]
|
|
|
+ public string ResultMsg { get; set; } = string.Empty;
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ public class TbkLinkDtoDomain : TopObject
|
|
|
+ {
|
|
|
+ [XmlArray("material_url_list")]
|
|
|
+ [XmlArrayItem("material_url_list")]
|
|
|
+ public List<MaterialUrlListDomain> MaterialUrlList { get; set; } = new();
|
|
|
+ }
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ public class MaterialUrlListDomain : TopObject
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 物料对应错误描述。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("msg")]
|
|
|
+ public string Msg { get; set; } = string.Empty;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 物料对应错误码,需逐项检查解析结果。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("code")]
|
|
|
+ public long Code { get; set; }
|
|
|
+
|
|
|
+ [XmlElement("link_info_dto")]
|
|
|
+ public LinkInfoDtoDomain? LinkInfoDto { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 入参物料链接。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("input_material_url")]
|
|
|
+ public string InputMaterialUrl { get; set; } = string.Empty;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 解析成功时的补充说明。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("extra_info")]
|
|
|
+ public string ExtraInfo { get; set; } = string.Empty;
|
|
|
+ }
|
|
|
+
|
|
|
+ [Serializable]
|
|
|
+ public class LinkInfoDtoDomain : TopObject
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 1-商品,2-店铺,3-会场,4-承接开放,5-优惠券,6-直播间。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("material_type")]
|
|
|
+ public long MaterialType { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 入参口令/链接对应的原链接。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("tpwd_origin_url")]
|
|
|
+ public string TpwdOriginUrl { get; set; } = string.Empty;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 物料ID,根据物料类型区分商品ID、卖家ID或会场ID。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("material_id")]
|
|
|
+ public string MaterialId { get; set; } = string.Empty;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 1-联盟口令,2-主站口令;非淘口令场景不返回。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("tk_biz_type")]
|
|
|
+ public long TkBizType { get; set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 入参推广链接中的PID,需传入 fields=origin_pid,且属于当前推广者才返回。
|
|
|
+ /// </summary>
|
|
|
+ [XmlElement("origin_pid")]
|
|
|
+ public string OriginPid { get; set; } = string.Empty;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|