using COSXML.Network; using dodohold.core; using Spire.Pdf.Graphics; using System.Diagnostics; using System.Net; using System.Text.RegularExpressions; using TencentCloud.Apm.V20210622.Models; using static dodohold.core.ZTOExpress.CreateOrderArgs; namespace molilian.core { public partial class KsUnionPlus { public static string _url_pattern = @"https?://(?:[\w-]+\.)*(?:chenzhongtech\.com|kuaishou\.com)(?:/[^\s]*)?"; public static string GetLink(string content) { if (string.IsNullOrEmpty(content)) return content; string result = content; // Regex regex = new(_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 GetDeeplink(string url, LinkTypeEnum type) { string shareObjectId = string.Empty; string url_pattern = @"shareObjectId=([^,%&]+)"; var match = Regex.Match(url, url_pattern); if (match.Success) shareObjectId = match.Groups[1].Value; string result = type switch { LinkTypeEnum.video => $"kwai://work/{shareObjectId}", LinkTypeEnum.profile => $"kwai://profile/{shareObjectId}", LinkTypeEnum.live => $"kwai://live/play/{shareObjectId}", LinkTypeEnum.baseDomain or LinkTypeEnum.other_aff => "kwai://home", LinkTypeEnum.goods or LinkTypeEnum.note => "kwai://home", _ => string.Empty, }; return result; } public static KsDataDTO GetFormattedObject(string content, string ip = "", string oaid = "") { string shortLinkurl = GetLink(content); LinkTypeEnum link_type = string.IsNullOrEmpty(shortLinkurl) ? LinkTypeEnum.unknown : LinkTypeEnum.baseDomain; string deeplink_url = GetDeeplink(shortLinkurl, link_type); return new KsDataDTO() { message = string.Empty, link_type = link_type, channel = TkChannelEnum.ks, 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, }; } private LinkTypeEnum GetLinkType(string url) { if (string.IsNullOrEmpty(url)) return LinkTypeEnum.unknown; string url_pattern = @"https?://(?:[\w-]+\.)*(?:chenzhongtech\.com|kuaishou\.com)/fw/(?:photo|long-video)/[^\s]*\bshareObjectId=[^\s&]+"; var match = Regex.Match(url, url_pattern); if (match.Success) return LinkTypeEnum.video; url_pattern = @"https?://(?:[\w-]+\.)*(?:chenzhongtech\.com|kuaishou\.com)/fw/user/[^\s]*\bshareObjectId=[^\s&]+"; match = Regex.Match(url, url_pattern); if (match.Success) return LinkTypeEnum.profile; url_pattern = @"https?://(?:[\w-]+\.)*(?:chenzhongtech\.com|kuaishou\.com)/fw/live/[^\s]*\bshareObjectId=[^\s&]+"; match = Regex.Match(url, url_pattern); if (match.Success) return LinkTypeEnum.live; if (url.Contains("chenzhongtech.com") || url.Contains("kuaishou.com")) return LinkTypeEnum.baseDomain; return LinkTypeEnum.unknown; } private bool IsAffCode(string content) { string url_pattern = @"復制整段消息,打開快手|复制整段消息,打开快手"; var match = Regex.Match(content, url_pattern); if (match.Success) return true; return false; } private async Task<(bool, string)> GetDesiredUrlAsync(string url) { string result = url; try { string pattern = @"https:\/\/v\.kuaishou\.com\/[A-Za-z0-9]+"; Match match = Regex.Match(url, pattern); //不是短网址,不用展开 if (!match.Success) return (true, url); WebClientUtility client = new() { Proxy = _proxy ?? ProxyNodesCore.RandomOne(), UserAgent = Sayaka.Common.ProviderFakeUserAgent.RandomComputer, AllowAutoRedirect = false }; #if DEBUG client.Proxy = null; #endif client.Timeout = GetRequestTimeout(0); var response = await client.RequestAsync(url); if (response.ResponseMessage != null) { result = response.ResponseMessage.Headers.Location.ToString(); result = result.UrlDecode(); return (true, result); } } catch (Exception ex) { result = $"{ex.Message}\n{ex.StackTrace}"; } return (false, result); } public TimeSpan GetRequestTimeout(int deduction = 0) { #if DEBUG return TimeSpan.FromMilliseconds(10 * 1000); #endif int min = (int)(_config.rt_max * 0.3); if (_config.rt_max == 0) return TimeSpan.FromMilliseconds(1000); int timeout = _config.rt_max; if (deduction == 0) { timeout -= min; return TimeSpan.FromMilliseconds(timeout); } timeout -= deduction; if (timeout <= min) return TimeSpan.FromMilliseconds(1); return TimeSpan.FromMilliseconds(min); } public async Task KsParseAsync(string content, KsDataDTO result, CancellationToken cancellationToken = default) { //正文里面不包含url if (string.IsNullOrEmpty(result.shortLinkurl) && IsAffCode(content)) { result.success = false; result.link_type = LinkTypeEnum.other_aff; result.message = "放弃转链"; result.reason = "其他推广链接"; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.deeplink_url = GetDeeplink(content, LinkTypeEnum.goods); return result; } string url = string.Empty; if (!string.IsNullOrEmpty(result.shortLinkurl)) { //从http获取跳转的url Stopwatch stopwatch = Stopwatch.StartNew(); stopwatch.Start(); (bool success, url) = await GetDesiredUrlAsync(result.shortLinkurl); stopwatch.Stop(); // 获取执行时间 result.elapsedTime2 = (int)stopwatch.ElapsedMilliseconds; result.link_type = GetLinkType(url); if (result.link_type == LinkTypeEnum.other_aff) { result.success = false; result.message = "放弃转链"; result.reason = "其他推广链接"; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.deeplink_url = GetDeeplink(content, LinkTypeEnum.goods); return result; } //没有链接、 不是链接 if (!success) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.message = "放弃转链"; result.reason = url; result.accountId = 0; result.accountName = string.Empty; result.content = content; return result; } result.deeplink_url = GetDeeplink(url, result.link_type); //临时规则 if (!content.Contains("商品")) { result.success = false; result.message = "放弃转链"; result.reason = "非商品链接"; result.deeplink_url = GetDeeplink(content, LinkTypeEnum.goods); } return result; } if (!result.ip.StartsWith("127.0.0") && FlowControlIgnoreRequest(_config, out string reason)) { result.success = false; result.link_type = LinkTypeEnum.unknown; result.message = "放弃转链"; result.reason = reason; result.accountId = 0; result.accountName = string.Empty; result.content = content; result.deeplink_url = GetDeeplink(content, LinkTypeEnum.goods); return result; } //result.shortLinkurl = url; //临时规则 if (!content.Contains("商品")) { result.success = false; result.message = "放弃转链"; result.reason = "非商品链接"; result.deeplink_url = GetDeeplink(content, LinkTypeEnum.goods); return result; } switch (_account.work_mode) { case KsUnionWorkMode.SiteApi: result = await UnionGeneratelink(result, content, cancellationToken); break; case KsUnionWorkMode.Crawler: default: //result = await transferUrl(result, url, cancellationToken); break; } return result; } } }