tool_links.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using dodohold.core;
  2. using System.Diagnostics;
  3. using System.Text.Json;
  4. namespace molilian.core
  5. {
  6. public partial class AlimamaPlus
  7. {
  8. public async Task<TkDataDTO> endpoint_tool_links(string content, TkDataDTO result, CancellationToken cancellationToken = default)
  9. {
  10. string t = $"{DateTime.Now.Convert2UnixTimestamp(true)}";
  11. Random random = new();
  12. double randomNumber = random.NextDouble();
  13. string randomString = randomNumber.ToString()[2..];
  14. string cna = _cookies.GetContentPart("cna=", ";");
  15. string firstFiveCharacters = cna[..Math.Min(5, cna.Length)];
  16. var variableMap = new
  17. {
  18. url = content,
  19. union_lens = $"b_pvid:a219t._portal_v2_home_plus_index_htm_{t}_{randomString}_{firstFiveCharacters}_mmWuH",
  20. lensScene = "PUB",
  21. spmB = "_portal_v2_tool_links_page_home_index_htm"
  22. }.Convert2Json(true).UrlEncode();
  23. variableMap = variableMap.Replace(" ", "%20");
  24. _floorId = "61446";
  25. string url = "https://pub.alimama.com/openapi/param2/1/gateway.unionpub/xt.entry.json?" +
  26. $"t={t}&_tb_token_={_tb_token}&floorId={_floorId}&refpid={_refpid}&variableMap={variableMap}";
  27. Stopwatch stopwatch = Stopwatch.StartNew();
  28. stopwatch.Start();
  29. var client = new WebClientUtility().SetContentType("application/json;charset=utf-8")
  30. .AddHeaders("X-Requested-With", "XMLHttpRequest")
  31. .AddHeaders("Cookie", _cookies);
  32. client.Proxy = _proxy;
  33. #if DEBUG
  34. client.Proxy = null;
  35. #endif
  36. if (!string.IsNullOrEmpty(_user_agent)) client.UserAgent = _user_agent;
  37. client.Timeout = GetRequestTimeout2(result.elapsedTime2);
  38. //var response = client.Request(url);
  39. #if DEBUG
  40. var response = await client.RequestAsync(url, "GET");
  41. #else
  42. var response = await client.RequestAsync(url, "GET", cancellationToken);
  43. #endif
  44. stopwatch.Stop();
  45. result.elapsedTime3 = (int)stopwatch.ElapsedMilliseconds;
  46. var body = string.Empty;
  47. try
  48. {
  49. if (!response.Successed)
  50. {
  51. result.channel = TkChannelEnum.tb;
  52. result.link_type = LinkTypeEnum.unknown;
  53. result.success = false;
  54. result.message = "fail";
  55. if (response.ResponseException != null)
  56. {
  57. _ = new LoggerLibrary("api_error", "fail")
  58. .Info(response.ResponseException.Message, response.ResponseException.StackTrace)
  59. .SaveAsync();
  60. throw response.ResponseException;
  61. }
  62. return result;
  63. }
  64. if (response.ResponseMessage.StatusCode == System.Net.HttpStatusCode.Found)
  65. {
  66. _ = new LoggerLibrary("api_error", "fail")
  67. .Info($"302:{response.ResponseMessage.Headers.Location}")
  68. .SaveAsync();
  69. throw new Exception("302 Found, was canceled");
  70. }
  71. JsonElement root;
  72. try
  73. {
  74. body = response.Body();
  75. root = body.Convert2JsonElement();
  76. }
  77. catch (Exception ex)
  78. {
  79. _ = new LoggerLibrary("api_error", "fail")
  80. .Info(ex.Message, ex.StackTrace)
  81. .SaveAsync();
  82. if (body.Contains("https://g.alicdn.com/sd/punish/waf_block.html"))
  83. {
  84. await TkEndpointManager.SuspendAsync(_accountId, "tool_links", TkEndpointManager.SuspendReason.Passive);
  85. result.channel = TkChannelEnum.tb;
  86. result.link_type = LinkTypeEnum.unknown;
  87. result.success = false;
  88. result.message = "waf_block";
  89. return result;
  90. }
  91. if (body.Contains("https://bixi.alicdn.com") && body.Contains("\"action\": \"deny\""))
  92. {
  93. await TkEndpointManager.SuspendAsync(_accountId, "tool_links", TkEndpointManager.SuspendReason.Passive);
  94. result.channel = TkChannelEnum.tb;
  95. result.link_type = LinkTypeEnum.unknown;
  96. result.subCode = TkSubCodeEnum.ParseDeny;
  97. result.success = false;
  98. result.message = "waf_block";
  99. result.reason = "接口风控";
  100. return result;
  101. }
  102. throw new Exception(body);
  103. }
  104. if (body.Contains("https://bixi.alicdn.com") && body.Contains("\"action\": \"deny\""))
  105. {
  106. await TkEndpointManager.SuspendAsync(_accountId, "tool_links", TkEndpointManager.SuspendReason.Passive);
  107. result.channel = TkChannelEnum.tb;
  108. result.link_type = LinkTypeEnum.unknown;
  109. result.subCode = TkSubCodeEnum.ParseDeny;
  110. result.success = false;
  111. result.message = "waf_block";
  112. result.reason = "接口风控";
  113. return result;
  114. }
  115. bool success = root.Read<bool>("success", false);
  116. string message = root.Read("message", string.Empty);
  117. string info_message = root.PathRead("info.message", string.Empty);
  118. if (!string.IsNullOrEmpty(info_message)) message = info_message;
  119. string taoToken = root.PathRead("data.taoToken", string.Empty);
  120. string shortLinkurl = root.PathRead("data.shortLinkurl", string.Empty);
  121. string couponLinkTaoToken = root.PathRead("data.couponLinkTaoToken", string.Empty);
  122. string couponShortLinkUrl = root.PathRead("data.couponShortLinkUrl", string.Empty);
  123. decimal couponAmount = root.PathRead<decimal>("data.couponAmount", 0);
  124. string couponEffectiveEndTime = root.PathRead("data.couponEffectiveEndTime", string.Empty);
  125. string couponEffectiveStartTime = root.PathRead("data.couponEffectiveStartTime", string.Empty);
  126. string itemId = root.PathRead("data.itemId", string.Empty);
  127. string mktId = root.PathRead("data.outputMktId", string.Empty);
  128. string itemName = root.PathRead("data.itemName", string.Empty);
  129. decimal promotionPrice = root.PathRead<decimal>("data.promotionPrice", 0);
  130. string sellerNickName = root.PathRead("data.sellerNickName", string.Empty);
  131. string shopTitle = root.PathRead("data.shopTitle", string.Empty);
  132. string pic = root.PathRead("data.pic", string.Empty);
  133. if (pic.StartsWith("//")) pic = "https:" + pic;
  134. string qrCodeUrl = root.PathRead("data.qrCodeUrl", string.Empty);
  135. if (response.ResponseMessage != null)
  136. {
  137. switch (response.ResponseMessage.StatusCode)
  138. {
  139. case System.Net.HttpStatusCode.OK:
  140. {
  141. if (couponAmount > 0 && !string.IsNullOrEmpty(couponLinkTaoToken) && !string.IsNullOrEmpty(couponShortLinkUrl))
  142. {
  143. taoToken = couponLinkTaoToken;
  144. shortLinkurl = couponShortLinkUrl;
  145. }
  146. string shortLink = GetLink(taoToken);
  147. content = ReplaceUrls(content, shortLink);
  148. }
  149. break;
  150. case System.Net.HttpStatusCode.Found:
  151. string location = response.ResponseMessage.Headers.Location.OriginalString;
  152. if (!string.IsNullOrEmpty(location) && location.Contains("www.alimama.com/member/login.htm"))
  153. {
  154. success = false;
  155. message = "nologin";
  156. }
  157. break;
  158. default:
  159. {
  160. success = false;
  161. message = "other";
  162. }
  163. break;
  164. }
  165. }
  166. if (!success)
  167. {
  168. shortLinkurl = GetLink(content);
  169. switch (message)
  170. {
  171. case "该商品已经下架或未加入淘宝客":
  172. case "该链接不支持转化,请更换链接尝试":
  173. result.subCode = TkSubCodeEnum.NoConvert;
  174. break;
  175. case "网络错误":
  176. result.subCode = TkSubCodeEnum.NetError;
  177. break;
  178. default:
  179. var _headers = response.ResponseMessage.Headers;
  180. var headers = "";
  181. foreach (var h in _headers)
  182. {
  183. foreach (var Value in h.Value)
  184. {
  185. headers += $"{h.Key}: {Value}\n";
  186. }
  187. }
  188. _ = new LoggerLibrary("api_error", "fail")
  189. .Info(message, content)
  190. .Info(headers, body)
  191. .SaveAsync();
  192. break;
  193. }
  194. }
  195. shortLinkurl = GetLink(taoToken);
  196. string deeplink_url = GetDeeplink(shortLinkurl);
  197. result.channel = TkChannelEnum.tb;
  198. if (success)
  199. {
  200. result.subCode = TkSubCodeEnum.Success;
  201. switch (result.link_type)
  202. {
  203. case LinkTypeEnum.profile:
  204. case LinkTypeEnum.goods:
  205. case LinkTypeEnum.video:
  206. case LinkTypeEnum.live:
  207. break;
  208. default:
  209. result.link_type = LinkTypeEnum.goods;
  210. break;
  211. }
  212. }
  213. result.success = success;
  214. result.message = message;
  215. result.reason = string.Empty;
  216. result.content = content;
  217. result.couponAmount = couponAmount;
  218. result.couponEffectiveEndTime = couponEffectiveEndTime;
  219. result.couponEffectiveStartTime = couponEffectiveStartTime;
  220. result.taoToken = taoToken;
  221. if (!string.IsNullOrEmpty(shortLinkurl))
  222. {
  223. result.shortLinkurl = shortLinkurl;
  224. result.deeplink_url = deeplink_url;
  225. }
  226. result.mktId = mktId;
  227. result.itemId = itemId;
  228. result.itemName = itemName;
  229. result.promotionPrice = promotionPrice;
  230. result.sellerNickName = sellerNickName;
  231. result.shopTitle = shopTitle;
  232. result.pic = pic;
  233. result.qrCodeUrl = qrCodeUrl;
  234. }
  235. catch (Exception ex)
  236. {
  237. if (response.ResponseMessage?.StatusCode == System.Net.HttpStatusCode.OK)
  238. {
  239. if (body.Contains("<p>抱歉!页面无法访问……</p>"))
  240. {
  241. throw new APIException("抱歉!页面无法访问……");
  242. }
  243. }
  244. throw;
  245. }
  246. return result;
  247. }
  248. }
  249. }