UnionParseCore.cs 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728
  1. using dodohold.core;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System.Diagnostics;
  4. using System.Text.RegularExpressions;
  5. namespace molilian.core
  6. {
  7. public partial class UnionParseCore
  8. {
  9. public static async Task<ActionResult> UnionParseAsync(string content, string channel, int commerceType, string ip, string oaid, string riskStrategy, int launchScene, int accountid = 0, string clickId = "", string type = "")
  10. {
  11. content = content.Trim();
  12. if ("dp".Equals(type))
  13. {
  14. return channel switch
  15. {
  16. "jd" => await DeeplinkJdParseAsync(content, commerceType, ip, oaid, riskStrategy, launchScene, accountid, clickId),
  17. "pdd" => await DeeplinkPddParseAsync(content, commerceType, ip, oaid, accountid),
  18. "tb" => await DeeplinkTaobaoParseAsync(content, commerceType, ip, oaid, riskStrategy, launchScene, accountid),
  19. };
  20. }
  21. return channel switch
  22. {
  23. "wemeet" => await WemeetParseAsync(content, ip, oaid),
  24. "bdpan" => PanParse(content, ip, oaid),
  25. "jd" => await JdParseAsync(content, commerceType, ip, oaid, riskStrategy, launchScene, accountid, clickId),
  26. "ks" => await KsParseAsync(content, commerceType, ip, oaid, accountid),
  27. "dy" => await DyParseAsync(content, commerceType, ip, oaid),
  28. "pdd" => await PddParseAsync(content, commerceType, ip, oaid, accountid),
  29. "tb" => await TaobaoParseAsync(content, commerceType, ip, oaid, riskStrategy, launchScene, accountid),
  30. _ => await DeeplinkParseCore.ParseAsync(content, channel, ip, oaid),
  31. };
  32. }
  33. //return await DeeplinkParseCore.ParseAsync(content, channel, ip, oaid);
  34. public static async Task<APIResult> WemeetParseAsync(string content, string ip, string oaid)
  35. {
  36. var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.wemeet, content, ip, oaid);
  37. content = content.UrlDecode();
  38. result.rawContent = content;
  39. try
  40. {
  41. result = await ToolParsePlus.WemeetParseAsync(content, result);
  42. }
  43. catch (Exception ex)
  44. {
  45. _ = new LoggerLibrary("unionParse", "wemeet_error")
  46. .Info(ip, oaid)
  47. .Info(content)
  48. .Info(ex.Message, ex.StackTrace)
  49. .SaveAsync();
  50. NotifyCore.Notify(new NifyMessage
  51. {
  52. message = $"【转链异常Wemeet】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  53. priority = NifyMessagePriority.high,
  54. tags = ["red_circle"]
  55. });
  56. result.success = false;
  57. result.message = "内部错误";
  58. result.reason = "转链接口异常";
  59. }
  60. _ = TkLogCore.ParseLogAsync(result);
  61. return new APIResult(new
  62. {
  63. result.success,
  64. result.message,
  65. channel = result?.channel.ToString(),
  66. result.shortLinkurl,
  67. result.deeplink_url,
  68. result.itemName,
  69. }, result.success ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
  70. }
  71. public static APIResult PanParse(string content, string ip, string oaid)
  72. {
  73. var result = ToolParsePlus.GetFormattedObject(TkChannelEnum.bdpan, content, ip, oaid);
  74. content = content.UrlDecode();
  75. result.rawContent = content;
  76. try
  77. {
  78. ToolParsePlus.PanParse(content, ref result);
  79. }
  80. catch (Exception ex)
  81. {
  82. _ = new LoggerLibrary("unionParse", "pan_error")
  83. .Info(ip, oaid)
  84. .Info(content)
  85. .Info(ex.Message, ex.StackTrace)
  86. .SaveAsync();
  87. NotifyCore.Notify(new NifyMessage
  88. {
  89. message = $"【转链异常Pan】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  90. priority = NifyMessagePriority.high,
  91. tags = ["red_circle"]
  92. });
  93. result.success = false;
  94. result.message = "内部错误";
  95. result.reason = "转链接口异常";
  96. }
  97. _ = TkLogCore.ParseLogAsync(result);
  98. return new APIResult(new
  99. {
  100. result.success,
  101. result.message,
  102. channel = result?.channel.ToString(),
  103. result.shortLinkurl,
  104. result.deeplink_url,
  105. result.itemName,
  106. }, !string.IsNullOrEmpty(result.deeplink_url) ? APIResultCodeEnum.OK : APIResultCodeEnum.NotAcceptable);
  107. }
  108. private static APIResult TaobaoParseOutput(TkDataDTO result, Dictionary<string, long> swData, object info, APIResultCodeEnum code = APIResultCodeEnum.OK)
  109. {
  110. if (result.elapsedTime > 2000)
  111. {
  112. LoggerLibrary log = new("debug", "stopwatch");
  113. foreach ((var key, var value) in swData)
  114. {
  115. log.Info($"{key}\t{value}");
  116. }
  117. log.SaveAsync();
  118. }
  119. return new APIResult(info, code);
  120. }
  121. private static string parseDeeplinkInput(string content)
  122. {
  123. //detail.tmall.com
  124. //item.taobao.com
  125. //没有 ali_trackid 参数就转链
  126. if (content.StartsWith("tbopen://") || content.StartsWith("tmall://"))
  127. {
  128. string url = content.GetContentPart("h5Url=", "&");
  129. if (string.IsNullOrEmpty(url))
  130. {
  131. url = content.GetContentPart("h5Url=", "");
  132. }
  133. if (string.IsNullOrEmpty(url)) return content;
  134. content = url.UrlDecode();
  135. }
  136. if (content.StartsWith("openapp.jdmobile://"))
  137. {
  138. try
  139. {
  140. string param = content.GetContentPart("params=", "");
  141. param = param.UrlDecode();
  142. var root = param.Convert2JsonElement();
  143. string category = root.Read("category", string.Empty);
  144. string sourceType = root.Read("sourceType", string.Empty);
  145. string skuId = root.Read("skuId", string.Empty);
  146. switch (sourceType)
  147. {
  148. case "Item":
  149. string url_content = $"https://item.jd.com/{skuId}.html";
  150. return url_content;
  151. }
  152. switch (category)
  153. {
  154. case "jump":
  155. string url = root.Read("url", string.Empty);
  156. string url_content = url;
  157. return url_content;
  158. }
  159. }
  160. catch (Exception ex)
  161. {
  162. }
  163. }
  164. //tmall://page.tm/appLink?h5Url=https%3A%2F%2Fdetail.tmall.com%2Fitem.htm%3Fid%3D629542722592%26share_channel%3Ddetail%26paidshareToken%3D842B5476D9A0B364D5CC650F238292E3CFB595CDC22393CD60DAD29D99CDB28859466A4E043DC620792D1206C14333CF4494C856B7CB8E4E%26sourceType%3Dother%26suid%3D8daeb0cc-87f9-44c9-b530-aa4566945452%26ut_sk%3D1.Z9jmzqkFuPsDANvbV379%252FPgp_23181017_1752503741948.Copy.tm_detailbenefitshare%26un%3Df6b7d60f206d27bb88bd3787856a60a9%26share_crt_v%3D1%26un_site%3D0%26spm%3Da2159r.13376460.0.0%26sp_tk%3DR25MWDQxc3FYTUE%253D%26cpp%3D1%26shareurl%3Dtrue%26short_name%3Dh.hRhri7E%26bxsign%3DscdGJqiqt-937BvSp8SKU1sftPqjbSV-mN9PO9uSUpCQixolsthqN0L8lXUUcfE3z7Px0CurYbiqaK7Zu4nTznXTD9SNYSFZAWkd-quYKZBNgwpfIA5kJabJs1rRFphfw19%26tk%3DGnLX41sqXMA%2520CZ321%26app%3Dchrome%26sharingreflow%3Dh5%26bc_fl_src%3Dtmapp_detail_new%26traceId%3D1101041752523106267mmWuHUrYERQCA&module=h5&action=ali.open.nav&bc_fl_src=tmapp_detail_new&splash=9455fa72420237eb&traceId=1101041752523106267mmWuHUrYERQCA
  165. //intent://m.taobao.com/tbopen/index.html?h5Url=https%3A%2F%2Fpages-fast.m.taobao.com%2Fwow%2Fz%2Fapp%2Fltao-fe%2Fxsms-ssr-yyds%2Fexternal%3Fx-ssr%3Dtrue%26x-preload%3Dtrue%26x-sec%3Dwua%26disableProgress%3Dtrue%26disableNav%3DYES%26skeleton%3Dtrue%26asac%3D2A241230082ZOWK433A270%26forceThemis%3Dtrue%26status_bar_transparent%3Dtrue%26feedsCeiling%3Dtrue%26spmb%3Dmssharereturntb_base%26itemIds%3D902307586145%26src%3Dmsdetail%26isCallApp%3D1%26slk_gid%3Dgid_er_sidebar_0&action=ali.open.nav&module=h5&bootImage=0&slk_sid=vk/8IEUpYEoCARudLiPeC+y9_1752523360882&slk_t=1752523366491&slk_gid=gid_er_sidebar_0&afcPromotionOpen=false&bc_fl_src=h5_huanduan&source=slk_intent
  166. // tbopen://m.taobao.com/tbopen/index.html?action=ali.open.nav&module=h5&h5Url=https%3A%2F%2Fdetail.m.tmall.com%2Fitem.htm%3Fid%3D838442214976%26ali_trackid%3D2%3Amm_7770555492_3286350431_116030600497%3A1752523820207_557769320_0%26union_lens%3DlensId%3AOPT%401752508785%402135dbda_1303_19809a9e462_5d67%4001%40eyJmbG9vcklkIjo3MzM2N30ie%3Brecoveryid%3A557769320_0%401752523820210%26e%3DdXNALs0LOL32LDtfC7ZWu9EHLliVjxj7pU0YSYyMuITov3hgGO6cv43ak0M1RdoZhIY4r_DZTS7AIWf4uHY1l_zk9mjzcRPpAiUi6ISdl6tIQmqgSGrWBp4zrUrX30wzt5CoaUxHdgDcvlGY0FFw4AsSCrC98Ev3WwYNKzSCQESWOsgjI-_XQgIvzXlgEI89__I9gNxCnRWuLFbjX-6pADavg52v_HkHibcVNsFgxnVy52oYpKpvhmw_NFRtQD3PDSi1wLFUrWN_6nC8CG3HZzcKOEjMTefgpXU0JQv0wvGdjkXaNLJcTxH-LDKBJRbbUD-4jMAahepVY0FqvKyrNwo5h4XpPi-KwY3mRR37mYRk2qVlYBujxeXrXDgNuUfueXX72mp250XDG_1N5hlzNg%26type%3D2%26tk_cps_param%3D7770555492%26tkFlag%3D0%26tk_cps_ut%3D2%26bxsign%3Dtbkcb7FZp7TFdkfoQXHOByuFz_a0nDGWCqDV8BNKko5E73a65lh_x913EERrie6TvaWs7hDm2suzCAC_Q7KTXaHf8L6aOHPYNkJAwvON3bQRhfCIZWwiW14-Ws9DtJvqpvgeE76f_3H9O_RCdTJRsGvBcsNfJnkHdRYGo2t4m-mMnEy0GiLAZo_ahkGsuwzoKVi
  167. //openapp.jdmobile://virtual?params=%7B%22category%22%3A%22jump%22%2C%22des%22%3A%22productDetail%22%2C%22skuId%22%3A%2210153596800839%22%2C%22sourceType%22%3A%22Item%22%2C%22sourceValue%22%3A%22view-ware%22%2C%22utm_term_m%22%3A%22654711b5a69048ed8e277944bd840205%22%2C%22M_sourceFrom%22%3A%22sxbanner%22%2C%22yinliuExt%22%3A%22exp-base___bXBhZ2VhY3RpdmVfNzY5NjJ8ZXhwLWJhc2U%22%2C%22msf_type%22%3A%22click%22%2C%22m_param%22%3A%7B%22m_source%22%3A%220%22%2C%22jda%22%3A%22181111935.17520759467211334439509.1752075947.1752523405.1752523435.4%22%2C%22usc%22%3A%22lianmeng__9__kong%22%2C%22ucp%22%3A%22t_2035161610_%22%2C%22umd%22%3A%22tuiguang%22%2C%22utr%22%3A%22654711b5a69048ed8e277944bd840205%22%2C%22jdv%22%3A%22181111935%7Clianmeng__9__kong%7Ct_2035161610_%7Ctuiguang%7C654711b5a69048ed8e277944bd840205%7C1752523436869%22%2C%22ref%22%3A%22https%3A%2F%2Fitem.m.jd.com%2Fproduct%2F10153596800839.html%3Fcu%3Dtrue%26utm_source%3Dlianmeng__9__kong%26utm_medium%3Dtuiguang%26utm_campaign%3Dt_2035161610_%26utm_term%3D654711b5a69048ed8e277944bd840205%22%2C%22psn%22%3A%2217520759467211334439509%7C4%22%2C%22psq%22%3A1%2C%22unpl%22%3A%22JF8EAK9nNSttX09RAxsCSBZATFVVW1RcHh5XbGEDXFhdGAEMHgMYExR7XlVdWRRKER9vYxRVWFNKVg4fCisSF3teVVxZCEwXBG9mNWRaWEIZRElPKxEQe1xkXlsMSBYFa28AU1tbS1QHGQceEBhPXFxuXDhMFwpfZwRUWVpPXAISAxobEkNtZF9tCXsWMy4JBVRUW05XDRhPGxQUSFxSWlUNTBEAb2cHVlhdSVwBGgorEyBI%22%2C%22pc_source%22%3A%22%22%2C%22mba_muid%22%3A%2217520759467211334439509%22%2C%22mba_sid%22%3A%2217525234051972092463856%22%2C%22std%22%3A%22MO-J2011-1%22%2C%22par%22%3A%22cu%3Dtrue%26utm_source%3Dlianmeng__9__kong%26utm_medium%3Dtuiguang%26utm_campaign%3Dt_2035161610_%26utm_term%3D654711b5a69048ed8e277944bd840205%22%2C%22event_id%22%3A%22MDownLoadFloat_ClickOpenApp%22%2C%22mt_xid%22%3A%22%22%2C%22mt_subsite%22%3A%22%22%2C%22YINLIUhuanqi%22%3A%22https%3A%2F%2Fitem.m.jd.com%2Fproduct%2F10153596800839.html%3Fcu%3Dtrue%26utm_source%3Dlianmeng__9__kong%26utm_medium%3Dtuiguang%26utm_campaign%3Dt_2035161610_%26utm_term%3D654711b5a69048ed8e277944bd840205%22%2C%22yls%22%3A%22sh_bt_%22%2C%22ylb%22%3A%22safari%22%2C%22yld%22%3A%22iphone%22%2C%22ylh%22%3A%22https%3A%2F%2Fitem.m.jd.com%2Fproduct%2F10153596800839.html%22%2C%22yle%22%3A%5B%5D%2C%22ylle%22%3A%22%22%2C%22ylo%22%3A%22ios%22%7D%2C%22SE%22%3A%7B%22mt_subsite%22%3A%22%22%2C%22__jdv%22%3A%22181111935%7Clianmeng__9__kong%7Ct_2035161610_%7Ctuiguang%7C654711b5a69048ed8e277944bd840205%7C1752523436869%22%2C%22unpl%22%3A%22JF8EAK9nNSttX09RAxsCSBZATFVVW1RcHh5XbGEDXFhdGAEMHgMYExR7XlVdWRRKER9vYxRVWFNKVg4fCisSF3teVVxZCEwXBG9mNWRaWEIZRElPKxEQe1xkXlsMSBYFa28AU1tbS1QHGQceEBhPXFxuXDhMFwpfZwRUWVpPXAISAxobEkNtZF9tCXsWMy4JBVRUW05XDRhPGxQUSFxSWlUNTBEAb2cHVlhdSVwBGgorEyBI%22%2C%22__jda%22%3A%22181111935.17520759467211334439509.1752075947.1752523405.1752523435.4%22%7D%7D
  168. return content;
  169. }
  170. public static async Task<APIResult> TaobaoParseAsync(string content, int commerceType,
  171. string ip = "", string oaid = "", string riskStrategy = "", int launchScene = 0,
  172. int accountid = 0)
  173. {
  174. bool other_aff = false;
  175. AlimamaPlus alimama = null;
  176. //content = content.UrlDecode();
  177. var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
  178. result.riskStrategy = riskStrategy;
  179. result.launchScene = launchScene;
  180. result.rawContent = content;
  181. Dictionary<string, long> swData = new();
  182. swData.Add("StartNew", 0);
  183. Stopwatch stopwatch = Stopwatch.StartNew();
  184. try
  185. {
  186. content = content[..Math.Min(1000, content.Length)];
  187. string reason = string.Empty;
  188. var config = TkConfigCore.Get();
  189. var arr = config.tk_whitelist_regular.Split('\n')
  190. .Where(line => !string.IsNullOrWhiteSpace(line))
  191. .ToList();
  192. var arr2 = config.tk_blacklist_regular.Split('\n')
  193. .Where(line => !string.IsNullOrWhiteSpace(line))
  194. .ToList();
  195. var arr3 = config.multi_token_regular.Split('\n')
  196. .Where(line => !string.IsNullOrWhiteSpace(line))
  197. .ToList();
  198. bool is_tao_url = !string.IsNullOrEmpty(result.shortLinkurl);
  199. bool is_tao_token = AlimamaPlus.MatchRegexes(content, arr);
  200. bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);
  201. //============================== 放弃转链-初步筛选1 ==============================
  202. if (!is_tao_url && !is_tao_token || is_other)
  203. {
  204. //没有链接都放弃
  205. result.success = false;
  206. result.message = "放弃转链";
  207. result.reason = "初步筛选1";
  208. result.subCode = TkSubCodeEnum.Prelim1;
  209. result.itemName = "";
  210. result.deeplink_url = string.Empty;
  211. _ = TkLogCore.ParseLogAsync(result);
  212. return TaobaoParseOutput(result, swData, new
  213. {
  214. result.success,
  215. result.commercial,
  216. result.message,
  217. result.content,
  218. result.itemName,
  219. other_aff,
  220. result.deeplink_url,
  221. });
  222. }
  223. bool is_multi_token = AlimamaPlus.MatchMultiToken(content, arr3);
  224. //============================== 放弃转链-初步筛选1.5 ==============================
  225. if (is_multi_token)
  226. {
  227. //没有链接都放弃
  228. result.success = false;
  229. result.message = "放弃转链";
  230. result.reason = "初步筛选1.5";
  231. result.subCode = TkSubCodeEnum.Prelim1_5;
  232. result.itemName = "";
  233. result.deeplink_url = string.Empty;
  234. _ = TkLogCore.ParseLogAsync(result);
  235. return TaobaoParseOutput(result, swData, new
  236. {
  237. result.success,
  238. result.commercial,
  239. result.message,
  240. result.content,
  241. result.itemName,
  242. other_aff,
  243. result.deeplink_url,
  244. });
  245. }
  246. //============================== 放弃转链-初步筛选2 ==============================
  247. bool is_aff_link = false;
  248. if (!string.IsNullOrEmpty(result.shortLinkurl)) is_aff_link = AlimamaPlus.IsAffLink(result.shortLinkurl);
  249. if (!is_tao_url && is_tao_token)
  250. {
  251. //淘宝口令
  252. result.success = false;
  253. result.message = "放弃转链";
  254. result.reason = "初步筛选2";
  255. result.subCode = TkSubCodeEnum.Prelim2;
  256. result.itemName = "点击打开淘宝APP";
  257. _ = TkLogCore.ParseLogAsync(result);
  258. //20241229 特例
  259. //if ("bj".Equals(EndPointCore.CurrentEndPoint))
  260. //{
  261. // string ruleKey = $"tmp_rules2:tb:{DateTime.Now:yyyyMMdd}";
  262. // var count = RedisHelper.Get<int>(ruleKey);
  263. // var now = DateTime.Now;
  264. // if (now > new DateTime(2024, 12, 19) && now <= new DateTime(2024, 12, 22) && now.Hour >= 7 && count < 1000)
  265. // {
  266. // result.deeplink_url = "tbopen://m.taobao.com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&afc_route=1&bc_fl_src=growth_dhh_2200803434968_100-1930985-1595034112&dpa_Inid=159503411212096&dpa_material_id=530637422585&dpa_material_type=1&dpa_source_code=12096&force_no_smb=true&h5Url=https%3A%2F%2Fs.m.taobao.com%2Fh5%3Ffrom%3Dcustoms%26g_channelSrp%3Ddhhdpa_1232552832%26dpa_material_type%3D1%26ut_sk%3Dsearch%26spm%3Da2141.mb819t211c7%26sLaunch%3D0%26sKeep%3D1%26sModuleName%3Dsearch%26spm_back_up%3Da2141.mb819t211c7%26bc_fl_src%3Dgrowth_dhh_2200803434968_100-1930985-1595034112%26dpa_Inid%3D159503411212096%26dpa_material_id%3D530637422585%26dpa_material_type%3D1%26dpa_source_code%3D12096%26force_no_smb%3Dtrue%26itemIds%3D530637422585%26slk_actid%3D100000000207%26spm%3D2014.ugdhh.2200803434968.100-1930985-1595034112%26wh_biz%3Dtm&itemIds=530637422585&slk_actid=100000000207&spm=2014.ugdhh.2200803434968.100-1930985-1595034112&wh_biz=tm";
  267. // RedisHelper.IncrBy(ruleKey);
  268. // RedisHelper.Expire(ruleKey, 86400 * 1);
  269. // }
  270. //}
  271. other_aff = true;
  272. return TaobaoParseOutput(result, swData, new
  273. {
  274. result.success,
  275. result.commercial,
  276. result.message,
  277. result.content,
  278. result.itemName,
  279. other_aff,
  280. result.deeplink_url,
  281. });
  282. }
  283. if ((!is_tao_url && is_tao_token) || is_aff_link)
  284. {
  285. //没有短链接都放弃
  286. result.success = false;
  287. result.message = "放弃转链";
  288. result.reason = "初步筛选2";
  289. result.subCode = TkSubCodeEnum.Prelim2;
  290. result.itemName = "点击打开淘宝APP";
  291. _ = TkLogCore.ParseLogAsync(result);
  292. //20241229 特例
  293. //if ("bj".Equals(EndPointCore.CurrentEndPoint))
  294. //{
  295. // string ruleKey = $"tmp_rules2:tb:{DateTime.Now:yyyyMMdd}";
  296. // var count = RedisHelper.Get<int>(ruleKey);
  297. // var now = DateTime.Now;
  298. // if (now > new DateTime(2024, 12, 19) && now <= new DateTime(2024, 12, 22) && now.Hour >= 7 && count < 1000)
  299. // {
  300. // result.deeplink_url = "tbopen://m.taobao.com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&afc_route=1&bc_fl_src=growth_dhh_2200803434968_100-1930985-1595034112&dpa_Inid=159503411212096&dpa_material_id=530637422585&dpa_material_type=1&dpa_source_code=12096&force_no_smb=true&h5Url=https%3A%2F%2Fs.m.taobao.com%2Fh5%3Ffrom%3Dcustoms%26g_channelSrp%3Ddhhdpa_1232552832%26dpa_material_type%3D1%26ut_sk%3Dsearch%26spm%3Da2141.mb819t211c7%26sLaunch%3D0%26sKeep%3D1%26sModuleName%3Dsearch%26spm_back_up%3Da2141.mb819t211c7%26bc_fl_src%3Dgrowth_dhh_2200803434968_100-1930985-1595034112%26dpa_Inid%3D159503411212096%26dpa_material_id%3D530637422585%26dpa_material_type%3D1%26dpa_source_code%3D12096%26force_no_smb%3Dtrue%26itemIds%3D530637422585%26slk_actid%3D100000000207%26spm%3D2014.ugdhh.2200803434968.100-1930985-1595034112%26wh_biz%3Dtm&itemIds=530637422585&slk_actid=100000000207&spm=2014.ugdhh.2200803434968.100-1930985-1595034112&wh_biz=tm";
  301. // RedisHelper.IncrBy(ruleKey);
  302. // RedisHelper.Expire(ruleKey, 86400 * 1);
  303. // }
  304. //}
  305. other_aff = true;
  306. return TaobaoParseOutput(result, swData, new
  307. {
  308. result.success,
  309. result.commercial,
  310. result.message,
  311. result.content,
  312. result.itemName,
  313. other_aff,
  314. result.deeplink_url,
  315. });
  316. }
  317. //那就初步筛选3 有tb.cn 并且有 or 手淘发现
  318. string pattern = @"^(?!【淘宝】).*https?:\/\/m\.tb\.cn.*(?:手淘发现|手淘搜索)";
  319. bool isMatch = Regex.IsMatch(content, pattern);
  320. if (isMatch)
  321. {
  322. result.success = false;
  323. result.message = "放弃转链";
  324. result.reason = "初步筛选3";
  325. result.subCode = TkSubCodeEnum.Prelim3;
  326. result.itemName = "点击打开淘宝APP";
  327. _ = TkLogCore.ParseLogAsync(result);
  328. return TaobaoParseOutput(result, swData, new
  329. {
  330. result.success,
  331. result.commercial,
  332. result.message,
  333. result.content,
  334. result.itemName,
  335. other_aff,
  336. result.deeplink_url,
  337. });
  338. }
  339. //============================== 放弃转链-地区过滤 ==============================
  340. bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, riskStrategy, launchScene, out reason);
  341. if (is_ignore2)
  342. {
  343. result.success = false;
  344. result.message = "放弃转链";
  345. result.itemName = "点击打开淘宝APP";
  346. result.reason = reason;
  347. result.subCode = TkSubCodeEnum.TrafficCtrl;
  348. _ = TkLogCore.ParseLogAsync(result);
  349. return TaobaoParseOutput(result, swData, new
  350. {
  351. result.success,
  352. result.commercial,
  353. result.message,
  354. result.content,
  355. result.itemName,
  356. other_aff,
  357. result.deeplink_url,
  358. });
  359. }
  360. (bool isTaobaoUrl, string url) = AlimamaPlus.IsTaobaoUrl(content);
  361. //============================== 放弃转链-没有匹配账号 ==============================
  362. TkPoolDTO? account = accountid > 0 ?
  363. await TkPoolCore.GetOneAsync(accountid) :
  364. await TkPoolCore.GetOneAsync(TkPoolCore.TkAction.parse, isTaobaoUrl, riskStrategy, launchScene);
  365. if (account == null)
  366. {
  367. result.success = false;
  368. result.message = "放弃转链";
  369. result.reason = "没有匹配账号";
  370. result.subCode = TkSubCodeEnum.Other;
  371. result.itemName = "点击打开淘宝APP";
  372. _ = TkLogCore.ParseLogAsync(result);
  373. return TaobaoParseOutput(result, swData, new
  374. {
  375. result.success,
  376. result.commercial,
  377. result.message,
  378. result.content,
  379. result.couponAmount,
  380. result.taoToken,
  381. result.shortLinkurl,
  382. other_aff,
  383. result.deeplink_url,
  384. });
  385. }
  386. result.accountId = account.id;
  387. result.accountName = account.company;
  388. alimama = new AlimamaPlus(account);
  389. int timeout = alimama._config.rt_max;
  390. #if DEBUG
  391. timeout = 10000;
  392. #endif
  393. using var cts = new CancellationTokenSource();
  394. cts.CancelAfter(timeout);
  395. var requestTask = Task.Run(() => alimama.UnionParseAsync(ip, oaid, content, commerceType, result, isTaobaoUrl, riskStrategy, launchScene, cts.Token, swData), cts.Token);
  396. var delayTask = Task.Delay(timeout, cts.Token);
  397. var completedTask = await Task.WhenAny(requestTask, delayTask);
  398. if (completedTask == requestTask)
  399. {
  400. result = await requestTask;
  401. }
  402. else
  403. {
  404. //============================== 放弃转链-请求超时 ==============================
  405. cts.Cancel();
  406. result.success = false;
  407. result.message = "放弃转链";
  408. result.reason = "请求超时";
  409. result.subCode = TkSubCodeEnum.Other;
  410. result.itemName = "点击打开淘宝APP";
  411. }
  412. result.accountName = account.company;
  413. //result = await alimama.UnionParse2Async(content, result);
  414. }
  415. catch (Exception ex)
  416. {
  417. //============================== 放弃转链-请求超时 ==============================
  418. if (ex.Message.Contains("was canceled"))
  419. {
  420. result.success = false;
  421. result.message = "放弃转链";
  422. result.reason = "请求超时";
  423. result.subCode = TkSubCodeEnum.Other;
  424. result.itemName = "点击打开淘宝APP";
  425. }
  426. else
  427. {
  428. //============================== 转链接口异常 ==============================
  429. _ = new LoggerLibrary("unionParse", "tb_error")
  430. .Info(ip, oaid)
  431. .Info(content)
  432. .Info(ex.Message, ex.StackTrace)
  433. .SaveAsync();
  434. NotifyCore.Notify(new NifyMessage
  435. {
  436. message = $"【转链异常TB】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  437. priority = NifyMessagePriority.high,
  438. tags = ["red_circle"]
  439. });
  440. result.success = false;
  441. result.subCode = TkSubCodeEnum.Other;
  442. result.message = "转链接口异常";
  443. result.itemName = "点击打开淘宝APP";
  444. }
  445. }
  446. _ = TkLogCore.ParseLogAsync(result, alimama);
  447. switch (result.reason)
  448. {
  449. case "其他推广链接":
  450. //case "排除淘口令":
  451. case "纯口令 没链接":
  452. other_aff = true;
  453. break;
  454. }
  455. return TaobaoParseOutput(result, swData, new
  456. {
  457. result.success,
  458. result.commercial,
  459. result.message,
  460. link_type = result.link_type.ToString(),
  461. channel = result?.channel.ToString(),
  462. result.channel_type,
  463. result.itemId,
  464. result.itemName,
  465. result.pic,
  466. result.promotionPrice,
  467. result.couponAmount,
  468. result.couponEffectiveStartTime,
  469. result?.couponEffectiveEndTime,
  470. result.shortLinkurl,
  471. result.deeplink_url,
  472. result.riskStrategy,
  473. result.launchScene,
  474. result.content,
  475. result.taoToken,
  476. other_aff,
  477. });
  478. }
  479. public static async Task<APIResult> DeeplinkTaobaoParseAsync(string content, int commerceType,
  480. string ip = "", string oaid = "", string riskStrategy = "", int launchScene = 0,
  481. int accountid = 0)
  482. {
  483. bool other_aff = false;
  484. AlimamaPlus alimama = null;
  485. var result = AlimamaPlus.GetFormattedObject(content, ip, oaid);
  486. result.riskStrategy = riskStrategy;
  487. result.launchScene = launchScene;
  488. result.rawContent = content;
  489. result.parse_type = "dp";
  490. Dictionary<string, long> swData = new();
  491. swData.Add("StartNew", 0);
  492. Stopwatch stopwatch = Stopwatch.StartNew();
  493. try
  494. {
  495. string url_content = parseDeeplinkInput(content);
  496. if (url_content.Contains("ali_trackid="))
  497. {
  498. //============================== 其他推广链接 ==============================
  499. result.channel = TkChannelEnum.tb;
  500. result.channel_type = ChannelTypeEnum.tb;
  501. result.link_type = LinkTypeEnum.other_aff;
  502. result.success = false;
  503. result.message = "放弃转链";
  504. result.reason = "其他推广链接";
  505. result.subCode = TkSubCodeEnum.OtherPromo;
  506. result.accountName = string.Empty;
  507. result.content = content;
  508. result.deeplink_url = string.Empty;
  509. _ = TkLogCore.ParseLogAsync(result);
  510. return TaobaoParseOutput(result, swData, new
  511. {
  512. result.success,
  513. result.commercial,
  514. result.message,
  515. result.content,
  516. result.itemName,
  517. other_aff = true,
  518. result.deeplink_url,
  519. });
  520. }
  521. (bool isTaobaUrl, string shortLinkurl) = AlimamaPlus.IsTaobaoUrl(url_content);
  522. if (!isTaobaUrl)
  523. {
  524. result.success = false;
  525. result.channel = TkChannelEnum.tb;
  526. result.link_type = LinkTypeEnum.unknown;
  527. result.success = false;
  528. result.message = "放弃转链";
  529. result.reason = "无效商品id";
  530. if (!result.success)
  531. {
  532. result.deeplink_url = string.Empty;
  533. }
  534. _ = TkLogCore.ParseLogAsync(result);
  535. return TaobaoParseOutput(result, swData, new
  536. {
  537. result.success,
  538. result.commercial,
  539. result.message,
  540. result.content,
  541. result.itemName,
  542. other_aff,
  543. result.deeplink_url,
  544. });
  545. }
  546. result.shortLinkurl = shortLinkurl;
  547. result.deeplink_url = content;
  548. result.content = shortLinkurl;
  549. content = shortLinkurl;
  550. string reason = string.Empty;
  551. var config = TkConfigCore.Get();
  552. var arr = config.tk_whitelist_regular.Split('\n')
  553. .Where(line => !string.IsNullOrWhiteSpace(line))
  554. .ToList();
  555. var arr2 = config.tk_blacklist_regular.Split('\n')
  556. .Where(line => !string.IsNullOrWhiteSpace(line))
  557. .ToList();
  558. var arr3 = config.multi_token_regular.Split('\n')
  559. .Where(line => !string.IsNullOrWhiteSpace(line))
  560. .ToList();
  561. bool is_tao_url = !string.IsNullOrEmpty(result.shortLinkurl);
  562. bool is_tao_token = AlimamaPlus.MatchRegexes(content, arr);
  563. bool is_other = AlimamaPlus.MatchOtherInfo(content, arr2);
  564. //============================== 放弃转链-初步筛选1 ==============================
  565. if (!is_tao_url && !is_tao_token || is_other)
  566. {
  567. //没有链接都放弃
  568. result.success = false;
  569. result.message = "放弃转链";
  570. result.reason = "初步筛选1";
  571. result.subCode = TkSubCodeEnum.Prelim1;
  572. result.itemName = "";
  573. result.deeplink_url = string.Empty;
  574. _ = TkLogCore.ParseLogAsync(result);
  575. return TaobaoParseOutput(result, swData, new
  576. {
  577. result.success,
  578. result.commercial,
  579. result.message,
  580. result.content,
  581. result.itemName,
  582. other_aff,
  583. result.deeplink_url,
  584. });
  585. }
  586. bool is_multi_token = AlimamaPlus.MatchMultiToken(content, arr3);
  587. //============================== 放弃转链-初步筛选1.5 ==============================
  588. if (is_multi_token)
  589. {
  590. //没有链接都放弃
  591. result.success = false;
  592. result.message = "放弃转链";
  593. result.reason = "初步筛选1.5";
  594. result.subCode = TkSubCodeEnum.Prelim1_5;
  595. result.itemName = "";
  596. result.deeplink_url = string.Empty;
  597. _ = TkLogCore.ParseLogAsync(result);
  598. return TaobaoParseOutput(result, swData, new
  599. {
  600. result.success,
  601. result.commercial,
  602. result.message,
  603. result.content,
  604. result.itemName,
  605. other_aff,
  606. result.deeplink_url,
  607. });
  608. }
  609. //============================== 放弃转链-初步筛选2 ==============================
  610. bool is_aff_link = false;
  611. if (!string.IsNullOrEmpty(result.shortLinkurl)) is_aff_link = AlimamaPlus.IsAffLink(result.shortLinkurl);
  612. if (!is_tao_url && is_tao_token)
  613. {
  614. //淘宝口令
  615. result.success = false;
  616. result.message = "放弃转链";
  617. result.reason = "初步筛选2";
  618. result.subCode = TkSubCodeEnum.Prelim2;
  619. result.itemName = "点击打开淘宝APP";
  620. if (!result.success)
  621. {
  622. result.deeplink_url = string.Empty;
  623. }
  624. _ = TkLogCore.ParseLogAsync(result);
  625. //20241229 特例
  626. //if ("bj".Equals(EndPointCore.CurrentEndPoint))
  627. //{
  628. // string ruleKey = $"tmp_rules2:tb:{DateTime.Now:yyyyMMdd}";
  629. // var count = RedisHelper.Get<int>(ruleKey);
  630. // var now = DateTime.Now;
  631. // if (now > new DateTime(2024, 12, 19) && now <= new DateTime(2024, 12, 22) && now.Hour >= 7 && count < 1000)
  632. // {
  633. // result.deeplink_url = "tbopen://m.taobao.com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&afc_route=1&bc_fl_src=growth_dhh_2200803434968_100-1930985-1595034112&dpa_Inid=159503411212096&dpa_material_id=530637422585&dpa_material_type=1&dpa_source_code=12096&force_no_smb=true&h5Url=https%3A%2F%2Fs.m.taobao.com%2Fh5%3Ffrom%3Dcustoms%26g_channelSrp%3Ddhhdpa_1232552832%26dpa_material_type%3D1%26ut_sk%3Dsearch%26spm%3Da2141.mb819t211c7%26sLaunch%3D0%26sKeep%3D1%26sModuleName%3Dsearch%26spm_back_up%3Da2141.mb819t211c7%26bc_fl_src%3Dgrowth_dhh_2200803434968_100-1930985-1595034112%26dpa_Inid%3D159503411212096%26dpa_material_id%3D530637422585%26dpa_material_type%3D1%26dpa_source_code%3D12096%26force_no_smb%3Dtrue%26itemIds%3D530637422585%26slk_actid%3D100000000207%26spm%3D2014.ugdhh.2200803434968.100-1930985-1595034112%26wh_biz%3Dtm&itemIds=530637422585&slk_actid=100000000207&spm=2014.ugdhh.2200803434968.100-1930985-1595034112&wh_biz=tm";
  634. // RedisHelper.IncrBy(ruleKey);
  635. // RedisHelper.Expire(ruleKey, 86400 * 1);
  636. // }
  637. //}
  638. other_aff = true;
  639. return TaobaoParseOutput(result, swData, new
  640. {
  641. result.success,
  642. result.commercial,
  643. result.message,
  644. result.content,
  645. result.itemName,
  646. other_aff,
  647. result.deeplink_url,
  648. });
  649. }
  650. if ((!is_tao_url && is_tao_token) || is_aff_link)
  651. {
  652. //没有短链接都放弃
  653. result.success = false;
  654. result.message = "放弃转链";
  655. result.reason = "初步筛选2";
  656. result.subCode = TkSubCodeEnum.Prelim2;
  657. result.itemName = "点击打开淘宝APP";
  658. if (!result.success)
  659. {
  660. result.deeplink_url = string.Empty;
  661. }
  662. _ = TkLogCore.ParseLogAsync(result);
  663. //20241229 特例
  664. //if ("bj".Equals(EndPointCore.CurrentEndPoint))
  665. //{
  666. // string ruleKey = $"tmp_rules2:tb:{DateTime.Now:yyyyMMdd}";
  667. // var count = RedisHelper.Get<int>(ruleKey);
  668. // var now = DateTime.Now;
  669. // if (now > new DateTime(2024, 12, 19) && now <= new DateTime(2024, 12, 22) && now.Hour >= 7 && count < 1000)
  670. // {
  671. // result.deeplink_url = "tbopen://m.taobao.com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&afc_route=1&bc_fl_src=growth_dhh_2200803434968_100-1930985-1595034112&dpa_Inid=159503411212096&dpa_material_id=530637422585&dpa_material_type=1&dpa_source_code=12096&force_no_smb=true&h5Url=https%3A%2F%2Fs.m.taobao.com%2Fh5%3Ffrom%3Dcustoms%26g_channelSrp%3Ddhhdpa_1232552832%26dpa_material_type%3D1%26ut_sk%3Dsearch%26spm%3Da2141.mb819t211c7%26sLaunch%3D0%26sKeep%3D1%26sModuleName%3Dsearch%26spm_back_up%3Da2141.mb819t211c7%26bc_fl_src%3Dgrowth_dhh_2200803434968_100-1930985-1595034112%26dpa_Inid%3D159503411212096%26dpa_material_id%3D530637422585%26dpa_material_type%3D1%26dpa_source_code%3D12096%26force_no_smb%3Dtrue%26itemIds%3D530637422585%26slk_actid%3D100000000207%26spm%3D2014.ugdhh.2200803434968.100-1930985-1595034112%26wh_biz%3Dtm&itemIds=530637422585&slk_actid=100000000207&spm=2014.ugdhh.2200803434968.100-1930985-1595034112&wh_biz=tm";
  672. // RedisHelper.IncrBy(ruleKey);
  673. // RedisHelper.Expire(ruleKey, 86400 * 1);
  674. // }
  675. //}
  676. other_aff = true;
  677. return TaobaoParseOutput(result, swData, new
  678. {
  679. result.success,
  680. result.commercial,
  681. result.message,
  682. result.content,
  683. result.itemName,
  684. other_aff,
  685. result.deeplink_url,
  686. });
  687. }
  688. //那就初步筛选3 有tb.cn 并且有 or 手淘发现
  689. string pattern = @"^(?!【淘宝】).*https?:\/\/m\.tb\.cn.*(?:手淘发现|手淘搜索)";
  690. bool isMatch = Regex.IsMatch(content, pattern);
  691. if (isMatch)
  692. {
  693. result.success = false;
  694. result.message = "放弃转链";
  695. result.reason = "初步筛选3";
  696. result.subCode = TkSubCodeEnum.Prelim3;
  697. result.itemName = "点击打开淘宝APP";
  698. if (!result.success)
  699. {
  700. result.deeplink_url = string.Empty;
  701. }
  702. _ = TkLogCore.ParseLogAsync(result);
  703. return TaobaoParseOutput(result, swData, new
  704. {
  705. result.success,
  706. result.commercial,
  707. result.message,
  708. result.content,
  709. result.itemName,
  710. other_aff,
  711. result.deeplink_url,
  712. });
  713. }
  714. //============================== 放弃转链-地区过滤 ==============================
  715. bool is_ignore2 = AlimamaPlus.ShouldIgnoreRequest(ip, oaid, riskStrategy, launchScene, out reason);
  716. if (is_ignore2)
  717. {
  718. result.success = false;
  719. result.message = "放弃转链";
  720. result.itemName = "点击打开淘宝APP";
  721. result.reason = reason;
  722. result.subCode = TkSubCodeEnum.TrafficCtrl;
  723. if (!result.success)
  724. {
  725. result.deeplink_url = string.Empty;
  726. }
  727. _ = TkLogCore.ParseLogAsync(result);
  728. return TaobaoParseOutput(result, swData, new
  729. {
  730. result.success,
  731. result.commercial,
  732. result.message,
  733. result.content,
  734. result.itemName,
  735. other_aff,
  736. result.deeplink_url,
  737. });
  738. }
  739. (bool isTaobaoUrl, string url) = AlimamaPlus.IsTaobaoUrl(content);
  740. //============================== 放弃转链-没有匹配账号 ==============================
  741. TkPoolDTO? account = accountid > 0 ?
  742. await TkPoolCore.GetOneAsync(accountid) :
  743. await TkPoolCore.GetOneAsync(TkPoolCore.TkAction.parse, isTaobaoUrl, riskStrategy, launchScene, "dp");
  744. if (account == null)
  745. {
  746. result.success = false;
  747. result.message = "放弃转链";
  748. result.reason = "没有匹配账号";
  749. result.subCode = TkSubCodeEnum.Other;
  750. result.itemName = "点击打开淘宝APP";
  751. if (!result.success)
  752. {
  753. result.deeplink_url = string.Empty;
  754. }
  755. _ = TkLogCore.ParseLogAsync(result);
  756. return TaobaoParseOutput(result, swData, new
  757. {
  758. result.success,
  759. result.commercial,
  760. result.message,
  761. result.content,
  762. result.couponAmount,
  763. result.taoToken,
  764. result.shortLinkurl,
  765. other_aff,
  766. result.deeplink_url,
  767. });
  768. }
  769. result.accountId = account.id;
  770. result.accountName = account.company;
  771. alimama = new AlimamaPlus(account);
  772. int timeout = alimama._config.rt_max;
  773. #if DEBUG
  774. timeout = 10000;
  775. #endif
  776. using var cts = new CancellationTokenSource();
  777. cts.CancelAfter(timeout);
  778. var requestTask = Task.Run(() => alimama.UnionParseAsync(ip, oaid, content, commerceType, result, isTaobaoUrl, riskStrategy, launchScene, cts.Token, swData), cts.Token);
  779. var delayTask = Task.Delay(timeout, cts.Token);
  780. var completedTask = await Task.WhenAny(requestTask, delayTask);
  781. if (completedTask == requestTask)
  782. {
  783. result = await requestTask;
  784. }
  785. else
  786. {
  787. //============================== 放弃转链-请求超时 ==============================
  788. cts.Cancel();
  789. result.success = false;
  790. result.message = "放弃转链";
  791. result.reason = "请求超时";
  792. result.subCode = TkSubCodeEnum.Other;
  793. result.itemName = "点击打开淘宝APP";
  794. }
  795. result.accountName = account.company;
  796. //result = await alimama.UnionParse2Async(content, result);
  797. }
  798. catch (Exception ex)
  799. {
  800. //============================== 放弃转链-请求超时 ==============================
  801. if (ex.Message.Contains("was canceled"))
  802. {
  803. result.success = false;
  804. result.message = "放弃转链";
  805. result.reason = "请求超时";
  806. result.subCode = TkSubCodeEnum.Other;
  807. result.itemName = "点击打开淘宝APP";
  808. }
  809. else
  810. {
  811. //============================== 转链接口异常 ==============================
  812. _ = new LoggerLibrary("unionParse", "tb_error")
  813. .Info(ip, oaid)
  814. .Info(content)
  815. .Info(ex.Message, ex.StackTrace)
  816. .SaveAsync();
  817. NotifyCore.Notify(new NifyMessage
  818. {
  819. message = $"【转链异常TB】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  820. priority = NifyMessagePriority.high,
  821. tags = ["red_circle"]
  822. });
  823. result.success = false;
  824. result.subCode = TkSubCodeEnum.Other;
  825. result.message = "转链接口异常";
  826. result.itemName = "点击打开淘宝APP";
  827. }
  828. }
  829. if (!result.success)
  830. {
  831. result.deeplink_url = string.Empty;
  832. }
  833. _ = TkLogCore.ParseLogAsync(result, alimama);
  834. switch (result.reason)
  835. {
  836. case "其他推广链接":
  837. //case "排除淘口令":
  838. case "纯口令 没链接":
  839. other_aff = true;
  840. break;
  841. }
  842. return TaobaoParseOutput(result, swData, new
  843. {
  844. result.success,
  845. result.commercial,
  846. result.message,
  847. link_type = result.link_type.ToString(),
  848. channel = result?.channel.ToString(),
  849. result.channel_type,
  850. result.itemId,
  851. result.itemName,
  852. result.pic,
  853. result.promotionPrice,
  854. result.couponAmount,
  855. result.couponEffectiveStartTime,
  856. result?.couponEffectiveEndTime,
  857. result.shortLinkurl,
  858. result.deeplink_url,
  859. result.riskStrategy,
  860. result.launchScene,
  861. result.content,
  862. result.taoToken,
  863. other_aff,
  864. });
  865. }
  866. private static APIResult JdParseOutput(JdDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  867. {
  868. return new APIResult(new
  869. {
  870. result.success,
  871. result.commercial,
  872. result.message,
  873. link_type = result.link_type.ToString(),
  874. channel = result?.channel.ToString(),
  875. result.channel_type,
  876. result.itemId,
  877. result.itemName,
  878. result.shortLinkurl,
  879. result.deeplink_url,
  880. result.riskStrategy,
  881. result.launchScene,
  882. }, code);
  883. }
  884. public static async Task<APIResult> JdParseAsync(string content, int commerceType, string ip, string oaid,
  885. string riskStrategy = "", int launchScene = 0,
  886. int accountid = 0, string clickId = "", CancellationToken cancellationToken = default)
  887. {
  888. var config = TkConfigCore.Get();
  889. var result = JdUnionPlus.GetFormattedObject(content, ip, oaid, clickId);
  890. result.rawContent = content;
  891. result.riskStrategy = riskStrategy;
  892. result.launchScene = launchScene;
  893. bool IfExceptional = false;
  894. try
  895. {
  896. content = content.UrlDecode();
  897. if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
  898. {
  899. var blacklist = config.jd_blacklist_regular.Split('\n')
  900. .Where(line => !string.IsNullOrWhiteSpace(line))
  901. .ToList();
  902. bool anyMatch = false;
  903. foreach (string pattern in blacklist)
  904. {
  905. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  906. }
  907. if (anyMatch)
  908. {
  909. result.success = false;
  910. result.deeplink_url = string.Empty;
  911. result.message = "放弃转链";
  912. result.reason = "规则排除";
  913. _ = TkLogCore.ParseLogAsync(result);
  914. return JdParseOutput(result);
  915. }
  916. }
  917. string out_url = null;
  918. string itemId = null;
  919. //============================== 放弃转链-地区过滤 ==============================
  920. if (!TestParseCore.InWhitelist(result.ip, result.oaid) && accountid == 0 && JdUnionPlus.ShouldIgnoreRequest(config, ip, oaid, riskStrategy, launchScene, out string reason))
  921. {
  922. result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);
  923. result.deeplink_url = result.link_type switch
  924. {
  925. LinkTypeEnum.other_aff or
  926. LinkTypeEnum.live or
  927. LinkTypeEnum.video or
  928. LinkTypeEnum.profile or
  929. LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  930. _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  931. };
  932. //if (result.link_type == LinkTypeEnum.other_aff)
  933. //{
  934. // //20241204 特例
  935. // if ("bj".Equals(EndPointCore.CurrentEndPoint))
  936. // {
  937. // string ruleKey = $"tmp_rules1:jd:{DateTime.Now:yyyyMMdd}";
  938. // var count = RedisHelper.Get<int>(ruleKey);
  939. // if (DateTime.Now < DateTime.Parse("2024-12-07") && count < 500)
  940. // {
  941. // 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__";
  942. // RedisHelper.IncrBy(ruleKey);
  943. // RedisHelper.Expire(ruleKey, 86400 * 1);
  944. // }
  945. // }
  946. //}
  947. result.success = false;
  948. result.message = "放弃转链";
  949. result.reason = reason;
  950. _ = TkLogCore.ParseLogAsync(result);
  951. return JdParseOutput(result);
  952. }
  953. // bool is_ignore2 = JdUnionPlus.FlowControlIgnoreRequest(config, out reason);
  954. //#if DEBUG
  955. // is_ignore2 = false;
  956. //#endif
  957. // if (accountid == 0 && is_ignore2)
  958. // {
  959. // result.success = false;
  960. // result.message = "放弃转链";
  961. // result.reason = reason;
  962. // _ = TkLogCore.ParseLogAsync(result);
  963. // return JdParseOutput(result);
  964. // }
  965. result.shortLinkurl = JdUnionPlus.GetLink(content);
  966. result.content = result.shortLinkurl;
  967. result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);
  968. bool is_numeric = result.shortLinkurl.Contains(itemId);
  969. var account = accountid > 0 ? await JdPoolCore.GetOneAsync(accountid, JdPoolCore.JdAction.parse) : await JdPoolCore.GetOneAsync(JdPoolCore.JdAction.parse, riskStrategy, launchScene, is_numeric);
  970. if (account == null)
  971. {
  972. result.success = false;
  973. result.message = "放弃转链";
  974. result.reason = "没有匹配账号";
  975. result.deeplink_url = result.link_type switch
  976. {
  977. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  978. _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  979. };
  980. _ = TkLogCore.ParseLogAsync(result);
  981. return JdParseOutput(result);
  982. }
  983. result.accountId = account.id;
  984. result.accountName = account.name;
  985. var plus = new JdUnionPlus(account);
  986. result = await plus.JdParseAsync(content, commerceType, clickId, result, cancellationToken);
  987. }
  988. catch (Exception ex)
  989. {
  990. if (ex.Message.Contains("was canceled"))
  991. {
  992. result.success = false;
  993. result.message = "放弃转链";
  994. result.reason = "请求超时";
  995. }
  996. else
  997. {
  998. IfExceptional = true;
  999. _ = new LoggerLibrary("unionParse", "jd_error")
  1000. .Info(ip, oaid)
  1001. .Info(content)
  1002. .Info(ex.Message, ex.StackTrace)
  1003. .SaveAsync();
  1004. NotifyCore.Notify(new NifyMessage
  1005. {
  1006. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  1007. priority = NifyMessagePriority.high,
  1008. tags = ["red_circle"]
  1009. });
  1010. result.success = false;
  1011. result.message = "内部错误";
  1012. result.reason = "转链接口异常";
  1013. }
  1014. result.deeplink_url = result.link_type switch
  1015. {
  1016. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1017. _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1018. };
  1019. }
  1020. _ = TkLogCore.ParseLogAsync(result);
  1021. return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  1022. }
  1023. public static async Task<APIResult> DeeplinkJdParseAsync(string content, int commerceType, string ip, string oaid,
  1024. string riskStrategy = "", int launchScene = 0,
  1025. int accountid = 0, string clickId = "", CancellationToken cancellationToken = default)
  1026. {
  1027. var config = TkConfigCore.Get();
  1028. var result = JdUnionPlus.GetFormattedObject(content, ip, oaid, clickId);
  1029. result.rawContent = content;
  1030. result.parse_type = "dp";
  1031. result.riskStrategy = riskStrategy;
  1032. result.launchScene = launchScene;
  1033. bool IfExceptional = false;
  1034. try
  1035. {
  1036. string url_content = parseDeeplinkInput(content);
  1037. string utm_campaign = url_content.GetContentPart("utm_campaign=", "&");
  1038. string utm_term = url_content.GetContentPart("utm_term=", "&");
  1039. if (!string.IsNullOrEmpty(utm_campaign) || !string.IsNullOrEmpty(utm_term))
  1040. {
  1041. //============================== 其他推广链接 ==============================
  1042. result.channel = TkChannelEnum.jd;
  1043. result.channel_type = ChannelTypeEnum.jd;
  1044. result.link_type = LinkTypeEnum.other_aff;
  1045. result.success = false;
  1046. result.message = "放弃转链";
  1047. result.reason = "其他推广链接";
  1048. result.accountName = string.Empty;
  1049. result.content = content;
  1050. result.deeplink_url = string.Empty;
  1051. _ = TkLogCore.ParseLogAsync(result);
  1052. return JdParseOutput(result);
  1053. }
  1054. ///utm_campaign=t_2034983365_&utm_term=638b93ffc5174cc1a01a6471c56913d5 这俩带1个都不转。
  1055. ///
  1056. result.shortLinkurl = url_content;
  1057. result.content = url_content;
  1058. result.deeplink_url = content;
  1059. content = url_content;
  1060. if (!string.IsNullOrEmpty(config.jd_blacklist_regular))
  1061. {
  1062. var blacklist = config.jd_blacklist_regular.Split('\n')
  1063. .Where(line => !string.IsNullOrWhiteSpace(line))
  1064. .ToList();
  1065. bool anyMatch = false;
  1066. foreach (string pattern in blacklist)
  1067. {
  1068. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  1069. }
  1070. if (anyMatch)
  1071. {
  1072. result.success = false;
  1073. result.deeplink_url = string.Empty;
  1074. result.message = "放弃转链";
  1075. result.reason = "规则排除";
  1076. _ = TkLogCore.ParseLogAsync(result);
  1077. return JdParseOutput(result);
  1078. }
  1079. }
  1080. string out_url = null;
  1081. string itemId = null;
  1082. //============================== 放弃转链-地区过滤 ==============================
  1083. if (!TestParseCore.InWhitelist(result.ip, result.oaid) && accountid == 0 && JdUnionPlus.ShouldIgnoreRequest(config, ip, oaid, riskStrategy, launchScene, out string reason))
  1084. {
  1085. result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);
  1086. result.deeplink_url = result.link_type switch
  1087. {
  1088. LinkTypeEnum.other_aff or
  1089. LinkTypeEnum.live or
  1090. LinkTypeEnum.video or
  1091. LinkTypeEnum.profile or
  1092. LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1093. _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1094. };
  1095. result.success = false;
  1096. result.message = "放弃转链";
  1097. result.reason = reason;
  1098. if (!result.success)
  1099. {
  1100. result.deeplink_url = string.Empty;
  1101. }
  1102. _ = TkLogCore.ParseLogAsync(result);
  1103. return JdParseOutput(result);
  1104. }
  1105. result.shortLinkurl = JdUnionPlus.GetLink(content);
  1106. result.content = result.shortLinkurl;
  1107. result.link_type = JdUnionPlus.GetLinkType(result.shortLinkurl, out out_url, out itemId);
  1108. bool is_numeric = result.shortLinkurl.Contains(itemId);
  1109. var account = accountid > 0 ? await JdPoolCore.GetOneAsync(accountid, JdPoolCore.JdAction.parse) : await JdPoolCore.GetOneAsync(JdPoolCore.JdAction.parse, riskStrategy, launchScene, is_numeric,"dp");
  1110. if (account == null)
  1111. {
  1112. result.success = false;
  1113. result.message = "放弃转链";
  1114. result.reason = "没有匹配账号";
  1115. result.deeplink_url = result.link_type switch
  1116. {
  1117. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1118. _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1119. };
  1120. if (!result.success)
  1121. {
  1122. result.deeplink_url = string.Empty;
  1123. }
  1124. _ = TkLogCore.ParseLogAsync(result);
  1125. return JdParseOutput(result);
  1126. }
  1127. result.accountId = account.id;
  1128. result.accountName = account.name;
  1129. var plus = new JdUnionPlus(account);
  1130. result = await plus.JdParseAsync(content, commerceType, clickId, result, cancellationToken);
  1131. }
  1132. catch (Exception ex)
  1133. {
  1134. if (ex.Message.Contains("was canceled"))
  1135. {
  1136. result.success = false;
  1137. result.message = "放弃转链";
  1138. result.reason = "请求超时";
  1139. }
  1140. else
  1141. {
  1142. IfExceptional = true;
  1143. _ = new LoggerLibrary("unionParse", "jd_error")
  1144. .Info(ip, oaid)
  1145. .Info(content)
  1146. .Info(ex.Message, ex.StackTrace)
  1147. .SaveAsync();
  1148. NotifyCore.Notify(new NifyMessage
  1149. {
  1150. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  1151. priority = NifyMessagePriority.high,
  1152. tags = ["red_circle"]
  1153. });
  1154. result.success = false;
  1155. result.message = "内部错误";
  1156. result.reason = "转链接口异常";
  1157. }
  1158. result.deeplink_url = result.link_type switch
  1159. {
  1160. LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1161. _ => JdUnionPlus.GetDefaultStyleDeeplink(result.shortLinkurl),
  1162. };
  1163. }
  1164. if (!result.success)
  1165. {
  1166. result.deeplink_url = string.Empty;
  1167. }
  1168. _ = TkLogCore.ParseLogAsync(result);
  1169. return JdParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  1170. }
  1171. public static async Task<APIResult> DyParseAsync(string content, int commerceType, string ip, string oaid, CancellationToken cancellationToken = default)
  1172. {
  1173. var result = DyUnionPlus.GetFormattedObject(content, ip, oaid);
  1174. content = content.UrlDecode();
  1175. result.rawContent = content;
  1176. bool IfExceptional = false;
  1177. try
  1178. {
  1179. #if DEBUG
  1180. #else
  1181. // 2024-06-19 联盟业务下线
  1182. result.success = false;
  1183. result.message = "放弃转链";
  1184. result.reason = "联盟下线";
  1185. _ = TkLogCore.ParseLogAsync(result);
  1186. return new APIResult(result);
  1187. #endif
  1188. if (DyUnionPlus.ShouldIgnoreRequest(ip, oaid, out string reason))
  1189. {
  1190. result.success = false;
  1191. result.message = "放弃转链";
  1192. result.reason = reason;
  1193. _ = TkLogCore.ParseLogAsync(result);
  1194. return new APIResult(result);
  1195. }
  1196. var account = PangolinPoolCore.GetOne();
  1197. if (account == null)
  1198. {
  1199. result.success = false;
  1200. result.message = "放弃转链";
  1201. result.reason = "没有匹配账号";
  1202. _ = TkLogCore.ParseLogAsync(result);
  1203. return new APIResult(result);
  1204. }
  1205. result = await DyUnionPlus.DyParseAsync(account, content, commerceType, result, cancellationToken);
  1206. }
  1207. catch (Exception ex)
  1208. {
  1209. if (ex.Message.Contains("was canceled"))
  1210. {
  1211. result.success = false;
  1212. result.message = "放弃转链";
  1213. result.reason = "请求超时";
  1214. }
  1215. else
  1216. {
  1217. IfExceptional = true;
  1218. _ = new LoggerLibrary("unionParse", "dy_error")
  1219. .Info(ip, oaid)
  1220. .Info(content)
  1221. .Info(ex.Message, ex.StackTrace)
  1222. .SaveAsync();
  1223. NotifyCore.Notify(new NifyMessage
  1224. {
  1225. message = $"【转链异常DY】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  1226. priority = NifyMessagePriority.high,
  1227. tags = ["red_circle"]
  1228. });
  1229. result.success = false;
  1230. result.message = "内部错误";
  1231. result.reason = "转链接口异常";
  1232. }
  1233. }
  1234. _ = TkLogCore.ParseLogAsync(result);
  1235. return new APIResult(new
  1236. {
  1237. result.success,
  1238. result.message,
  1239. link_type = result.link_type.ToString(),
  1240. channel = result?.channel.ToString(),
  1241. content = result?.rawContent.ToString(),
  1242. taoToken = result?.taoToken.ToString(),
  1243. result.channel_type,
  1244. result.itemName,
  1245. result.shortLinkurl,
  1246. result.deeplink_url,
  1247. }, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  1248. }
  1249. public static async Task<APIResult> PddParseAsync(string content, int commerceType, string ip, string oaid,
  1250. int accountid = 0, CancellationToken cancellationToken = default)
  1251. {
  1252. var result = PddUnionPlus.GetFormattedObject(content, ip, oaid);
  1253. content = content.UrlDecode();
  1254. result.rawContent = content;
  1255. bool IfExceptional = false;
  1256. try
  1257. {
  1258. var config = TkConfigCore.Get();
  1259. if (!string.IsNullOrEmpty(config.pdd_blacklist_regular))
  1260. {
  1261. var blacklist = config.pdd_blacklist_regular.Split('\n')
  1262. .Where(line => !string.IsNullOrWhiteSpace(line))
  1263. .ToList();
  1264. bool anyMatch = false;
  1265. foreach (string pattern in blacklist)
  1266. {
  1267. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  1268. }
  1269. if (anyMatch)
  1270. {
  1271. result.success = false;
  1272. result.deeplink_url = string.Empty;
  1273. result.message = "放弃转链";
  1274. result.reason = "规则排除";
  1275. _ = TkLogCore.ParseLogAsync(result);
  1276. return PddParseOutput(result);
  1277. }
  1278. }
  1279. //============================== 放弃转链-地区过滤 ==============================
  1280. if (accountid == 0 && PddUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  1281. {
  1282. result.success = false;
  1283. result.message = "放弃转链";
  1284. result.reason = reason;
  1285. result.deeplink_url = PddUnionPlus.GetDeeplink(result.rawContent);
  1286. _ = TkLogCore.ParseLogAsync(result);
  1287. return PddParseOutput(result);
  1288. }
  1289. var account = PddPoolCore.GetOne(PddUnionWorkMode.All, accountid);
  1290. if (account == null)
  1291. {
  1292. result.success = false;
  1293. result.message = "放弃转链";
  1294. result.reason = "没有匹配账号";
  1295. result.deeplink_url = PddUnionPlus.GetDeeplink(result.rawContent);
  1296. _ = TkLogCore.ParseLogAsync(result);
  1297. return PddParseOutput(result);
  1298. }
  1299. result.accountId = account.id;
  1300. result.accountName = account.name;
  1301. var plus = new PddUnionPlus(account);
  1302. result = await plus.PddParseAsync(content, commerceType, result, cancellationToken);
  1303. }
  1304. catch (Exception ex)
  1305. {
  1306. if (ex.Message.Contains("was canceled"))
  1307. {
  1308. result.success = false;
  1309. result.message = "放弃转链";
  1310. result.reason = "请求超时";
  1311. }
  1312. else
  1313. {
  1314. IfExceptional = true;
  1315. _ = new LoggerLibrary("unionParse", "pdd_error")
  1316. .Info(ip, oaid)
  1317. .Info(content)
  1318. .Info(ex.Message, ex.StackTrace)
  1319. .SaveAsync();
  1320. NotifyCore.Notify(new NifyMessage
  1321. {
  1322. message = $"【转链异常PDD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  1323. priority = NifyMessagePriority.high,
  1324. tags = ["red_circle"]
  1325. });
  1326. result.success = false;
  1327. result.message = "内部错误";
  1328. result.reason = "转链接口异常";
  1329. }
  1330. }
  1331. _ = TkLogCore.ParseLogAsync(result);
  1332. return PddParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  1333. }
  1334. public static async Task<APIResult> DeeplinkPddParseAsync(string content, int commerceType, string ip, string oaid,
  1335. int accountid = 0, CancellationToken cancellationToken = default)
  1336. {
  1337. var result = PddUnionPlus.GetFormattedObject(content, ip, oaid);
  1338. content = content.UrlDecode();
  1339. result.rawContent = content;
  1340. result.parse_type = "dp";
  1341. bool IfExceptional = false;
  1342. try
  1343. {
  1344. var config = TkConfigCore.Get();
  1345. if (!string.IsNullOrEmpty(config.pdd_blacklist_regular))
  1346. {
  1347. var blacklist = config.pdd_blacklist_regular.Split('\n')
  1348. .Where(line => !string.IsNullOrWhiteSpace(line))
  1349. .ToList();
  1350. bool anyMatch = false;
  1351. foreach (string pattern in blacklist)
  1352. {
  1353. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  1354. }
  1355. if (anyMatch)
  1356. {
  1357. result.success = false;
  1358. result.deeplink_url = string.Empty;
  1359. result.message = "放弃转链";
  1360. result.reason = "规则排除";
  1361. _ = TkLogCore.ParseLogAsync(result);
  1362. return PddParseOutput(result);
  1363. }
  1364. }
  1365. //============================== 放弃转链-地区过滤 ==============================
  1366. if (accountid == 0 && PddUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  1367. {
  1368. result.success = false;
  1369. result.message = "放弃转链";
  1370. result.reason = reason;
  1371. result.deeplink_url = PddUnionPlus.GetDeeplink(result.rawContent);
  1372. _ = TkLogCore.ParseLogAsync(result);
  1373. return PddParseOutput(result);
  1374. }
  1375. var account = PddPoolCore.GetOne(PddUnionWorkMode.All, accountid, "dp");
  1376. if (account == null)
  1377. {
  1378. result.success = false;
  1379. result.message = "放弃转链";
  1380. result.reason = "没有匹配账号";
  1381. result.deeplink_url = PddUnionPlus.GetDeeplink(result.rawContent);
  1382. _ = TkLogCore.ParseLogAsync(result);
  1383. return PddParseOutput(result);
  1384. }
  1385. result.accountId = account.id;
  1386. result.accountName = account.name;
  1387. var plus = new PddUnionPlus(account);
  1388. result = await plus.PddParseAsync(content, commerceType, result, cancellationToken);
  1389. }
  1390. catch (Exception ex)
  1391. {
  1392. if (ex.Message.Contains("was canceled"))
  1393. {
  1394. result.success = false;
  1395. result.message = "放弃转链";
  1396. result.reason = "请求超时";
  1397. }
  1398. else
  1399. {
  1400. IfExceptional = true;
  1401. _ = new LoggerLibrary("unionParse", "pdd_error")
  1402. .Info(ip, oaid)
  1403. .Info(content)
  1404. .Info(ex.Message, ex.StackTrace)
  1405. .SaveAsync();
  1406. NotifyCore.Notify(new NifyMessage
  1407. {
  1408. message = $"【转链异常PDD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  1409. priority = NifyMessagePriority.high,
  1410. tags = ["red_circle"]
  1411. });
  1412. result.success = false;
  1413. result.message = "内部错误";
  1414. result.reason = "转链接口异常";
  1415. }
  1416. }
  1417. _ = TkLogCore.ParseLogAsync(result);
  1418. return PddParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  1419. }
  1420. private static APIResult PddParseOutput(PddDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  1421. {
  1422. return new APIResult(new
  1423. {
  1424. result.success,
  1425. result.message,
  1426. link_type = result.link_type.ToString(),
  1427. channel = result?.channel.ToString(),
  1428. result.itemId,
  1429. result.itemName,
  1430. result.shortLinkurl,
  1431. result.deeplink_url,
  1432. }, code);
  1433. }
  1434. public static async Task<APIResult> KsParseAsync(string content, int commerceType, string ip, string oaid,
  1435. int accountid = 0, CancellationToken cancellationToken = default)
  1436. {
  1437. var result = KsUnionPlus.GetFormattedObject(content, ip, oaid);
  1438. content = content.UrlDecode();
  1439. result.rawContent = content;
  1440. bool IfExceptional = false;
  1441. try
  1442. {
  1443. var config = TkConfigCore.Get();
  1444. if (!string.IsNullOrEmpty(config.ks_blacklist_regular))
  1445. {
  1446. var blacklist = config.ks_blacklist_regular.Split('\n')
  1447. .Where(line => !string.IsNullOrWhiteSpace(line))
  1448. .ToList();
  1449. bool anyMatch = false;
  1450. foreach (string pattern in blacklist)
  1451. {
  1452. if (Regex.IsMatch(content, pattern, RegexOptions.IgnoreCase)) anyMatch = true;
  1453. }
  1454. if (anyMatch)
  1455. {
  1456. result.success = false;
  1457. result.deeplink_url = string.Empty;
  1458. result.message = "放弃转链";
  1459. result.reason = "规则排除";
  1460. _ = TkLogCore.ParseLogAsync(result);
  1461. return KsParseOutput(result);
  1462. }
  1463. }
  1464. //============================== 放弃转链-地区过滤 ==============================
  1465. if (accountid == 0 && KsUnionPlus.ShouldIgnoreRequest(config, ip, oaid, out string reason))
  1466. {
  1467. result.success = false;
  1468. result.message = "放弃转链";
  1469. result.reason = reason;
  1470. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  1471. _ = TkLogCore.ParseLogAsync(result);
  1472. return KsParseOutput(result);
  1473. }
  1474. var account = accountid > 0 ? KsPoolCore.GetOne(accountid, KsPoolCore.KsAction.parse) : KsPoolCore.GetOne(KsPoolCore.KsAction.parse);
  1475. if (account == null)
  1476. {
  1477. result.success = false;
  1478. result.message = "放弃转链";
  1479. result.reason = "没有匹配账号";
  1480. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  1481. _ = TkLogCore.ParseLogAsync(result);
  1482. return KsParseOutput(result);
  1483. }
  1484. result.accountId = account.id;
  1485. result.accountName = account.name;
  1486. var plus = new KsUnionPlus(account);
  1487. result = await plus.KsParseAsync(content, commerceType, result, cancellationToken);
  1488. }
  1489. catch (Exception ex)
  1490. {
  1491. if (ex.Message.Contains("was canceled"))
  1492. {
  1493. result.success = false;
  1494. result.message = "放弃转链";
  1495. result.reason = "请求超时";
  1496. }
  1497. else
  1498. {
  1499. IfExceptional = true;
  1500. _ = new LoggerLibrary("unionParse", "jd_error")
  1501. .Info(ip, oaid)
  1502. .Info(content)
  1503. .Info(ex.Message, ex.StackTrace)
  1504. .SaveAsync();
  1505. NotifyCore.Notify(new NifyMessage
  1506. {
  1507. message = $"【转链异常JD】\n{content}\n\n{ex.Message}\n{ex.StackTrace}",
  1508. priority = NifyMessagePriority.high,
  1509. tags = ["red_circle"]
  1510. });
  1511. result.success = false;
  1512. result.message = "内部错误";
  1513. result.reason = "转链接口异常";
  1514. }
  1515. result.deeplink_url = KsUnionPlus.GetDeeplink(string.Empty, LinkTypeEnum.baseDomain);
  1516. }
  1517. _ = TkLogCore.ParseLogAsync(result);
  1518. return KsParseOutput(result, IfExceptional ? APIResultCodeEnum.NotAcceptable : APIResultCodeEnum.OK);
  1519. }
  1520. private static APIResult KsParseOutput(KsDataDTO result, APIResultCodeEnum code = APIResultCodeEnum.OK)
  1521. {
  1522. return new APIResult(new
  1523. {
  1524. result.success,
  1525. result.message,
  1526. link_type = result.link_type.ToString(),
  1527. channel = result?.channel.ToString(),
  1528. result.itemId,
  1529. result.itemName,
  1530. result.shortLinkurl,
  1531. result.deeplink_url,
  1532. }, code);
  1533. }
  1534. }
  1535. }