UnionParseCore.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  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, 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, ip, oaid, accountid),
  40. "ks" => await KsParseAsync(content, ip, oaid, accountid),
  41. "dy" => await DyParseAsync(content, ip, oaid),
  42. "pdd" => await PddParseAsync(content, ip, oaid, accountid),
  43. "tb" => await TaobaoParseAsync(content, 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,
  136. string ip = "", string oaid = "",
  137. int accountid = 0)
  138. {
  139. AlimamaPlus alimama = null;
  140. //content = content.UrlDecode();
  141. content = content[..Math.Min(1000, content.Length)];
  142. var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
  143. Dictionary<string, long> swData = new();
  144. swData.Add("StartNew", 0);
  145. Stopwatch stopwatch = Stopwatch.StartNew();
  146. result.rawContent = content;
  147. try
  148. {
  149. string reason = string.Empty;
  150. var config = TkConfigCore.Get();
  151. var arr = config.tk_whitelist_regular.Split('\n')
  152. .Where(line => !string.IsNullOrWhiteSpace(line))
  153. .ToList();
  154. var arr2 = config.tk_blacklist_regular.Split('\n')
  155. .Where(line => !string.IsNullOrWhiteSpace(line))
  156. .ToList();
  157. var arr3 = config.multi_token_regular.Split('\n')
  158. .Where(line => !string.IsNullOrWhiteSpace(line))
  159. .ToList();
  160. bool is_tao_url = !string.IsNullOrEmpty(result.shortLinkurl);
  161. bool is_tao_token = AlimamaPlus.MatchRegexes(content, arr);
  162. bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);
  163. //============================== 放弃转链-初步筛选1 ==============================
  164. if (!is_tao_url && !is_tao_token || is_other)
  165. {
  166. //没有链接都放弃
  167. result.success = false;
  168. result.message = "放弃转链";
  169. result.reason = "初步筛选1";
  170. result.subCode = TkSubCodeEnum.Prelim1;
  171. result.itemName = "";
  172. result.deeplink_url = "";
  173. _ = TkLogCore.ParseLogAsync(result);
  174. return TaobaoParseOutput(result, swData, new
  175. {
  176. result.success,
  177. result.message,
  178. result.content,
  179. result.itemName,
  180. result.deeplink_url,
  181. });
  182. }
  183. bool is_multi_token = AlimamaPlus.MatchMultiToken(content, arr3);
  184. //============================== 放弃转链-初步筛选1.5 ==============================
  185. if (is_multi_token)
  186. {
  187. //没有链接都放弃
  188. result.success = false;
  189. result.message = "放弃转链";
  190. result.reason = "初步筛选1.5";
  191. result.subCode = TkSubCodeEnum.Prelim1_5;
  192. result.itemName = "";
  193. result.deeplink_url = "";
  194. _ = TkLogCore.ParseLogAsync(result);
  195. return TaobaoParseOutput(result, swData, new
  196. {
  197. result.success,
  198. result.message,
  199. result.content,
  200. result.itemName,
  201. result.deeplink_url,
  202. });
  203. }
  204. //============================== 放弃转链-初步筛选2 ==============================
  205. bool is_aff_link = false;
  206. if (!string.IsNullOrEmpty(result.shortLinkurl)) is_aff_link = AlimamaPlus.IsAffLink(result.shortLinkurl);
  207. if ((!is_tao_url && is_tao_token) || is_aff_link)
  208. {
  209. //没有短链接都放弃
  210. result.success = false;
  211. result.message = "放弃转链";
  212. result.reason = "初步筛选2";
  213. result.subCode = TkSubCodeEnum.Prelim2;
  214. result.itemName = "点击打开淘宝APP";
  215. _ = TkLogCore.ParseLogAsync(result);
  216. return TaobaoParseOutput(result, swData, new
  217. {
  218. result.success,
  219. result.message,
  220. result.content,
  221. result.itemName,
  222. result.deeplink_url,
  223. });
  224. }
  225. //那就初步筛选3 有tb.cn 并且有 or 手淘发现
  226. string pattern = @"^(?!【淘宝】).*https?:\/\/m\.tb\.cn.*(?:手淘发现|手淘搜索)";
  227. bool isMatch = Regex.IsMatch(content, pattern);
  228. if (isMatch)
  229. {
  230. result.success = false;
  231. result.message = "放弃转链";
  232. result.reason = "初步筛选3";
  233. result.subCode = TkSubCodeEnum.Prelim3;
  234. result.itemName = "点击打开淘宝APP";
  235. _ = TkLogCore.ParseLogAsync(result);
  236. return TaobaoParseOutput(result, swData, new
  237. {
  238. result.success,
  239. result.message,
  240. result.content,
  241. result.itemName,
  242. result.deeplink_url,
  243. });
  244. }
  245. //============================== 放弃转链-地区过滤 ==============================
  246. bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out reason);
  247. if (is_ignore2)
  248. {
  249. result.success = false;
  250. result.message = "放弃转链";
  251. result.itemName = "点击打开淘宝APP";
  252. result.reason = reason;
  253. result.subCode = TkSubCodeEnum.TrafficCtrl;
  254. _ = TkLogCore.ParseLogAsync(result);
  255. return TaobaoParseOutput(result, swData, new
  256. {
  257. result.success,
  258. result.message,
  259. result.content,
  260. result.itemName,
  261. result.deeplink_url,
  262. });
  263. }
  264. //============================== 放弃转链-没有匹配账号 ==============================
  265. TkPoolDTO? account = accountid > 0 ?
  266. TkPoolCore.GetOne(accountid) :
  267. TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
  268. if (account == null)
  269. {
  270. result.success = false;
  271. result.message = "放弃转链";
  272. result.reason = "没有匹配账号";
  273. result.subCode = TkSubCodeEnum.Other;
  274. result.itemName = "点击打开淘宝APP";
  275. _ = TkLogCore.ParseLogAsync(result);
  276. return TaobaoParseOutput(result, swData, new
  277. {
  278. result.success,
  279. result.message,
  280. result.content,
  281. result.couponAmount,
  282. result.taoToken,
  283. result.shortLinkurl,
  284. result.deeplink_url,
  285. });
  286. }
  287. result.accountId = account.id;
  288. result.accountName = account.company;
  289. alimama = new AlimamaPlus(account);
  290. int timeout = alimama._config.rt_max;
  291. #if DEBUG
  292. timeout = 10000;
  293. #endif
  294. using var cts = new CancellationTokenSource();
  295. cts.CancelAfter(timeout);
  296. var requestTask = Task.Run(() => alimama.UnionParse2Async(content, result, cts.Token, swData), cts.Token);
  297. var delayTask = Task.Delay(timeout, cts.Token);
  298. var completedTask = await Task.WhenAny(requestTask, delayTask);
  299. if (completedTask == requestTask)
  300. {
  301. result = await requestTask;
  302. }
  303. else
  304. {
  305. //============================== 放弃转链-请求超时 ==============================
  306. cts.Cancel();
  307. result.success = false;
  308. result.message = "放弃转链";
  309. result.reason = "请求超时";
  310. result.subCode = TkSubCodeEnum.Other;
  311. result.itemName = "点击打开淘宝APP";
  312. }
  313. result.accountName = account.company;
  314. //result = await alimama.UnionParse2Async(content, result);
  315. }
  316. catch (Exception ex)
  317. {
  318. //============================== 放弃转链-请求超时 ==============================
  319. if (ex.Message.Contains("was canceled"))
  320. {
  321. result.success = false;
  322. result.message = "放弃转链";
  323. result.reason = "请求超时";
  324. result.subCode = TkSubCodeEnum.Other;
  325. result.itemName = "点击打开淘宝APP";
  326. }
  327. else
  328. {
  329. //============================== 转链接口异常 ==============================
  330. _ = new LoggerLibrary("unionParse", "tb_error")
  331. .Info(ip, oaid)
  332. .Info(content)
  333. .Info(ex.Message, ex.StackTrace)
  334. .SaveAsync();
  335. NotifyCore.Notify(new NifyMessage
  336. {
  337. message = $"【转链异常TB】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  338. priority = NifyMessagePriority.high,
  339. tags = ["red_circle"]
  340. });
  341. result.success = false;
  342. result.subCode = TkSubCodeEnum.Other;
  343. result.message = "转链接口异常";
  344. result.itemName = "点击打开淘宝APP";
  345. }
  346. }
  347. _ = TkLogCore.ParseLogAsync(result, alimama);
  348. return TaobaoParseOutput(result, swData, new
  349. {
  350. result.success,
  351. result.message,
  352. link_type = result.link_type.ToString(),
  353. channel = result?.channel.ToString(),
  354. result.channel_type,
  355. result.itemId,
  356. result.itemName,
  357. result.pic,
  358. result.promotionPrice,
  359. result.couponAmount,
  360. result.couponEffectiveStartTime,
  361. result?.couponEffectiveEndTime,
  362. result.shortLinkurl,
  363. result.deeplink_url,
  364. result.content,
  365. result.taoToken,
  366. });
  367. }
  368. private static APIResult JdParseOutput(JdDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  369. {
  370. return new APIResult(new
  371. {
  372. result.success,
  373. result.message,
  374. link_type = result.link_type.ToString(),
  375. channel = result?.channel.ToString(),
  376. result.channel_type,
  377. result.itemId,
  378. result.itemName,
  379. result.shortLinkurl,
  380. result.deeplink_url,
  381. }, code);
  382. }
  383. public static async Task<APIResult> JdParseAsync(string content, string ip, string oaid,
  384. int accountid = 0, CancellationToken cancellationToken = default)
  385. {
  386. var result = JdUnionPlus.GetFormattedObject(content, ip, oaid);
  387. content = content.UrlDecode();
  388. result.rawContent = content;
  389. bool IfExceptional = false;
  390. try
  391. {
  392. var config = TkConfigCore.Get();
  393. if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
  394. {
  395. var blacklist = config.jd_blacklist_regular.Split('\n')
  396. .Where(line => !string.IsNullOrWhiteSpace(line))
  397. .ToList();
  398. bool anyMatch = false;
  399. foreach (string pattern in blacklist)
  400. {
  401. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  402. }
  403. if (anyMatch)
  404. {
  405. result.success = false;
  406. result.deeplink_url = string.Empty;
  407. result.message = "放弃转链";
  408. result.reason = "规则排除";
  409. _ = TkLogCore.ParseLogAsync(result);
  410. return JdParseOutput(result);
  411. }
  412. }
  413. //============================== 放弃转链-地区过滤 ==============================
  414. if (!result.ip.StartsWith("127.0.0") && accountid == 0 && JdUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  415. {
  416. result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out string out_url, out string itemId);
  417. result.deeplink_url = result.link_type switch
  418. {
  419. LinkTypeEnum.other_aff or
  420. LinkTypeEnum.live or
  421. LinkTypeEnum.video or
  422. LinkTypeEnum.profile or
  423. LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
  424. _ => JdUnionPlus.GetDeeplink(string.Empty),
  425. };
  426. result.success = false;
  427. result.message = "放弃转链";
  428. result.reason = reason;
  429. _ = TkLogCore.ParseLogAsync(result);
  430. return JdParseOutput(result);
  431. }
  432. // bool is_ignore2 = JdUnionPlus.FlowControlIgnoreRequest(config, out reason);
  433. //#if DEBUG
  434. // is_ignore2 = false;
  435. //#endif
  436. // if (accountid == 0 && is_ignore2)
  437. // {
  438. // result.success = false;
  439. // result.message = "放弃转链";
  440. // result.reason = reason;
  441. // _ = TkLogCore.ParseLogAsync(result);
  442. // return JdParseOutput(result);
  443. // }
  444. var account = accountid > 0 ? JdPoolCore.GetOne(accountid, JdPoolCore.JdAction.parse) : JdPoolCore.GetOne(JdPoolCore.JdAction.parse);
  445. if (account == null)
  446. {
  447. result.success = false;
  448. result.message = "放弃转链";
  449. result.reason = "没有匹配账号";
  450. result.deeplink_url = result.link_type switch
  451. {
  452. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
  453. _ => JdUnionPlus.GetDeeplink(string.Empty),
  454. };
  455. _ = TkLogCore.ParseLogAsync(result);
  456. return JdParseOutput(result);
  457. }
  458. result.accountId = account.id;
  459. result.accountName = account.name;
  460. var plus = new JdUnionPlus(account);
  461. result = await plus.JdParseAsync(content, result, cancellationToken);
  462. }
  463. catch (Exception ex)
  464. {
  465. if (ex.Message.Contains("was canceled"))
  466. {
  467. result.success = false;
  468. result.message = "放弃转链";
  469. result.reason = "请求超时";
  470. }
  471. else
  472. {
  473. IfExceptional = true;
  474. _ = new LoggerLibrary("unionParse", "jd_error")
  475. .Info(ip, oaid)
  476. .Info(content)
  477. .Info(ex.Message, ex.StackTrace)
  478. .SaveAsync();
  479. NotifyCore.Notify(new NifyMessage
  480. {
  481. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  482. priority = NifyMessagePriority.high,
  483. tags = ["red_circle"]
  484. });
  485. result.success = false;
  486. result.message = "内部错误";
  487. result.reason = "转链接口异常";
  488. }
  489. result.deeplink_url = result.link_type switch
  490. {
  491. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl),
  492. _ => JdUnionPlus.GetDeeplink(string.Empty),
  493. };
  494. }
  495. _ = TkLogCore.ParseLogAsync(result);
  496. return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  497. }
  498. public static async Task<APIResult> DyParseAsync(string content, string ip, string oaid, CancellationToken cancellationToken = default)
  499. {
  500. var result = DyUnionPlus.GetFormattedObject(content, ip, oaid);
  501. content = content.UrlDecode();
  502. result.rawContent = content;
  503. bool IfExceptional = false;
  504. try
  505. {
  506. #if DEBUG
  507. #else
  508. // 2024-06-19 联盟业务下线
  509. result.success = false;
  510. result.message = "放弃转链";
  511. result.reason = "联盟下线";
  512. _ = TkLogCore.ParseLogAsync(result);
  513. return new APIResult(result);
  514. #endif
  515. if (DyUnionPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  516. {
  517. result.success = false;
  518. result.message = "放弃转链";
  519. result.reason = reason;
  520. _ = TkLogCore.ParseLogAsync(result);
  521. return new APIResult(result);
  522. }
  523. var account = PangolinPoolCore.GetOne();
  524. if (account == null)
  525. {
  526. result.success = false;
  527. result.message = "放弃转链";
  528. result.reason = "没有匹配账号";
  529. _ = TkLogCore.ParseLogAsync(result);
  530. return new APIResult(result);
  531. }
  532. result = await DyUnionPlus.DyParseAsync(account, content, 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", "dy_error")
  546. .Info(ip, oaid)
  547. .Info(content)
  548. .Info(ex.Message, ex.StackTrace)
  549. .SaveAsync();
  550. NotifyCore.Notify(new NifyMessage
  551. {
  552. message = $"【转链异常DY】\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. }
  561. _ = TkLogCore.ParseLogAsync(result);
  562. return new APIResult(new
  563. {
  564. result.success,
  565. result.message,
  566. link_type = result.link_type.ToString(),
  567. channel = result?.channel.ToString(),
  568. content = result?.rawContent.ToString(),
  569. taoToken = result?.taoToken.ToString(),
  570. result.channel_type,
  571. result.itemName,
  572. result.shortLinkurl,
  573. result.deeplink_url,
  574. }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  575. }
  576. public static async Task<APIResult> PddParseAsync(string content, string ip, string oaid,
  577. int accountid = 0, CancellationToken cancellationToken = default)
  578. {
  579. var result = PddUnionPlus.GetFormattedObject(content, ip, oaid);
  580. content = content.UrlDecode();
  581. result.rawContent = content;
  582. bool IfExceptional = false;
  583. try
  584. {
  585. var config = TkConfigCore.Get();
  586. if (!string.IsNullOrEmpty(config.pdd_blacklist_regular))
  587. {
  588. var blacklist = config.pdd_blacklist_regular.Split('\n')
  589. .Where(line => !string.IsNullOrWhiteSpace(line))
  590. .ToList();
  591. bool anyMatch = false;
  592. foreach (string pattern in blacklist)
  593. {
  594. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  595. }
  596. if (anyMatch)
  597. {
  598. result.success = false;
  599. result.deeplink_url = string.Empty;
  600. result.message = "放弃转链";
  601. result.reason = "规则排除";
  602. _ = TkLogCore.ParseLogAsync(result);
  603. return PddParseOutput(result);
  604. }
  605. }
  606. //============================== 放弃转链-地区过滤 ==============================
  607. if (accountid == 0 && PddUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  608. {
  609. result.success = false;
  610. result.message = "放弃转链";
  611. result.reason = reason;
  612. _ = TkLogCore.ParseLogAsync(result);
  613. return PddParseOutput(result);
  614. }
  615. var account = PddPoolCore.GetOne(PddUnionWorkMode.All, accountid);
  616. if (account == null)
  617. {
  618. result.success = false;
  619. result.message = "放弃转链";
  620. result.reason = "没有匹配账号";
  621. _ = TkLogCore.ParseLogAsync(result);
  622. return PddParseOutput(result);
  623. }
  624. result.accountId = account.id;
  625. result.accountName = account.name;
  626. var plus = new PddUnionPlus(account);
  627. result = await plus.PddParseAsync(content, result, cancellationToken);
  628. }
  629. catch (Exception ex)
  630. {
  631. if (ex.Message.Contains("was canceled"))
  632. {
  633. result.success = false;
  634. result.message = "放弃转链";
  635. result.reason = "请求超时";
  636. }
  637. else
  638. {
  639. IfExceptional = true;
  640. _ = new LoggerLibrary("unionParse", "pdd_error")
  641. .Info(ip, oaid)
  642. .Info(content)
  643. .Info(ex.Message, ex.StackTrace)
  644. .SaveAsync();
  645. NotifyCore.Notify(new NifyMessage
  646. {
  647. message = $"【转链异常PDD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  648. priority = NifyMessagePriority.high,
  649. tags = ["red_circle"]
  650. });
  651. result.success = false;
  652. result.message = "内部错误";
  653. result.reason = "转链接口异常";
  654. }
  655. }
  656. _ = TkLogCore.ParseLogAsync(result);
  657. return PddParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  658. }
  659. private static APIResult PddParseOutput(PddDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  660. {
  661. return new APIResult(new
  662. {
  663. result.success,
  664. result.message,
  665. link_type = result.link_type.ToString(),
  666. channel = result?.channel.ToString(),
  667. result.itemId,
  668. result.itemName,
  669. result.shortLinkurl,
  670. result.deeplink_url,
  671. }, code);
  672. }
  673. public static async Task<APIResult> KsParseAsync(string content, string ip, string oaid,
  674. int accountid = 0, CancellationToken cancellationToken = default)
  675. {
  676. var result = KsUnionPlus.GetFormattedObject(content, ip, oaid);
  677. content = content.UrlDecode();
  678. result.rawContent = content;
  679. bool IfExceptional = false;
  680. try
  681. {
  682. var config = TkConfigCore.Get();
  683. if (!string.IsNullOrEmpty(config.ks_blacklist_regular))
  684. {
  685. var blacklist = config.ks_blacklist_regular.Split('\n')
  686. .Where(line => !string.IsNullOrWhiteSpace(line))
  687. .ToList();
  688. bool anyMatch = false;
  689. foreach (string pattern in blacklist)
  690. {
  691. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  692. }
  693. if (anyMatch)
  694. {
  695. result.success = false;
  696. result.deeplink_url = string.Empty;
  697. result.message = "放弃转链";
  698. result.reason = "规则排除";
  699. _ = TkLogCore.ParseLogAsync(result);
  700. return KsParseOutput(result);
  701. }
  702. }
  703. //============================== 放弃转链-地区过滤 ==============================
  704. if (accountid == 0 && KsUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  705. {
  706. result.success = false;
  707. result.message = "放弃转链";
  708. result.reason = reason;
  709. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  710. _ = TkLogCore.ParseLogAsync(result);
  711. return KsParseOutput(result);
  712. }
  713. var account = accountid > 0 ? KsPoolCore.GetOne(accountid, KsPoolCore.KsAction.parse) : KsPoolCore.GetOne(KsPoolCore.KsAction.parse);
  714. if (account == null)
  715. {
  716. result.success = false;
  717. result.message = "放弃转链";
  718. result.reason = "没有匹配账号";
  719. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  720. _ = TkLogCore.ParseLogAsync(result);
  721. return KsParseOutput(result);
  722. }
  723. result.accountId = account.id;
  724. result.accountName = account.name;
  725. var plus = new KsUnionPlus(account);
  726. result = await plus.KsParseAsync(content, result, cancellationToken);
  727. }
  728. catch (Exception ex)
  729. {
  730. if (ex.Message.Contains("was canceled"))
  731. {
  732. result.success = false;
  733. result.message = "放弃转链";
  734. result.reason = "请求超时";
  735. }
  736. else
  737. {
  738. IfExceptional = true;
  739. _ = new LoggerLibrary("unionParse", "jd_error")
  740. .Info(ip, oaid)
  741. .Info(content)
  742. .Info(ex.Message, ex.StackTrace)
  743. .SaveAsync();
  744. NotifyCore.Notify(new NifyMessage
  745. {
  746. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  747. priority = NifyMessagePriority.high,
  748. tags = ["red_circle"]
  749. });
  750. result.success = false;
  751. result.message = "内部错误";
  752. result.reason = "转链接口异常";
  753. }
  754. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  755. }
  756. _ = TkLogCore.ParseLogAsync(result);
  757. return KsParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  758. }
  759. private static APIResult KsParseOutput(KsDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  760. {
  761. return new APIResult(new
  762. {
  763. result.success,
  764. result.message,
  765. link_type = result.link_type.ToString(),
  766. channel = result?.channel.ToString(),
  767. result.itemId,
  768. result.itemName,
  769. result.shortLinkurl,
  770. result.deeplink_url,
  771. }, code);
  772. }
  773. }
  774. }