UnionParseCore.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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. namespace molilian.core
  24. {
  25. public partial class UnionParseCore
  26. {
  27. public static async Task<ActionResult> UnionParseAsync(string content, string channel, string ip, string oaid, int accountid = 0)
  28. {
  29. content = content.Trim();
  30. return channel switch
  31. {
  32. "wemeet" => await WemeetParseAsync(content, ip, oaid),
  33. "bdpan" => PanParse(content, ip, oaid),
  34. "jd" => await JdParseAsync(content, ip, oaid),
  35. "dy" => await DyParseAsync(content, ip, oaid),
  36. _ => await TaobaoParseAsync(content, ip, oaid, accountid),
  37. };
  38. }
  39. public static async Task<APIResult> WemeetParseAsync(string content, string ip, string oaid)
  40. {
  41. var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.wemeet, content, ip, oaid);
  42. content = content.UrlDecode();
  43. result.rawContent = content;
  44. try
  45. {
  46. result = await ToolParsePlus.WemeetParseAsync(content, result);
  47. }
  48. catch (Exception ex)
  49. {
  50. _ = new LoggerLibrary("unionParse", "wemeet_error")
  51. .Info(ip, oaid)
  52. .Info(content)
  53. .Info(ex.Message, ex.StackTrace)
  54. .SaveAsync();
  55. NotifyCore.Notify(new NifyMessage
  56. {
  57. message = $"【转链异常Wemeet】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  58. priority = NifyMessagePriority.high,
  59. tags = ["red_circle"]
  60. });
  61. result.success = false;
  62. result.message = "内部错误";
  63. result.reason = "转链接口异常";
  64. }
  65. _ = TkLogCore.ParseLogAsync(result);
  66. return new APIResult(new
  67. {
  68. result.success,
  69. result.message,
  70. channel = result?.channel.ToString(),
  71. result.shortLinkurl,
  72. result.deeplink_url,
  73. result.itemName,
  74. }, result.success ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
  75. }
  76. public static APIResult PanParse(string content, string ip, string oaid)
  77. {
  78. var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.bdpan, content, ip, oaid);
  79. content = content.UrlDecode();
  80. result.rawContent = content;
  81. try
  82. {
  83. ToolParsePlus.PanParse(content, ref result);
  84. }
  85. catch (Exception ex)
  86. {
  87. _ = new LoggerLibrary("unionParse", "pan_error")
  88. .Info(ip, oaid)
  89. .Info(content)
  90. .Info(ex.Message, ex.StackTrace)
  91. .SaveAsync();
  92. NotifyCore.Notify(new NifyMessage
  93. {
  94. message = $"【转链异常Pan】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  95. priority = NifyMessagePriority.high,
  96. tags = ["red_circle"]
  97. });
  98. result.success = false;
  99. result.message = "内部错误";
  100. result.reason = "转链接口异常";
  101. }
  102. _ = TkLogCore.ParseLogAsync(result);
  103. return new APIResult(new
  104. {
  105. result.success,
  106. result.message,
  107. channel = result?.channel.ToString(),
  108. result.shortLinkurl,
  109. result.deeplink_url,
  110. result.itemName,
  111. }, !string.IsNullOrEmpty(result.deeplink_url) ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
  112. }
  113. private static APIResult TaobaoParseOutput(TkDataDTO result, Dictionary<string, long> swData, object info, APIResultCodeEnum code = APIResultCodeEnum.OK)
  114. {
  115. if (result.elapsedTime > 2000)
  116. {
  117. LoggerLibrary log = new("debug", "stopwatch");
  118. foreach ((var key, var value) in swData)
  119. {
  120. log.Info($"{key}\t{value}");
  121. }
  122. log.SaveAsync();
  123. }
  124. return new APIResult(info, code);
  125. }
  126. public static async Task<APIResult> TaobaoParseAsync(string content,
  127. string ip = "", string oaid = "",
  128. int accountid = 0)
  129. {
  130. AlimamaPlus alimama = null;
  131. //content = content.UrlDecode();
  132. content = content[..Math.Min(1000, content.Length)];
  133. var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
  134. Dictionary<string, long> swData = new();
  135. swData.Add("StartNew", 0);
  136. Stopwatch stopwatch = Stopwatch.StartNew();
  137. result.rawContent = content;
  138. try
  139. {
  140. string reason = string.Empty;
  141. //============================== 放弃转链-平台错误 ==============================
  142. //bool is_other = await AlimamaPlus.OtherPlatformAsync(content);
  143. //if (is_other)
  144. //{
  145. // result.success = false;
  146. // result.message = "放弃转链";
  147. // result.reason = "初步筛选";
  148. // result.itemName = "";
  149. // result.deeplink_url = "";
  150. // _ = TkLogCore.ParseLogAsync(result);
  151. // return TaobaoParseOutput(result, swData, new
  152. // {
  153. // result.success,
  154. // result.message,
  155. // result.content,
  156. // result.itemName,
  157. // result.deeplink_url,
  158. // });
  159. //}
  160. ////一眼要排除
  161. //if (content.Contains("bmlxkyy.com"))
  162. //{
  163. // result.success = false;
  164. // result.message = "放弃转链";
  165. // result.reason = "初步筛选";
  166. // result.itemName = "";
  167. // result.deeplink_url = "";
  168. // _ = TkLogCore.ParseLogAsync(result);
  169. // return TaobaoParseOutput(result, swData, new
  170. // {
  171. // result.success,
  172. // result.message,
  173. // result.content,
  174. // result.itemName,
  175. // result.deeplink_url,
  176. // });
  177. //}
  178. var config = TkConfigCore.Get();
  179. var arr = config.tk_whitelist_regular.Split('\n')
  180. .Where(line => !string.IsNullOrWhiteSpace(line))
  181. .ToList();
  182. var arr2 = config.tk_blacklist_regular.Split('\n')
  183. .Where(line => !string.IsNullOrWhiteSpace(line))
  184. .ToList();
  185. var arr3 = config.multi_token_regular.Split('\n')
  186. .Where(line => !string.IsNullOrWhiteSpace(line))
  187. .ToList();
  188. bool is_tao_url = !string.IsNullOrEmpty(result.shortLinkurl);
  189. bool is_tao_token = AlimamaPlus.MatchRegexes(content, arr);
  190. bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);
  191. //============================== 放弃转链-初步筛选1 ==============================
  192. if (!is_tao_url && !is_tao_token || is_other)
  193. {
  194. //没有链接都放弃
  195. result.success = false;
  196. result.message = "放弃转链";
  197. result.reason = "初步筛选1";
  198. result.itemName = "";
  199. result.deeplink_url = "";
  200. _ = TkLogCore.ParseLogAsync(result);
  201. return TaobaoParseOutput(result, swData, new
  202. {
  203. result.success,
  204. result.message,
  205. result.content,
  206. result.itemName,
  207. result.deeplink_url,
  208. });
  209. }
  210. bool is_multi_token = AlimamaPlus.MatchMultiToken(content, arr3);
  211. //============================== 放弃转链-初步筛选1.5 ==============================
  212. if (is_multi_token)
  213. {
  214. //没有链接都放弃
  215. result.success = false;
  216. result.message = "放弃转链";
  217. result.reason = "初步筛选1.5";
  218. result.itemName = "";
  219. result.deeplink_url = "";
  220. _ = TkLogCore.ParseLogAsync(result);
  221. return TaobaoParseOutput(result, swData, new
  222. {
  223. result.success,
  224. result.message,
  225. result.content,
  226. result.itemName,
  227. result.deeplink_url,
  228. });
  229. }
  230. //============================== 放弃转链-初步筛选2 ==============================
  231. bool is_aff_link = false;
  232. if (!string.IsNullOrEmpty(result.shortLinkurl)) is_aff_link = AlimamaPlus.IsAffLink(result.shortLinkurl);
  233. if ((!is_tao_url && is_tao_token) || is_aff_link)
  234. {
  235. //没有短链接都放弃
  236. result.success = false;
  237. result.message = "放弃转链";
  238. result.reason = "初步筛选2";
  239. result.itemName = "点击打开淘宝APP";
  240. _ = TkLogCore.ParseLogAsync(result);
  241. return TaobaoParseOutput(result, swData, new
  242. {
  243. result.success,
  244. result.message,
  245. result.content,
  246. result.itemName,
  247. result.deeplink_url,
  248. });
  249. }
  250. //============================== 放弃转链-地区过滤 ==============================
  251. bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, out reason);
  252. if (is_ignore2)
  253. {
  254. result.success = false;
  255. result.message = "放弃转链";
  256. result.itemName = "点击打开淘宝APP";
  257. result.reason = reason;
  258. _ = TkLogCore.ParseLogAsync(result);
  259. return TaobaoParseOutput(result, swData, new
  260. {
  261. result.success,
  262. result.message,
  263. result.content,
  264. result.itemName,
  265. result.deeplink_url,
  266. });
  267. }
  268. ////============================== 放弃转链-初步筛选 ==============================
  269. //bool is_ignore = AlimamaPlus.FirstFilterIgnoreRequest(content, out reason);
  270. //if (string.IsNullOrEmpty(result.shortLinkurl) && is_ignore)
  271. //{
  272. // //没有短链接都放弃
  273. // result.success = false;
  274. // result.message = "放弃转链";
  275. // result.itemName = "点击打开淘宝APP";
  276. // result.reason = "初步筛选";
  277. // _ = TkLogCore.ParseLogAsync(result);
  278. // return TaobaoParseOutput(result, swData, new
  279. // {
  280. // result.success,
  281. // result.message,
  282. // result.content,
  283. // result.itemName,
  284. // result.deeplink_url,
  285. // });
  286. //}
  287. //============================== 放弃转链-没有匹配账号 ==============================
  288. TkPoolDTO? account = accountid > 0 ?
  289. TkPoolCore.GetOne(accountid) :
  290. TkPoolCore.GetOne(TkPoolCore.TkAction.parse);
  291. if (account == null)
  292. {
  293. result.success = false;
  294. result.message = "放弃转链";
  295. result.reason = "没有匹配账号";
  296. result.itemName = "点击打开淘宝APP";
  297. _ = TkLogCore.ParseLogAsync(result);
  298. return TaobaoParseOutput(result, swData, new
  299. {
  300. result.success,
  301. result.message,
  302. result.content,
  303. result.couponAmount,
  304. result.taoToken,
  305. result.shortLinkurl,
  306. result.deeplink_url,
  307. });
  308. }
  309. result.accountId = account.id;
  310. result.accountName = account.company;
  311. alimama = new AlimamaPlus(account);
  312. int timeout = alimama._config.rt_max;
  313. using var cts = new CancellationTokenSource();
  314. cts.CancelAfter(timeout);
  315. var requestTask = Task.Run(() => alimama.UnionParse2Async(content, result, cts.Token, swData), cts.Token);
  316. var delayTask = Task.Delay(timeout, cts.Token);
  317. var completedTask = await Task.WhenAny(requestTask, delayTask);
  318. if (completedTask == requestTask)
  319. {
  320. result = await requestTask;
  321. }
  322. else
  323. {
  324. //============================== 放弃转链-请求超时 ==============================
  325. cts.Cancel();
  326. result.success = false;
  327. result.message = "放弃转链";
  328. result.reason = "请求超时";
  329. result.itemName = "点击打开淘宝APP";
  330. }
  331. result.accountName = account.company;
  332. //result = await alimama.UnionParse2Async(content, result);
  333. }
  334. catch (Exception ex)
  335. {
  336. //============================== 放弃转链-请求超时 ==============================
  337. if (ex.Message.Contains("was canceled"))
  338. {
  339. result.success = false;
  340. result.message = "放弃转链";
  341. result.reason = "请求超时";
  342. result.itemName = "点击打开淘宝APP";
  343. }
  344. else
  345. {
  346. //============================== 转链接口异常 ==============================
  347. _ = new LoggerLibrary("unionParse", "tb_error")
  348. .Info(ip, oaid)
  349. .Info(content)
  350. .Info(ex.Message, ex.StackTrace)
  351. .SaveAsync();
  352. NotifyCore.Notify(new NifyMessage
  353. {
  354. message = $"【转链异常TB】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  355. priority = NifyMessagePriority.high,
  356. tags = ["red_circle"]
  357. });
  358. result.success = false;
  359. result.message = "转链接口异常";
  360. result.itemName = "点击打开淘宝APP";
  361. }
  362. }
  363. _ = TkLogCore.ParseLogAsync(result, alimama);
  364. return TaobaoParseOutput(result, swData, new
  365. {
  366. result.success,
  367. result.message,
  368. link_type = result.link_type.ToString(),
  369. channel = result?.channel.ToString(),
  370. result.channel_type,
  371. result.itemId,
  372. result.itemName,
  373. result.pic,
  374. result.promotionPrice,
  375. result.couponAmount,
  376. result.couponEffectiveStartTime,
  377. result?.couponEffectiveEndTime,
  378. result.shortLinkurl,
  379. result.deeplink_url,
  380. result.content,
  381. result.taoToken,
  382. });
  383. }
  384. public static async Task<APIResult> JdParseAsync(string content, string ip, string oaid, 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. if (JdUnionPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  393. {
  394. result.success = false;
  395. result.message = "放弃转链";
  396. result.reason = reason;
  397. _ = TkLogCore.ParseLogAsync(result);
  398. return new APIResult(result);
  399. }
  400. var account = JdPoolCore.GetOne();
  401. if (account == null)
  402. {
  403. result.success = false;
  404. result.message = "放弃转链";
  405. result.reason = "没有匹配账号";
  406. _ = TkLogCore.ParseLogAsync(result);
  407. return new APIResult(result);
  408. }
  409. result = await JdUnionPlus.JdParseAsync(account, content, result, cancellationToken);
  410. }
  411. catch (Exception ex)
  412. {
  413. if (ex.Message.Contains("was canceled"))
  414. {
  415. result.success = false;
  416. result.message = "放弃转链";
  417. result.reason = "请求超时";
  418. }
  419. else
  420. {
  421. IfExceptional = true;
  422. _ = new LoggerLibrary("unionParse", "jd_error")
  423. .Info(ip, oaid)
  424. .Info(content)
  425. .Info(ex.Message, ex.StackTrace)
  426. .SaveAsync();
  427. NotifyCore.Notify(new NifyMessage
  428. {
  429. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  430. priority = NifyMessagePriority.high,
  431. tags = ["red_circle"]
  432. });
  433. result.success = false;
  434. result.message = "内部错误";
  435. result.reason = "转链接口异常";
  436. }
  437. }
  438. _ = TkLogCore.ParseLogAsync(result);
  439. return new APIResult(new
  440. {
  441. result.success,
  442. result.message,
  443. link_type = result.link_type.ToString(),
  444. channel = result?.channel.ToString(),
  445. result.channel_type,
  446. result.itemId,
  447. result.itemName,
  448. result.shortLinkurl,
  449. result.deeplink_url,
  450. }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  451. }
  452. public static async Task<APIResult> DyParseAsync(string content, string ip, string oaid, CancellationToken cancellationToken = default)
  453. {
  454. var result = DyUnionPlus.GetFormattedObject(content, ip, oaid);
  455. content = content.UrlDecode();
  456. result.rawContent = content;
  457. bool IfExceptional = false;
  458. try
  459. {
  460. // 2024-06-19 联盟业务下线
  461. result.success = false;
  462. result.message = "放弃转链";
  463. result.reason = "联盟下线";
  464. _ = TkLogCore.ParseLogAsync(result);
  465. return new APIResult(result);
  466. if (DyUnionPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  467. {
  468. result.success = false;
  469. result.message = "放弃转链";
  470. result.reason = reason;
  471. _ = TkLogCore.ParseLogAsync(result);
  472. return new APIResult(result);
  473. }
  474. var account = PangolinPoolCore.GetOne();
  475. if (account == null)
  476. {
  477. result.success = false;
  478. result.message = "放弃转链";
  479. result.reason = "没有匹配账号";
  480. _ = TkLogCore.ParseLogAsync(result);
  481. return new APIResult(result);
  482. }
  483. result = await DyUnionPlus.DyParseAsync(account, content, result, cancellationToken);
  484. }
  485. catch (Exception ex)
  486. {
  487. if (ex.Message.Contains("was canceled"))
  488. {
  489. result.success = false;
  490. result.message = "放弃转链";
  491. result.reason = "请求超时";
  492. }
  493. else
  494. {
  495. IfExceptional = true;
  496. _ = new LoggerLibrary("unionParse", "dy_error")
  497. .Info(ip, oaid)
  498. .Info(content)
  499. .Info(ex.Message, ex.StackTrace)
  500. .SaveAsync();
  501. NotifyCore.Notify(new NifyMessage
  502. {
  503. message = $"【转链异常DY】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  504. priority = NifyMessagePriority.high,
  505. tags = ["red_circle"]
  506. });
  507. result.success = false;
  508. result.message = "内部错误";
  509. result.reason = "转链接口异常";
  510. }
  511. }
  512. _ = TkLogCore.ParseLogAsync(result);
  513. return new APIResult(new
  514. {
  515. result.success,
  516. result.message,
  517. link_type = result.link_type.ToString(),
  518. channel = result?.channel.ToString(),
  519. content = result?.rawContent.ToString(),
  520. taoToken = result?.taoToken.ToString(),
  521. result.channel_type,
  522. result.itemName,
  523. result.shortLinkurl,
  524. result.deeplink_url,
  525. }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  526. }
  527. }
  528. }