UnionParseCore.cs 27 KB

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