| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- 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;
- using System.Web;
- namespace molilian.core
- {
- public partial class JdUnionPlus
- {
- private const string VIDEO_URL_PREFIX = "https://h5.m.jd.com/active/faxian/video/index.html";
- 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<Match>())
- {
- 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;
- if (!string.IsNullOrEmpty(url) && url.StartsWith(VIDEO_URL_PREFIX))
- {
- // 处理视频URL的情况
- var queryString = url.Substring(VIDEO_URL_PREFIX.Length + 1); // +1 for the '?' character
- var queryParams = HttpUtility.ParseQueryString(queryString);
- var paramsDict = queryParams.AllKeys.ToDictionary(k => k, k => queryParams[k]);
- paramsDict["category"] = "jump";
- paramsDict["m_param"] = $"{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}";
- virtual_params = JsonSerializer.Serialize(paramsDict);
- }
- else if (string.IsNullOrEmpty(url))
- {
- virtual_params = $"{{\"category\":\"jump\",\"des\":\"HomePage\",\"m_param\":{{\"jdv\":\"0|oppo_seedling|-|widget|{clickId}|{ts}\"}}";
- }
- else
- {
- 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;
- if (url.StartsWith(VIDEO_URL_PREFIX))
- {
- // 处理视频URL的情况
- var queryString = url.Substring(VIDEO_URL_PREFIX.Length + 1);
- var queryParams = HttpUtility.ParseQueryString(queryString);
- var paramsDict = queryParams.AllKeys.ToDictionary(k => k, k => queryParams[k]);
- paramsDict["category"] = "jump";
- virtual_params = JsonSerializer.Serialize(paramsDict);
- }
- else
- {
- 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 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 = GetDefaultStyleDeeplink(shortLinkurl);
- 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 async Task<JdDataDTO> 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 = GetDefaultStyleDeeplink(url);
- return result;
- }
- string shortLinkurl = url;
- //result.link_type = plus.IsAffLlink(url) ? LinkTypeEnum.other_aff : LinkTypeEnum.goods;
- result.shortLinkurl = url;
- 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 = GetDefaultStyleDeeplink(url);
- 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 = GetDefaultStyleDeeplink(url);
- 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 = shortLinkurl;
- result.deeplink_url = result.link_type switch
- {
- LinkTypeEnum.other_aff or
- LinkTypeEnum.baseDomain or
- LinkTypeEnum.goods => GetDefaultStyleDeeplink(result.shortLinkurl),
- _ => GetDefaultStyleDeeplink(result.shortLinkurl),
- };
- return result;
- }
- break;
- }
- if (!TestParseCore.InWhitelist(result.ip, result.oaid) && FlowControlIgnoreRequest(_config, result.riskStrategy, result.launchScene, 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 => GetDefaultStyleDeeplink(result.shortLinkurl),
- _ => GetDefaultStyleDeeplink(result.shortLinkurl),
- };
- 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.Ddx:
- result = await GetPromotionByDdxAsync(result, url, clickId, cancellationToken);
- break;
- case JdUnionWorkMode.JingFen:
- result = await GetPromotionByCrawlerJingfenAsync(result, url, clickId, cancellationToken);
- break;
- case JdUnionWorkMode.Crawler:
- default:
- result = await GetPromotionByCrawlerAsync(result, url, clickId, cancellationToken);
- break;
- }
- return result;
- }
- }
- }
|