UnionParseCore.cs 39 KB

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