open.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. using dodohold.core;
  2. using Sayaka.Common;
  3. using System.Text;
  4. using System.Text.RegularExpressions;
  5. using System.Web;
  6. namespace molilian.core
  7. {
  8. public partial class PddUnionPlus
  9. {
  10. static string _baseUrl = "https://gw-api.pinduoduo.com/api/router";
  11. public class ErrorResponse
  12. {
  13. public string error_msg { get; set; }
  14. public string sub_msg { get; set; }
  15. public string sub_code { get; set; }
  16. public int error_code { get; set; }
  17. public string request_id { get; set; }
  18. }
  19. public class GoodsZsUnitGenerateResponse
  20. {
  21. public string multi_group_mobile_short_url { get; set; }
  22. public string multi_group_url { get; set; }
  23. public string mobile_url { get; set; }
  24. public string multi_group_short_url { get; set; }
  25. public string mobile_short_url { get; set; }
  26. public string multi_group_mobile_url { get; set; }
  27. public string request_id { get; set; }
  28. public string url { get; set; }
  29. public string short_url { get; set; }
  30. }
  31. public class UnionGeneratelinkDTO
  32. {
  33. public GoodsZsUnitGenerateResponse goods_zs_unit_generate_response { get; set; }
  34. public ErrorResponse error_response { get; set; }
  35. }
  36. public class GoodsSearchItem
  37. {
  38. public long goods_id { get; set; }
  39. public string goods_sign { get; set; } = string.Empty;
  40. public string goods_name { get; set; } = string.Empty;
  41. }
  42. public class GoodsSearchResponse
  43. {
  44. public List<GoodsSearchItem> goods_list { get; set; } = [];
  45. public int total_count { get; set; }
  46. public string request_id { get; set; } = string.Empty;
  47. }
  48. public class GoodsSearchDTO
  49. {
  50. public GoodsSearchResponse? goods_search_response { get; set; }
  51. public ErrorResponse? error_response { get; set; }
  52. }
  53. public static Dictionary<string, string> GenerateSignature(PddPoolDTO account, Dictionary<string, string> args)
  54. {
  55. if (args.ContainsKey("sign")) args.Remove("sign");
  56. // 对参数进行ASCII升序排序
  57. var sortedArgs = args.OrderBy(kv => kv.Key).ToDictionary(kv => kv.Key, kv => kv.Value);
  58. // 拼接排序后的参数
  59. StringBuilder stringBuilder = new StringBuilder();
  60. foreach (var kv in sortedArgs)
  61. {
  62. stringBuilder.Append(kv.Key).Append(kv.Value);
  63. }
  64. // 在头部和尾部分别拼接client_secret
  65. string signString = account.app_secret + stringBuilder.ToString() + account.app_secret;
  66. signString = signString.MD5(false, false);
  67. if (!args.TryAdd("sign", signString))
  68. {
  69. args["sign"] = signString;
  70. }
  71. return args;
  72. }
  73. /// <summary>
  74. /// 多多进宝转链接口
  75. /// </summary>
  76. /// <param name="result"></param>
  77. /// <param name="sourceUrl"></param>
  78. /// <param name="cancellationToken"></param>
  79. /// <returns></returns>
  80. public async Task<PddDataDTO> UnionGeneratelink(PddDataDTO result, string sourceUrl, CancellationToken cancellationToken = default)
  81. {
  82. string api_type = "pdd.ddk.goods.zs.unit.url.gen";
  83. if (!string.IsNullOrEmpty(_account.access_token))
  84. {
  85. api_type = "pdd.ddk.oauth.goods.zs.unit.url.gen";
  86. }
  87. var ts = DateTime.Now.Convert2UnixTimestamp(true);
  88. var args = new Dictionary<string, string>
  89. {
  90. { "type",api_type},
  91. { "data_type", "JSON" },
  92. { "client_id", _account.app_key },
  93. { "access_token", _account.access_token },
  94. { "pid", _account.pid },
  95. { "source_url", sourceUrl },
  96. { "timestamp", ts.ToString() }
  97. };
  98. args = GenerateSignature(_account, args);
  99. var query = HttpUtility.ParseQueryString(string.Empty);
  100. foreach (var kvp in args) query[kvp.Key] = kvp.Value;
  101. string urlWithQuery = $"{_baseUrl}?{query}";
  102. WebClientUtility client = new();
  103. client.Proxy = _proxy;
  104. #if DEBUG
  105. client.Proxy = null;
  106. #endif
  107. client.SetContentType("application/json");
  108. var response = await client.RequestAsync(urlWithQuery, "GET", cancellationToken);
  109. //https://gw-api.pinduoduo.com/api/router?type=pdd.ddk.oauth.goods.zs.unit.url.gen&data_type=JSON&client_id=c8823690b47842649e4fee054317e0c1&access_token=5742da3542b94f86a29f1582e02cdfce76260f09&pid=41188561_292056956&source_url=https%3A%2F%2Fp.pinduoduo.com%2FbycsAB3L&timestamp=1725306430&sign=31EFD135B3530C639AAC32B9DFF1F2F4
  110. //https://gw-api.pinduoduo.com/api/router?type=pdd.ddk.goods.zs.unit.url.gen&data_type=JSON&client_id=c8823690b47842649e4fee054317e0c1&access_token=5742da3542b94f86a29f1582e02cdfce76260f09&pid=41188561_292056956&source_url=https%3a%2f%2fp.pinduoduo.com%2fbycsAB3L&timestamp=1725306278417&sign=72D2F327C0199AC68C1CF1136C14FA4B
  111. string body = response.Body();
  112. var root = body.Convert2Object<UnionGeneratelinkDTO>();
  113. string message = string.Empty;
  114. if (root.error_response != null || root.goods_zs_unit_generate_response == null)
  115. {
  116. message = $"{root.error_response.sub_code}:{root.error_response.sub_msg}";
  117. result.success = false;
  118. result.message = "转链失败";
  119. result.reason = message;
  120. _ = new LoggerLibrary("PddUnion", "UnionGeneratelink").Info(urlWithQuery, body).SaveAsync();
  121. if ("30007".Equals(root.error_response.sub_code))
  122. {
  123. PddPoolCore.AccountRisk(_account);
  124. }
  125. return result;
  126. }
  127. if (string.IsNullOrEmpty(root.goods_zs_unit_generate_response.url))
  128. {
  129. result.success = false;
  130. result.message = "转链失败";
  131. result.reason = "无法转链";
  132. _ = new LoggerLibrary("PddUnion", "UnionGeneratelink").Info(urlWithQuery, body).SaveAsync();
  133. return result;
  134. }
  135. result.itemId = root.goods_zs_unit_generate_response.url.GetContentPart("goods_id=", "&");
  136. if (string.IsNullOrEmpty(root.goods_zs_unit_generate_response.short_url))
  137. {
  138. result.success = false;
  139. result.message = "转链失败";
  140. result.reason = "链接无效";
  141. _ = new LoggerLibrary("PddUnion", "UnionGeneratelink").Info(urlWithQuery, body).SaveAsync();
  142. return result;
  143. }
  144. result.success = true;
  145. result.message = "OK";
  146. result.commercial = true;
  147. result.link_type = LinkTypeEnum.goods;
  148. result.shortLinkurl = root.goods_zs_unit_generate_response.short_url;
  149. result.content = result.shortLinkurl;
  150. result.deeplink_url = GetDeeplink(result.shortLinkurl);
  151. return result;
  152. }
  153. }
  154. }