UnionParseCore.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc.Controllers;
  3. using Microsoft.AspNetCore.Mvc.Filters;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using dodohold.core;
  9. using Spire.Pdf.Exporting.XPS.Schema;
  10. using System.Xml.Linq;
  11. using System.Net;
  12. using TencentCloud.Mrs.V20200910.Models;
  13. using Microsoft.AspNetCore.Mvc;
  14. using Microsoft.AspNetCore.Authentication;
  15. using Spire.Pdf.Graphics;
  16. using Google.Protobuf.WellKnownTypes;
  17. using TencentCloud.Tcm.V20210413.Models;
  18. using System.Diagnostics;
  19. using System.Threading;
  20. using TencentCloud.Soe.V20180724.Models;
  21. using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
  22. using System.Runtime.Intrinsics.Arm;
  23. using ZstdSharp.Unsafe;
  24. using System.Text.RegularExpressions;
  25. using static dodohold.core.ZTOExpress.CreateOrderArgs;
  26. using System.Security.Cryptography;
  27. using System.Threading.Channels;
  28. namespace molilian.core
  29. {
  30. public partial class UnionParseCore
  31. {
  32. public static async Task<ActionResult> UnionParseAsync(string content, string channel, int commerceType, string ip, string oaid, int accountid = 0)
  33. {
  34. content = content.Trim();
  35. return channel switch
  36. {
  37. "wemeet" => await WemeetParseAsync(content, ip, oaid),
  38. "bdpan" => PanParse(content, ip, oaid),
  39. "jd" => await JdParseAsync(content, commerceType, ip, oaid, accountid),
  40. "ks" => await KsParseAsync(content, commerceType, ip, oaid, accountid),
  41. "dy" => await DyParseAsync(content, commerceType, ip, oaid),
  42. "pdd" => await PddParseAsync(content, commerceType, ip, oaid, accountid),
  43. "tb" => await TaobaoParseAsync(content, commerceType, ip, oaid, accountid),
  44. _ => await DeeplinkParseCore.ParseAsync(content, channel, ip, oaid),
  45. };
  46. }
  47. //return await DeeplinkParseCore.ParseAsync(content, channel, ip, oaid);
  48. public static async Task<APIResult> WemeetParseAsync(string content, string ip, string oaid)
  49. {
  50. var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.wemeet, content, ip, oaid);
  51. content = content.UrlDecode();
  52. result.rawContent = content;
  53. try
  54. {
  55. result = await ToolParsePlus.WemeetParseAsync(content, result);
  56. }
  57. catch (Exception ex)
  58. {
  59. _ = new LoggerLibrary("unionParse", "wemeet_error")
  60. .Info(ip, oaid)
  61. .Info(content)
  62. .Info(ex.Message, ex.StackTrace)
  63. .SaveAsync();
  64. NotifyCore.Notify(new NifyMessage
  65. {
  66. message = $"【转链异常Wemeet】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  67. priority = NifyMessagePriority.high,
  68. tags = ["red_circle"]
  69. });
  70. result.success = false;
  71. result.message = "内部错误";
  72. result.reason = "转链接口异常";
  73. }
  74. _ = TkLogCore.ParseLogAsync(result);
  75. return new APIResult(new
  76. {
  77. result.success,
  78. result.message,
  79. channel = result?.channel.ToString(),
  80. result.shortLinkurl,
  81. result.deeplink_url,
  82. result.itemName,
  83. }, result.success ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
  84. }
  85. public static APIResult PanParse(string content, string ip, string oaid)
  86. {
  87. var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.bdpan, content, ip, oaid);
  88. content = content.UrlDecode();
  89. result.rawContent = content;
  90. try
  91. {
  92. ToolParsePlus.PanParse(content, ref result);
  93. }
  94. catch (Exception ex)
  95. {
  96. _ = new LoggerLibrary("unionParse", "pan_error")
  97. .Info(ip, oaid)
  98. .Info(content)
  99. .Info(ex.Message, ex.StackTrace)
  100. .SaveAsync();
  101. NotifyCore.Notify(new NifyMessage
  102. {
  103. message = $"【转链异常Pan】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  104. priority = NifyMessagePriority.high,
  105. tags = ["red_circle"]
  106. });
  107. result.success = false;
  108. result.message = "内部错误";
  109. result.reason = "转链接口异常";
  110. }
  111. _ = TkLogCore.ParseLogAsync(result);
  112. return new APIResult(new
  113. {
  114. result.success,
  115. result.message,
  116. channel = result?.channel.ToString(),
  117. result.shortLinkurl,
  118. result.deeplink_url,
  119. result.itemName,
  120. }, !string.IsNullOrEmpty(result.deeplink_url) ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
  121. }
  122. private static APIResult TaobaoParseOutput(TkDataDTO result, Dictionary<string, long> swData, object info, APIResultCodeEnum code = APIResultCodeEnum.OK)
  123. {
  124. if (result.elapsedTime > 2000)
  125. {
  126. LoggerLibrary log = new("debug", "stopwatch");
  127. foreach ((var key, var value) in swData)
  128. {
  129. log.Info($"{key}\t{value}");
  130. }
  131. log.SaveAsync();
  132. }
  133. return new APIResult(info, code);
  134. }
  135. public static async Task<APIResult> TaobaoParseAsync(string content, int commerceType,
  136. string ip = "", string oaid = "",
  137. int accountid = 0)
  138. {
  139. bool other_aff = false;
  140. AlimamaPlus alimama = null;
  141. //content = content.UrlDecode();
  142. content = content[..Math.Min(1000, content.Length)];
  143. var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
  144. Dictionary<string, long> swData = new();
  145. swData.Add("StartNew", 0);
  146. Stopwatch stopwatch = Stopwatch.StartNew();
  147. result.rawContent = content;
  148. try
  149. {
  150. string reason = string.Empty;
  151. var config = TkConfigCore.Get();
  152. var arr = config.tk_whitelist_regular.Split('\n')
  153. .Where(line => !string.IsNullOrWhiteSpace(line))
  154. .ToList();
  155. var arr2 = config.tk_blacklist_regular.Split('\n')
  156. .Where(line => !string.IsNullOrWhiteSpace(line))
  157. .ToList();
  158. var arr3 = config.multi_token_regular.Split('\n')
  159. .Where(line => !string.IsNullOrWhiteSpace(line))
  160. .ToList();
  161. bool is_tao_url = !string.IsNullOrEmpty(result.shortLinkurl);
  162. bool is_tao_token = AlimamaPlus.MatchRegexes(content, arr);
  163. bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);
  164. //============================== 放弃转链-初步筛选1 ==============================
  165. if (!is_tao_url && !is_tao_token || is_other)
  166. {
  167. //没有链接都放弃
  168. result.success = false;
  169. result.message = "放弃转链";
  170. result.reason = "初步筛选1";
  171. result.subCode = TkSubCodeEnum.Prelim1;
  172. result.itemName = "";
  173. result.deeplink_url = "";
  174. _ = TkLogCore.ParseLogAsync(result);
  175. return TaobaoParseOutput(result, swData, new
  176. {
  177. result.success,
  178. result.commercial,
  179. result.message,
  180. result.content,
  181. result.itemName,
  182. other_aff,
  183. result.deeplink_url,
  184. });
  185. }
  186. bool is_multi_token = AlimamaPlus.MatchMultiToken(content, arr3);
  187. //============================== 放弃转链-初步筛选1.5 ==============================
  188. if (is_multi_token)
  189. {
  190. //没有链接都放弃
  191. result.success = false;
  192. result.message = "放弃转链";
  193. result.reason = "初步筛选1.5";
  194. result.subCode = TkSubCodeEnum.Prelim1_5;
  195. result.itemName = "";
  196. result.deeplink_url = "";
  197. _ = TkLogCore.ParseLogAsync(result);
  198. return TaobaoParseOutput(result, swData, new
  199. {
  200. result.success,
  201. result.commercial,
  202. result.message,
  203. result.content,
  204. result.itemName,
  205. other_aff,
  206. result.deeplink_url,
  207. });
  208. }
  209. //============================== 放弃转链-初步筛选2 ==============================
  210. bool is_aff_link = false;
  211. if (!string.IsNullOrEmpty(result.shortLinkurl)) is_aff_link = AlimamaPlus.IsAffLink(result.shortLinkurl);
  212. if (!is_tao_url && is_tao_token)
  213. {
  214. //淘宝口令
  215. result.success = false;
  216. result.message = "放弃转链";
  217. result.reason = "初步筛选2";
  218. result.subCode = TkSubCodeEnum.Prelim2;
  219. result.itemName = "点击打开淘宝APP";
  220. _ = TkLogCore.ParseLogAsync(result);
  221. //20241108 特例
  222. string ruleKey = $"tmp_rules:{DateTime.Now:yyyyMMdd}";
  223. var count = RedisHelper.IncrBy(ruleKey);
  224. if (DateTime.Now < DateTime.Parse("2024-11-11") && count < 2500)
  225. {
  226. //"https://s.click.taobao.com/t?union_lens=lensId%3APUB%401730991020%400bbb0a39_0e75_193071ad936_c566%4001%40eyJmbG9vcklkIjozODg1Miiwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfYWN0aXZpdHlfb2ZmaWNpYWxfaW5kZXhfaHRtIn0ie%3BeventPageId%3A20150318020007201&e=m%3D2%26s%3DipuVKjYImbNw4vFB6t2Z2iperVdZeJviU%2F9%2F0taeK29yINtkUhsv0KWvzu%2FHMi3%2BFPhC4MirEWStw6LBB4w3HYXT%2BqQ2P5OIQVNSryTmvs7YddWYbxmvGTMNfihJN%2FGnAGIx0oe2X2hZfJ7ZQxC1%2FU3rpAhWgptfEBnEBk3xaGylLmcSHKfaX1CIFRJhZoJ2keMqUwSQcLRC0TzsMy8kp7Hfv3%2BBYcPW3eHn14rW1PB5SunYCHQHRbw6LwQYf%2F1JuyhJem%2BM5OoR2cbDLktPLiIOenYkFIXa2HzNl%2Bm1VXoil%2F2L3b1aA6a%2FoVHlY%2BqZ2kyLuBX5NHCAQVYCmAmuozC39JfnbJNrE%2FSR3F9BSjOYe76q6w0hyfybhwAASyyp5XMWEyz25ulHMwkL2n%2F7nNBiFmadXyjFDPu12TgSnbZtfjDbrVTLHb6MowVEq7z9LgOFRSuRLesvlLykGd2CaRk8ezhE61zXa8yR1eex6ip3KqbOh7CEmgCLaFxcnT%2BrGuviRFaBil8Mlu5kMKse3g%3D%3D";
  227. string hb_url = "https://s.click.taobao.com/t?union_lens=lensId%3APUB%401730991060%400b510772_0df6_193071b768d_210f%4001%40eyJmbG9vcklkIjozODg1Miiwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfYWN0aXZpdHlfb2ZmaWNpYWxfaW5kZXhfaHRtIn0ie%3BeventPageId%3A20150318020016843&e=m%3D2%26s%3DA1AHKD9F7Nhw4vFB6t2Z2iperVdZeJviU%2F9%2F0taeK29yINtkUhsv0KWvzu%2FHMi3%2Bh1wntvOGDCytw6LBB4w3HYXT%2BqQ2P5OIQVNSryTmvs7eznT8c0%2BOxucX6%2FIvhSD5AGIx0oe2X2hZfJ7ZQxC1%2FU3rpAhWgptfEBnEBk3xaGylLmcSHKfaX1CIFRJhZoJ2keMqUwSQcLRC0TzsMy8kp7Hfv3%2BBYcPW3eHn14rW1PB5SunYCHQHRbw6LwQYf%2F1JuyhJem%2BM5OoR2cbDLktPLiIOenYkFIXaB%2FWmSjJ%2FDetdnBNxJusisiH18dRGjHzjUh%2Bx4%2Bh6gbwLqirZAkaxvnIKgJtaeeuKsJkGnmNeMxV2b5AccURU%2FXqss%2B9QPoF86hteE8NJKpolfPKodRMJmRfFCEuMVaVFTjJ9EustsCzTbaXzU0HzGQ3G0oSVAhvq8dJ646N9%2BfPG7KP%2FW7aJTlBg0B0VOPmAfTYWTuIBgHgsBQ1POZZlkf%2BtQEx4g%2BcAxnAryvg3Dknnic12Z1shopsQ%2FFWmC5aPxgxdTc00KD8%3D";
  228. result.deeplink_url = AlimamaPlus.GetDeeplink(hb_url);
  229. RedisHelper.Expire(ruleKey, 86400 * 10);
  230. }
  231. other_aff = true;
  232. return TaobaoParseOutput(result, swData, new
  233. {
  234. result.success,
  235. result.commercial,
  236. result.message,
  237. result.content,
  238. result.itemName,
  239. other_aff,
  240. result.deeplink_url,
  241. });
  242. }
  243. if ((!is_tao_url && is_tao_token) || is_aff_link)
  244. {
  245. //没有短链接都放弃
  246. result.success = false;
  247. result.message = "放弃转链";
  248. result.reason = "初步筛选2";
  249. result.subCode = TkSubCodeEnum.Prelim2;
  250. result.itemName = "点击打开淘宝APP";
  251. _ = TkLogCore.ParseLogAsync(result);
  252. other_aff = true;
  253. return TaobaoParseOutput(result, swData, new
  254. {
  255. result.success,
  256. result.commercial,
  257. result.message,
  258. result.content,
  259. result.itemName,
  260. other_aff,
  261. result.deeplink_url,
  262. });
  263. }
  264. //那就初步筛选3 有tb.cn 并且有 or 手淘发现
  265. string pattern = @"^(?!【淘宝】).*https?:\/\/m\.tb\.cn.*(?:手淘发现|手淘搜索)";
  266. bool isMatch = Regex.IsMatch(content, pattern);
  267. if (isMatch)
  268. {
  269. result.success = false;
  270. result.message = "放弃转链";
  271. result.reason = "初步筛选3";
  272. result.subCode = TkSubCodeEnum.Prelim3;
  273. result.itemName = "点击打开淘宝APP";
  274. _ = TkLogCore.ParseLogAsync(result);
  275. return TaobaoParseOutput(result, swData, new
  276. {
  277. result.success,
  278. result.commercial,
  279. result.message,
  280. result.content,
  281. result.itemName,
  282. other_aff,
  283. result.deeplink_url,
  284. });
  285. }
  286. //============================== 放弃转链-地区过滤 ==============================
  287. bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out reason);
  288. if (is_ignore2)
  289. {
  290. result.success = false;
  291. result.message = "放弃转链";
  292. result.itemName = "点击打开淘宝APP";
  293. result.reason = reason;
  294. result.subCode = TkSubCodeEnum.TrafficCtrl;
  295. _ = TkLogCore.ParseLogAsync(result);
  296. return TaobaoParseOutput(result, swData, new
  297. {
  298. result.success,
  299. result.commercial,
  300. result.message,
  301. result.content,
  302. result.itemName,
  303. other_aff,
  304. result.deeplink_url,
  305. });
  306. }
  307. //============================== 放弃转链-没有匹配账号 ==============================
  308. TkPoolDTO? account = accountid > 0 ?
  309. TkPoolCore.GetOne(accountid) :
  310. TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
  311. if (account == null)
  312. {
  313. result.success = false;
  314. result.message = "放弃转链";
  315. result.reason = "没有匹配账号";
  316. result.subCode = TkSubCodeEnum.Other;
  317. result.itemName = "点击打开淘宝APP";
  318. _ = TkLogCore.ParseLogAsync(result);
  319. return TaobaoParseOutput(result, swData, new
  320. {
  321. result.success,
  322. result.commercial,
  323. result.message,
  324. result.content,
  325. result.couponAmount,
  326. result.taoToken,
  327. result.shortLinkurl,
  328. other_aff,
  329. result.deeplink_url,
  330. });
  331. }
  332. result.accountId = account.id;
  333. result.accountName = account.company;
  334. alimama = new AlimamaPlus(account);
  335. int timeout = alimama._config.rt_max;
  336. #if DEBUG
  337. timeout = 10000;
  338. #endif
  339. using var cts = new CancellationTokenSource();
  340. cts.CancelAfter(timeout);
  341. var requestTask = Task.Run(() => alimama.UnionParse2Async(content, commerceType, result, cts.Token, swData), cts.Token);
  342. var delayTask = Task.Delay(timeout, cts.Token);
  343. var completedTask = await Task.WhenAny(requestTask, delayTask);
  344. if (completedTask == requestTask)
  345. {
  346. result = await requestTask;
  347. }
  348. else
  349. {
  350. //============================== 放弃转链-请求超时 ==============================
  351. cts.Cancel();
  352. result.success = false;
  353. result.message = "放弃转链";
  354. result.reason = "请求超时";
  355. result.subCode = TkSubCodeEnum.Other;
  356. result.itemName = "点击打开淘宝APP";
  357. }
  358. result.accountName = account.company;
  359. //result = await alimama.UnionParse2Async(content, result);
  360. }
  361. catch (Exception ex)
  362. {
  363. //============================== 放弃转链-请求超时 ==============================
  364. if (ex.Message.Contains("was canceled"))
  365. {
  366. result.success = false;
  367. result.message = "放弃转链";
  368. result.reason = "请求超时";
  369. result.subCode = TkSubCodeEnum.Other;
  370. result.itemName = "点击打开淘宝APP";
  371. }
  372. else
  373. {
  374. //============================== 转链接口异常 ==============================
  375. _ = new LoggerLibrary("unionParse", "tb_error")
  376. .Info(ip, oaid)
  377. .Info(content)
  378. .Info(ex.Message, ex.StackTrace)
  379. .SaveAsync();
  380. NotifyCore.Notify(new NifyMessage
  381. {
  382. message = $"【转链异常TB】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  383. priority = NifyMessagePriority.high,
  384. tags = ["red_circle"]
  385. });
  386. result.success = false;
  387. result.subCode = TkSubCodeEnum.Other;
  388. result.message = "转链接口异常";
  389. result.itemName = "点击打开淘宝APP";
  390. }
  391. }
  392. _ = TkLogCore.ParseLogAsync(result, alimama);
  393. switch (result.reason)
  394. {
  395. case "其他推广链接":
  396. //case "排除淘口令":
  397. case "纯口令 没链接":
  398. other_aff = true;
  399. break;
  400. }
  401. return TaobaoParseOutput(result, swData, new
  402. {
  403. result.success,
  404. result.commercial,
  405. result.message,
  406. link_type = result.link_type.ToString(),
  407. channel = result?.channel.ToString(),
  408. result.channel_type,
  409. result.itemId,
  410. result.itemName,
  411. result.pic,
  412. result.promotionPrice,
  413. result.couponAmount,
  414. result.couponEffectiveStartTime,
  415. result?.couponEffectiveEndTime,
  416. result.shortLinkurl,
  417. result.deeplink_url,
  418. result.content,
  419. result.taoToken,
  420. other_aff,
  421. });
  422. }
  423. private static APIResult JdParseOutput(JdDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  424. {
  425. return new APIResult(new
  426. {
  427. result.success,
  428. result.message,
  429. link_type = result.link_type.ToString(),
  430. channel = result?.channel.ToString(),
  431. result.channel_type,
  432. result.itemId,
  433. result.itemName,
  434. result.shortLinkurl,
  435. result.deeplink_url,
  436. }, code);
  437. }
  438. public static async Task<APIResult> JdParseAsync(string content, int commerceType, string ip, string oaid,
  439. int accountid = 0, CancellationToken cancellationToken = default)
  440. {
  441. var result = JdUnionPlus.GetFormattedObject(content, ip, oaid);
  442. content = content.UrlDecode();
  443. result.rawContent = content;
  444. bool IfExceptional = false;
  445. try
  446. {
  447. var config = TkConfigCore.Get();
  448. if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
  449. {
  450. var blacklist = config.jd_blacklist_regular.Split('\n')
  451. .Where(line => !string.IsNullOrWhiteSpace(line))
  452. .ToList();
  453. bool anyMatch = false;
  454. foreach (string pattern in blacklist)
  455. {
  456. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  457. }
  458. if (anyMatch)
  459. {
  460. result.success = false;
  461. result.deeplink_url = string.Empty;
  462. result.message = "放弃转链";
  463. result.reason = "规则排除";
  464. _ = TkLogCore.ParseLogAsync(result);
  465. return JdParseOutput(result);
  466. }
  467. }
  468. //============================== 放弃转链-地区过滤 ==============================
  469. if (!result.ip.StartsWith("127.0.0") && accountid == 0 && JdUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  470. {
  471. result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out string out_url, out string itemId);
  472. result.deeplink_url = result.link_type switch
  473. {
  474. LinkTypeEnum.other_aff or
  475. LinkTypeEnum.live or
  476. LinkTypeEnum.video or
  477. LinkTypeEnum.profile or
  478. LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
  479. _ => JdUnionPlus.GetDeeplink(string.Empty),
  480. };
  481. result.success = false;
  482. result.message = "放弃转链";
  483. result.reason = reason;
  484. _ = TkLogCore.ParseLogAsync(result);
  485. return JdParseOutput(result);
  486. }
  487. // bool is_ignore2 = JdUnionPlus.FlowControlIgnoreRequest(config, out reason);
  488. //#if DEBUG
  489. // is_ignore2 = false;
  490. //#endif
  491. // if (accountid == 0 && is_ignore2)
  492. // {
  493. // result.success = false;
  494. // result.message = "放弃转链";
  495. // result.reason = reason;
  496. // _ = TkLogCore.ParseLogAsync(result);
  497. // return JdParseOutput(result);
  498. // }
  499. var account = accountid > 0 ? JdPoolCore.GetOne(accountid, JdPoolCore.JdAction.parse) : JdPoolCore.GetOne(JdPoolCore.JdAction.parse);
  500. if (account == null)
  501. {
  502. result.success = false;
  503. result.message = "放弃转链";
  504. result.reason = "没有匹配账号";
  505. result.deeplink_url = result.link_type switch
  506. {
  507. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
  508. _ => JdUnionPlus.GetDeeplink(string.Empty),
  509. };
  510. _ = TkLogCore.ParseLogAsync(result);
  511. return JdParseOutput(result);
  512. }
  513. result.accountId = account.id;
  514. result.accountName = account.name;
  515. var plus = new JdUnionPlus(account);
  516. result = await plus.JdParseAsync(content, commerceType, result, cancellationToken);
  517. }
  518. catch (Exception ex)
  519. {
  520. if (ex.Message.Contains("was canceled"))
  521. {
  522. result.success = false;
  523. result.message = "放弃转链";
  524. result.reason = "请求超时";
  525. }
  526. else
  527. {
  528. IfExceptional = true;
  529. _ = new LoggerLibrary("unionParse", "jd_error")
  530. .Info(ip, oaid)
  531. .Info(content)
  532. .Info(ex.Message, ex.StackTrace)
  533. .SaveAsync();
  534. NotifyCore.Notify(new NifyMessage
  535. {
  536. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  537. priority = NifyMessagePriority.high,
  538. tags = ["red_circle"]
  539. });
  540. result.success = false;
  541. result.message = "内部错误";
  542. result.reason = "转链接口异常";
  543. }
  544. result.deeplink_url = result.link_type switch
  545. {
  546. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
  547. _ => JdUnionPlus.GetDeeplink(string.Empty),
  548. };
  549. }
  550. _ = TkLogCore.ParseLogAsync(result);
  551. return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  552. }
  553. public static async Task<APIResult> DyParseAsync(string content, int commerceType, string ip, string oaid, CancellationToken cancellationToken = default)
  554. {
  555. var result = DyUnionPlus.GetFormattedObject(content, ip, oaid);
  556. content = content.UrlDecode();
  557. result.rawContent = content;
  558. bool IfExceptional = false;
  559. try
  560. {
  561. #if DEBUG
  562. #else
  563. // 2024-06-19 联盟业务下线
  564. result.success = false;
  565. result.message = "放弃转链";
  566. result.reason = "联盟下线";
  567. _ = TkLogCore.ParseLogAsync(result);
  568. return new APIResult(result);
  569. #endif
  570. if (DyUnionPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  571. {
  572. result.success = false;
  573. result.message = "放弃转链";
  574. result.reason = reason;
  575. _ = TkLogCore.ParseLogAsync(result);
  576. return new APIResult(result);
  577. }
  578. var account = PangolinPoolCore.GetOne();
  579. if (account == null)
  580. {
  581. result.success = false;
  582. result.message = "放弃转链";
  583. result.reason = "没有匹配账号";
  584. _ = TkLogCore.ParseLogAsync(result);
  585. return new APIResult(result);
  586. }
  587. result = await DyUnionPlus.DyParseAsync(account, content, commerceType, result, cancellationToken);
  588. }
  589. catch (Exception ex)
  590. {
  591. if (ex.Message.Contains("was canceled"))
  592. {
  593. result.success = false;
  594. result.message = "放弃转链";
  595. result.reason = "请求超时";
  596. }
  597. else
  598. {
  599. IfExceptional = true;
  600. _ = new LoggerLibrary("unionParse", "dy_error")
  601. .Info(ip, oaid)
  602. .Info(content)
  603. .Info(ex.Message, ex.StackTrace)
  604. .SaveAsync();
  605. NotifyCore.Notify(new NifyMessage
  606. {
  607. message = $"【转链异常DY】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  608. priority = NifyMessagePriority.high,
  609. tags = ["red_circle"]
  610. });
  611. result.success = false;
  612. result.message = "内部错误";
  613. result.reason = "转链接口异常";
  614. }
  615. }
  616. _ = TkLogCore.ParseLogAsync(result);
  617. return new APIResult(new
  618. {
  619. result.success,
  620. result.message,
  621. link_type = result.link_type.ToString(),
  622. channel = result?.channel.ToString(),
  623. content = result?.rawContent.ToString(),
  624. taoToken = result?.taoToken.ToString(),
  625. result.channel_type,
  626. result.itemName,
  627. result.shortLinkurl,
  628. result.deeplink_url,
  629. }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  630. }
  631. public static async Task<APIResult> PddParseAsync(string content, int commerceType, string ip, string oaid,
  632. int accountid = 0, CancellationToken cancellationToken = default)
  633. {
  634. var result = PddUnionPlus.GetFormattedObject(content, ip, oaid);
  635. content = content.UrlDecode();
  636. result.rawContent = content;
  637. bool IfExceptional = false;
  638. try
  639. {
  640. var config = TkConfigCore.Get();
  641. if (!string.IsNullOrEmpty(config.pdd_blacklist_regular))
  642. {
  643. var blacklist = config.pdd_blacklist_regular.Split('\n')
  644. .Where(line => !string.IsNullOrWhiteSpace(line))
  645. .ToList();
  646. bool anyMatch = false;
  647. foreach (string pattern in blacklist)
  648. {
  649. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  650. }
  651. if (anyMatch)
  652. {
  653. result.success = false;
  654. result.deeplink_url = string.Empty;
  655. result.message = "放弃转链";
  656. result.reason = "规则排除";
  657. _ = TkLogCore.ParseLogAsync(result);
  658. return PddParseOutput(result);
  659. }
  660. }
  661. //============================== 放弃转链-地区过滤 ==============================
  662. if (accountid == 0 && PddUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  663. {
  664. result.success = false;
  665. result.message = "放弃转链";
  666. result.reason = reason;
  667. _ = TkLogCore.ParseLogAsync(result);
  668. return PddParseOutput(result);
  669. }
  670. var account = PddPoolCore.GetOne(PddUnionWorkMode.All, accountid);
  671. if (account == null)
  672. {
  673. result.success = false;
  674. result.message = "放弃转链";
  675. result.reason = "没有匹配账号";
  676. _ = TkLogCore.ParseLogAsync(result);
  677. return PddParseOutput(result);
  678. }
  679. result.accountId = account.id;
  680. result.accountName = account.name;
  681. var plus = new PddUnionPlus(account);
  682. result = await plus.PddParseAsync(content, commerceType, result, cancellationToken);
  683. }
  684. catch (Exception ex)
  685. {
  686. if (ex.Message.Contains("was canceled"))
  687. {
  688. result.success = false;
  689. result.message = "放弃转链";
  690. result.reason = "请求超时";
  691. }
  692. else
  693. {
  694. IfExceptional = true;
  695. _ = new LoggerLibrary("unionParse", "pdd_error")
  696. .Info(ip, oaid)
  697. .Info(content)
  698. .Info(ex.Message, ex.StackTrace)
  699. .SaveAsync();
  700. NotifyCore.Notify(new NifyMessage
  701. {
  702. message = $"【转链异常PDD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  703. priority = NifyMessagePriority.high,
  704. tags = ["red_circle"]
  705. });
  706. result.success = false;
  707. result.message = "内部错误";
  708. result.reason = "转链接口异常";
  709. }
  710. }
  711. _ = TkLogCore.ParseLogAsync(result);
  712. return PddParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  713. }
  714. private static APIResult PddParseOutput(PddDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  715. {
  716. return new APIResult(new
  717. {
  718. result.success,
  719. result.message,
  720. link_type = result.link_type.ToString(),
  721. channel = result?.channel.ToString(),
  722. result.itemId,
  723. result.itemName,
  724. result.shortLinkurl,
  725. result.deeplink_url,
  726. }, code);
  727. }
  728. public static async Task<APIResult> KsParseAsync(string content, int commerceType, string ip, string oaid,
  729. int accountid = 0, CancellationToken cancellationToken = default)
  730. {
  731. var result = KsUnionPlus.GetFormattedObject(content, ip, oaid);
  732. content = content.UrlDecode();
  733. result.rawContent = content;
  734. bool IfExceptional = false;
  735. try
  736. {
  737. var config = TkConfigCore.Get();
  738. if (!string.IsNullOrEmpty(config.ks_blacklist_regular))
  739. {
  740. var blacklist = config.ks_blacklist_regular.Split('\n')
  741. .Where(line => !string.IsNullOrWhiteSpace(line))
  742. .ToList();
  743. bool anyMatch = false;
  744. foreach (string pattern in blacklist)
  745. {
  746. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  747. }
  748. if (anyMatch)
  749. {
  750. result.success = false;
  751. result.deeplink_url = string.Empty;
  752. result.message = "放弃转链";
  753. result.reason = "规则排除";
  754. _ = TkLogCore.ParseLogAsync(result);
  755. return KsParseOutput(result);
  756. }
  757. }
  758. //============================== 放弃转链-地区过滤 ==============================
  759. if (accountid == 0 && KsUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  760. {
  761. result.success = false;
  762. result.message = "放弃转链";
  763. result.reason = reason;
  764. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  765. _ = TkLogCore.ParseLogAsync(result);
  766. return KsParseOutput(result);
  767. }
  768. var account = accountid > 0 ? KsPoolCore.GetOne(accountid, KsPoolCore.KsAction.parse) : KsPoolCore.GetOne(KsPoolCore.KsAction.parse);
  769. if (account == null)
  770. {
  771. result.success = false;
  772. result.message = "放弃转链";
  773. result.reason = "没有匹配账号";
  774. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  775. _ = TkLogCore.ParseLogAsync(result);
  776. return KsParseOutput(result);
  777. }
  778. result.accountId = account.id;
  779. result.accountName = account.name;
  780. var plus = new KsUnionPlus(account);
  781. result = await plus.KsParseAsync(content, commerceType, result, cancellationToken);
  782. }
  783. catch (Exception ex)
  784. {
  785. if (ex.Message.Contains("was canceled"))
  786. {
  787. result.success = false;
  788. result.message = "放弃转链";
  789. result.reason = "请求超时";
  790. }
  791. else
  792. {
  793. IfExceptional = true;
  794. _ = new LoggerLibrary("unionParse", "jd_error")
  795. .Info(ip, oaid)
  796. .Info(content)
  797. .Info(ex.Message, ex.StackTrace)
  798. .SaveAsync();
  799. NotifyCore.Notify(new NifyMessage
  800. {
  801. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  802. priority = NifyMessagePriority.high,
  803. tags = ["red_circle"]
  804. });
  805. result.success = false;
  806. result.message = "内部错误";
  807. result.reason = "转链接口异常";
  808. }
  809. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  810. }
  811. _ = TkLogCore.ParseLogAsync(result);
  812. return KsParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  813. }
  814. private static APIResult KsParseOutput(KsDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  815. {
  816. return new APIResult(new
  817. {
  818. result.success,
  819. result.message,
  820. link_type = result.link_type.ToString(),
  821. channel = result?.channel.ToString(),
  822. result.itemId,
  823. result.itemName,
  824. result.shortLinkurl,
  825. result.deeplink_url,
  826. }, code);
  827. }
  828. }
  829. }