TbkDgGeneralLinkParse.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using dodohold.core;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Xml.Serialization;
  5. using Top.Api;
  6. using Top.Api.Request;
  7. using Top.Api.Response;
  8. using Top.Api.Util;
  9. namespace molilian.core
  10. {
  11. public partial class TaobaoOpenPlus
  12. {
  13. /// <summary>
  14. /// 万能解析:解析淘宝链接或淘口令,返回物料类型、物料ID及原始链接。
  15. /// </summary>
  16. /// <param name="materialUrl">待解析的链接或淘口令。</param>
  17. /// <param name="relationId">可选的渠道管理ID。</param>
  18. /// <param name="fields">可选返回字段,例如 origin_pid。</param>
  19. public TbkDgGeneralLinkParseResponse GeneralLinkParseRequest(
  20. string materialUrl, string? relationId = null, string? fields = null)
  21. {
  22. ArgumentException.ThrowIfNullOrWhiteSpace(materialUrl);
  23. return GeneralLinkParseRequest(new[] { materialUrl }, relationId, fields);
  24. }
  25. /// <summary>
  26. /// 批量解析淘宝链接或淘口令,每个物料的解析结果独立返回。
  27. /// </summary>
  28. public TbkDgGeneralLinkParseResponse GeneralLinkParseRequest(
  29. IEnumerable<string> materialUrls, string? relationId = null, string? fields = null)
  30. {
  31. ArgumentNullException.ThrowIfNull(materialUrls);
  32. List<TbkDgGeneralLinkParseRequest.LkMaterialDtoDomain> materials = new();
  33. foreach (string materialUrl in materialUrls)
  34. {
  35. if (string.IsNullOrWhiteSpace(materialUrl))
  36. {
  37. throw new ArgumentException("materialUrls cannot contain empty values", nameof(materialUrls));
  38. }
  39. materials.Add(new TbkDgGeneralLinkParseRequest.LkMaterialDtoDomain
  40. {
  41. MaterialUrl = materialUrl
  42. });
  43. }
  44. if (materials.Count == 0)
  45. {
  46. throw new ArgumentException("at least one material URL is required", nameof(materialUrls));
  47. }
  48. if (string.IsNullOrWhiteSpace(_pid))
  49. {
  50. throw new ArgumentException("pid is required", nameof(_pid));
  51. }
  52. string[] pidParts = _pid.Split('_');
  53. if (pidParts.Length != 4 || pidParts[0] != "mm" ||
  54. string.IsNullOrWhiteSpace(pidParts[1]) || string.IsNullOrWhiteSpace(pidParts[2]) ||
  55. !long.TryParse(pidParts[3], out long adzoneId) || adzoneId <= 0)
  56. {
  57. throw new ArgumentException("pid format is invalid", nameof(_pid));
  58. }
  59. var client = new DefaultTopClient(_server_url, _app_key, _app_secret, "json");
  60. client.SetProxy(_proxy);
  61. TbkDgGeneralLinkParseRequest req = new()
  62. {
  63. AdzoneId = adzoneId,
  64. MaterialDto_ = materials,
  65. RelationId = relationId,
  66. Fields = fields
  67. };
  68. TbkDgGeneralLinkParseResponse rsp = client.Execute(req);
  69. if (_debug)
  70. {
  71. var requestJson = req.Convert2Json();
  72. var responseJson = rsp.Convert2Json();
  73. new LoggerLibrary("debug", _pid).Info(requestJson, responseJson).Save();
  74. }
  75. return rsp;
  76. }
  77. }
  78. }
  79. namespace Top.Api.Request
  80. {
  81. /// <summary>
  82. /// TOP API: taobao.tbk.dg.general.link.parse
  83. /// </summary>
  84. public class TbkDgGeneralLinkParseRequest : BaseTopRequest<TbkDgGeneralLinkParseResponse>
  85. {
  86. /// <summary>
  87. /// 推广位ID,mm_xx_xx_xx 中的最后一段。
  88. /// </summary>
  89. public long? AdzoneId { get; set; }
  90. /// <summary>
  91. /// 渠道管理ID。
  92. /// </summary>
  93. public string? RelationId { get; set; }
  94. /// <summary>
  95. /// 链接/口令物料列表的JSON数组。
  96. /// </summary>
  97. public string MaterialDto { get; set; } = string.Empty;
  98. public List<LkMaterialDtoDomain> MaterialDto_
  99. {
  100. set { MaterialDto = TopUtils.ObjectToJson(value); }
  101. }
  102. /// <summary>
  103. /// 可选返回字段,有 origin_pid 使用场景时传入 origin_pid。
  104. /// </summary>
  105. public string? Fields { get; set; }
  106. public override string GetApiName()
  107. {
  108. return "taobao.tbk.dg.general.link.parse";
  109. }
  110. public override IDictionary<string, string> GetParameters()
  111. {
  112. TopDictionary parameters = new();
  113. parameters.Add("adzone_id", AdzoneId?.ToString());
  114. parameters.Add("relation_id", RelationId);
  115. parameters.Add("material_dto", MaterialDto);
  116. parameters.Add("fields", Fields);
  117. return parameters;
  118. }
  119. public override void Validate()
  120. {
  121. RequestValidator.ValidateRequired("adzone_id", AdzoneId);
  122. }
  123. [Serializable]
  124. public class LkMaterialDtoDomain : TopObject
  125. {
  126. /// <summary>
  127. /// 物料链接,可以为URL或淘口令。
  128. /// </summary>
  129. [XmlElement("material_url")]
  130. public string MaterialUrl { get; set; } = string.Empty;
  131. }
  132. }
  133. }
  134. namespace Top.Api.Response
  135. {
  136. /// <summary>
  137. /// 淘宝客-推广者-万能解析响应。
  138. /// </summary>
  139. public class TbkDgGeneralLinkParseResponse : TopResponse
  140. {
  141. [XmlElement("data")]
  142. public TbkLinkDtoDomain? Data { get; set; }
  143. /// <summary>
  144. /// 业务错误码。
  145. /// </summary>
  146. [XmlElement("biz_error_desc")]
  147. public long BizErrorDesc { get; set; }
  148. /// <summary>
  149. /// 业务结果描述。
  150. /// </summary>
  151. [XmlElement("result_msg")]
  152. public string ResultMsg { get; set; } = string.Empty;
  153. [Serializable]
  154. public class TbkLinkDtoDomain : TopObject
  155. {
  156. [XmlArray("material_url_list")]
  157. [XmlArrayItem("material_url_list")]
  158. public List<MaterialUrlListDomain> MaterialUrlList { get; set; } = new();
  159. }
  160. [Serializable]
  161. public class MaterialUrlListDomain : TopObject
  162. {
  163. /// <summary>
  164. /// 物料对应错误描述。
  165. /// </summary>
  166. [XmlElement("msg")]
  167. public string Msg { get; set; } = string.Empty;
  168. /// <summary>
  169. /// 物料对应错误码,需逐项检查解析结果。
  170. /// </summary>
  171. [XmlElement("code")]
  172. public long Code { get; set; }
  173. [XmlElement("link_info_dto")]
  174. public LinkInfoDtoDomain? LinkInfoDto { get; set; }
  175. /// <summary>
  176. /// 入参物料链接。
  177. /// </summary>
  178. [XmlElement("input_material_url")]
  179. public string InputMaterialUrl { get; set; } = string.Empty;
  180. /// <summary>
  181. /// 解析成功时的补充说明。
  182. /// </summary>
  183. [XmlElement("extra_info")]
  184. public string ExtraInfo { get; set; } = string.Empty;
  185. }
  186. [Serializable]
  187. public class LinkInfoDtoDomain : TopObject
  188. {
  189. /// <summary>
  190. /// 1-商品,2-店铺,3-会场,4-承接开放,5-优惠券,6-直播间。
  191. /// </summary>
  192. [XmlElement("material_type")]
  193. public long MaterialType { get; set; }
  194. /// <summary>
  195. /// 入参口令/链接对应的原链接。
  196. /// </summary>
  197. [XmlElement("tpwd_origin_url")]
  198. public string TpwdOriginUrl { get; set; } = string.Empty;
  199. /// <summary>
  200. /// 物料ID,根据物料类型区分商品ID、卖家ID或会场ID。
  201. /// </summary>
  202. [XmlElement("material_id")]
  203. public string MaterialId { get; set; } = string.Empty;
  204. /// <summary>
  205. /// 1-联盟口令,2-主站口令;非淘口令场景不返回。
  206. /// </summary>
  207. [XmlElement("tk_biz_type")]
  208. public long TkBizType { get; set; }
  209. /// <summary>
  210. /// 入参推广链接中的PID,需传入 fields=origin_pid,且属于当前推广者才返回。
  211. /// </summary>
  212. [XmlElement("origin_pid")]
  213. public string OriginPid { get; set; } = string.Empty;
  214. }
  215. }
  216. }