using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Text; using dodohold.core; using Dataoke; using System.Text.RegularExpressions; using Org.BouncyCastle.Ocsp; using System.Diagnostics; using TencentCloud.Fmu.V20191213.Models; using Microsoft.VisualBasic; using System.Text.Json; using static System.Runtime.InteropServices.JavaScript.JSType; using System.Security.Cryptography; using Google.Protobuf.WellKnownTypes; using Microsoft.Extensions.FileSystemGlobbing.Internal; namespace molilian.core { public partial class JdUnionPlus { public static string GetLink(string content) { if (string.IsNullOrEmpty(content)) return content; string result = content; //string pattern = @"https?:\/\/?([\da-z\.-]+)\.([a-z]{2,6})(:\d{1,5})?([\/\w\.-]*)*\/?(#[\S]+)?(\?[\S]+)?"; Regex regex = new(AlimamaPlus._url_pattern); MatchCollection matches = regex.Matches(content); foreach (Match m in matches.Cast()) { string url = m.Value; return url; } return string.Empty; } public static string GetItemId(string url) { if (string.IsNullOrEmpty(url)) return string.Empty; string[] patterns = [ @"https?://(?:i-)?item(?:\.m)?\.jd\.com/(?:product/)?(\d+)\.html(?:\?.*)?" //@"https?:\/\/b2b\.m\.jd\.com\/goods-detail\/.*[?&]skuId=(\d+)" ]; foreach (var pattern in patterns) { Match match = Regex.Match(url, pattern); if (match.Success) { string idNumber = match.Groups[1].Value; // 捕获组1包含数字ID return idNumber; } } return string.Empty; } public static string GetDeeplink(string url, string clickId) { var config = TkConfigCore.Get(); if (string.IsNullOrEmpty(config.dp_style)) return GetDefaultStyleDeeplink(url); Random rand = new(); int randomValue = rand.Next(0, 101); if (randomValue > config.dp_style_percentage) return GetDefaultStyleDeeplink(url); if (string.IsNullOrEmpty(clickId)) clickId = config.dp_style_default_str; var ts = DateTime.Now.Convert2UnixTimestamp(true); string virtual_params = $"{{\"category\":\"jump\",\"des\":\"HomePage\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}"; if (!string.IsNullOrEmpty(url)) { virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"url\":\"{url}\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}}}"; } string result = $"openapp.jdmobile://virtual?params={virtual_params.UrlEncode()}"; return result; } public static string GetDefaultStyleDeeplink(string url) { if (string.IsNullOrEmpty(url)) return "openapp.jdmobile://"; string virtual_params = $"{{\"category\":\"jump\",\"des\":\"m\",\"sourceValue\":\"babel-act\",\"sourceType\":\"babel\",\"url\":\"{url}\",\"M_sourceFrom\":\"h5auto\",\"msf_type\":\"auto\"}}"; string result = $"openapp.jdmobile://virtual?params={virtual_params.UrlEncode()}"; return result; } public static JdDataDTO GetFormattedObject(string content, string ip = "", string oaid = "", string clickId = "") { string shortLinkurl = GetLink(content); string deeplink_url = GetDeeplink(shortLinkurl, clickId); return new JdDataDTO() { message = string.Empty, link_type = LinkTypeEnum.unknown, channel = TkChannelEnum.jd, accountName = string.Empty, success = false, content = content, ip = ip, oaid = oaid, elapsedTime = 0, itemName = "点击打开京东APP", shortLinkurl = shortLinkurl, deeplink_url = deeplink_url, create_time = DateTime.Now, end_point = _end_point, }; } public static bool IsAffLlink(string url) { Uri uri = new(url); if (uri.Host.Equals("`u.jd.com", StringComparison.OrdinalIgnoreCase)) { return true; } return false; } public static string? GetDesiredUrl(string url) { try { WebClientUtility client = new() { AllowAutoRedirect = false, Referer = "http://www.jd.com", Proxy = ProxyNodesCore.RandomOne() }; #if DEBUG client.Proxy = null; #endif var response = client.Request(url); if (!response.Successed) return null; var target_url = response.ResponseMessage?.Headers?.Location?.ToString(); if (!url.StartsWith("https://3.cn")) return null; return target_url; } catch (Exception ex) { } return null; } public static LinkTypeEnum GetLinkType(string url, out string desiredUrl, out string itemId) { desiredUrl = url; itemId = string.Empty; if (string.IsNullOrEmpty(url)) return LinkTypeEnum.unknown; string lowerUrl = url.ToLower(); Uri uri = new(url); if ("3.cn".Equals(uri.Host)) { var target_url = GetDesiredUrl(url); return GetLinkType(target_url, out desiredUrl, out itemId); } string[] arr = ["mall.jd.com", "shop.m.jd.com", "shop.jd.com"]; if (arr.Contains(uri.Host)) return LinkTypeEnum.profile; arr = ["lives.jd.com"]; if (arr.Contains(uri.Host)) return LinkTypeEnum.live; arr = ["u.jd.com"]; if (arr.Contains(uri.Host)) return LinkTypeEnum.other_aff; arr = ["h5.m.jd.com"]; if (arr.Contains(uri.Host)) return LinkTypeEnum.video; if (lowerUrl.Contains("h5.m.jd.com/active/faxian/video/index.html")) return LinkTypeEnum.video; if (lowerUrl.Contains("eco.m.jd.com/content/dr_home/index.html")) return LinkTypeEnum.profile; if (uri.Host.Contains("jd.com")) { itemId = GetItemId(url); if (!string.IsNullOrEmpty(itemId)) return LinkTypeEnum.goods; return LinkTypeEnum.baseDomain; } return LinkTypeEnum.unknown; } static bool ContainsSpecialFormat(string content) { // 使用正则表达式匹配内容中是否含有特定格式的字符串 string pattern = @"[!$¥%]+[a-zA-Z0-9]+[!$¥%]]*"; return Regex.IsMatch(content, pattern); } //public static JdDataDTO JdParse(JdPoolDTO account, string content, ref JdDataDTO result) //{ // string message = "OK"; // string url = GetLink(content); // var plus = new JdUnionPlus(account.app_key, account.app_secret); // if (ContainsSpecialFormat(content)) // { // result.link_type = LinkTypeEnum.other_aff; // result.success = false; // result.link_type = LinkTypeEnum.unknown; // result.channel_type = ChannelTypeEnum.jd; // result.message = "其他推广链接"; // result.accountName = string.Empty; // result.content = content; // result.shortLinkurl = url; // result.deeplink_url = GetDeeplink(null); // return result; // } // //result.link_type = plus.IsAffLlink(url) ? LinkTypeEnum.other_aff : LinkTypeEnum.goods; // if (!string.IsNullOrEmpty(url)) // { // (result.link_type, result.content) = GetLinkType(url); // if (result.link_type == LinkTypeEnum.other_aff) // { // result.success = false; // result.link_type = LinkTypeEnum.unknown; // result.channel_type = ChannelTypeEnum.jd; // result.message = "其他推广链接"; // result.accountName = string.Empty; // result.content = content; // result.shortLinkurl = url; // result.deeplink_url = GetDeeplink(null); // return result; // } // } // string shortLinkurl = plus.promotion_get(account.site_id, string.IsNullOrEmpty(url) ? content : url); // var success = !string.IsNullOrEmpty(shortLinkurl); // if (!success) message = "转链失败"; // result.content = shortLinkurl; // result.shortLinkurl = shortLinkurl; // result.success = success; // result.message = message; // result.deeplink_url = GetDeeplink(url); // return result; //} public async Task JdParseAsync(string content, int commerceType, string clickId, JdDataDTO result, CancellationToken cancellationToken = default) { string message = "OK"; string url = GetLink(content); if (string.IsNullOrEmpty(url)) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.jd; result.message = "放弃转链"; result.reason = "纯口令"; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.shortLinkurl = url; result.deeplink_url = GetDeeplink(url, clickId); return result; } string shortLinkurl = url; //result.link_type = plus.IsAffLlink(url) ? LinkTypeEnum.other_aff : LinkTypeEnum.goods; result.link_type = GetLinkType(url, out string out_url, out string itemId); url = out_url; result.itemId = itemId; switch (result.link_type) { case LinkTypeEnum.profile: case LinkTypeEnum.live: case LinkTypeEnum.video: result.success = false; result.channel_type = ChannelTypeEnum.jd; result.message = "放弃转链"; result.reason = result.link_type switch { LinkTypeEnum.profile => "店铺", LinkTypeEnum.live => "直播", LinkTypeEnum.video => "视频", _ => "非标链接", }; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.shortLinkurl = url; result.deeplink_url = GetDeeplink(url, clickId); return result; case LinkTypeEnum.other_aff: result.success = false; result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.jd; result.message = "放弃转链"; result.reason = "其他推广链接"; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.shortLinkurl = url; result.deeplink_url = GetDeeplink(url, clickId); return result; default: if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(result.itemId) || (!url.StartsWith("https://item.jd.com/") && !url.StartsWith("http://item.jd.com/") && !url.StartsWith("https://item.m.jd.com/product/") && !url.StartsWith("http://item.m.jd.com/product/") && !url.StartsWith("http://item.m.jd.com/product/"))) { result.success = false; //result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.jd; result.message = "放弃转链"; result.reason = "非标链接"; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.shortLinkurl = url; result.deeplink_url = result.link_type switch { LinkTypeEnum.other_aff or LinkTypeEnum.baseDomain or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId), _ => JdUnionPlus.GetDeeplink(string.Empty, clickId), }; return result; } break; } if (!result.ip.StartsWith("127.0.0") && FlowControlIgnoreRequest(_config, out string reason)) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.channel_type = ChannelTypeEnum.jd; result.message = "放弃转链"; result.reason = reason; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.shortLinkurl = url; result.deeplink_url = result.link_type switch { LinkTypeEnum.other_aff or LinkTypeEnum.goods => JdUnionPlus.GetDeeplink(result.shortLinkurl, clickId), _ => JdUnionPlus.GetDeeplink(string.Empty, clickId), }; return result; } switch (commerceType) { case 1: case 2: result.success = false; result.message = "放弃转链"; result.reason = $"厂商放弃{commerceType}"; return result; } switch (_account.work_mode) { case JdUnionWorkMode.SiteApi: result = await GetPromotionBySiteAsync(result, url, clickId, cancellationToken); break; case JdUnionWorkMode.AffApi: result = await GetPromotionByAffAsync(result, url, clickId, cancellationToken); break; case JdUnionWorkMode.Crawler: default: result = await GetPromotionByCrawlerAsync(result, url, clickId, cancellationToken); break; } return result; } } }