public static async Task <List <TimelineTweet> > GetTimelineByWebAsync(string screenName) { using (var client = HttpClientExtensions.CreateClient(referer: "https://twitter.com/" + screenName, useGZip: true)) { client.DefaultRequestHeaders.Accept.ParseAdd("application/json, text/javascript, */*; q=0.01"); client.DefaultRequestHeaders.Add("x-previous-page-name", "profile"); client.DefaultRequestHeaders.Add("x-twitter-active-user", "yes"); var json = JToken.Parse(await client.GetStringAsync( $"https://twitter.com/i/profiles/show/{screenName}/timeline/tweets?include_available_features=1&include_entities=1&reset_error_state=false")); var doc = new HtmlDocument(); doc.LoadHtml(json["items_html"].ToString()); return((from liNode in doc.DocumentNode.ChildNodes.Where(v => v.Name == "li") let pinned = liNode.Attributes.First(v => v.Name == "class").Value.Trim().EndsWith("pinned") let id = long.Parse(liNode.Attributes.First(v => v.Name == "data-item-id").Value) let div = liNode.ChildNodes.First(v => v.Name == "div").ChildNodes.Last(v => v.Name == "div") let content = div.ChildNodes.First(v => v.Name == "div" && v.Attributes.Any(att => att.Value == "js-tweet-text-container")) .InnerText .Trim() select new TimelineTweet() { Id = id, Pinned = pinned, ScreenName = screenName, Retweeted = liNode.ChildNodes.First(v => v.Name == "div").ChildNodes.First(v => v.Name == "div") .InnerText.Contains("Retweeted"), Content = content }).ToList()); } }
public static async Task <BilibiliUser> GetBilibiliUserAsync(long userId) { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JObject.Parse(await client.GetStringAsync(Sign("https://api.bilibili.com/x/space/app/index", new { mid = userId }))); return(json["data"]["info"].ToObject <BilibiliUser>()); } }
public static async Task <VtuberDatabaseEntity[]> GetDatabaseEntitiesAsync() { using (var client = HttpClientExtensions.CreateClient()) { var json = JToken.Parse(await client.GetStringAsync("https://vdb.vtbs.moe/json/list.json")); return(json["vtbs"].ToObject <VtuberDatabaseEntity[]>()); } }
public async Task <List <TweetCard> > GetAllCommentAsync() { using (var client = HttpClientExtensions.CreateClient(referer: "https://twitter.com/" + ScreenName, useGZip: true)) { client.DefaultRequestHeaders.Accept.ParseAdd("application/json, text/javascript, */*; q=0.01"); client.DefaultRequestHeaders.Add("x-overlay-request", "true"); client.DefaultRequestHeaders.Add("x-previous-page-name", "profile"); client.DefaultRequestHeaders.Add("x-twitter-active-user", "yes"); var json = JToken.Parse(await client.GetStringAsync( $"https://twitter.com/i/{ScreenName}/conversation/{Id}?include_available_features=1&include_entities=1&max_position={MinPosition}&reset_error_state=false")); var comments = new List <TweetCard>(); string minPosition; do { var doc = new HtmlDocument(); doc.LoadHtml(json["items_html"].ToString()); minPosition = json["min_position"]?.ToString(); foreach (var node in doc.DocumentNode.ChildNodes.Where(v => v.Name == "li")) { var context = node.ChildNodes.First(v => v.Name == "ol").ChildNodes .FirstOrDefault(v => v.Name == "li"); if (context == null || context.Attributes.First(v => v.Name == "class").Value == "ThreadedConversation-moreReplies") { context = node.ChildNodes .First(v => v.Name == "ol").ChildNodes .First(v => v.Name == "div").ChildNodes.First(v => v.Name == "li"); } var id = context.Attributes.FirstOrDefault(v => v.Name == "data-item-id")?.Value; var info = context.ChildNodes.First(v => v.Name == "div"); var authorDisplayName = info.Attributes.First(v => v.Name == "data-name").Value; var message = info.ChildNodes.First(v => v.Name == "div" && v.ChildNodes.Count > 2) .ChildNodes .First(v => v.Attributes.Any(att => att.Name == "class" && att.Value == "js-tweet-text-container")).ChildNodes .First(v => v.Name == "p"); var authorScreenName = info.ChildNodes.First(v => v.Name == "div" && v.ChildNodes.Count > 2) .ChildNodes .First(v => v.Attributes.Any(att => att.Name == "class" && att.Value == "stream-item-header")).ChildNodes .First(v => v.Name == "a").Attributes.First(v => v.Name == "href").Value; comments.Add(new TweetCard() { Id = long.Parse(id), DisplayName = authorDisplayName, ScreenName = authorScreenName.Substring(1, authorScreenName.Length - 1), Content = message.InnerText }); } json = JToken.Parse(await client.GetStringAsync( $"https://twitter.com/i/{ScreenName}/conversation/{Id}?include_available_features=1&include_entities=1&max_position={minPosition}&reset_error_state=false")); } while (!string.IsNullOrEmpty(minPosition)); return(comments.Union(RootComments).ToList()); } }
public static async Task InitAccessToken() { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", BaseToken); var json = JObject.Parse(await(await client.PostFormAsync("https://api.twitter.com/oauth2/token", new { grant_type = "client_credentials" })).Content.ReadAsStringAsync()); AccessToken = json["access_token"].ToObject <string>(); } }
public static async Task <List <UserlocalSearchItem> > SearchAsync(string keyword) { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JToken.Parse(await client.GetStringAsync( "https://social.userlocal.jp/apis/data/youtube_vy_search.php?output=json&q=" + keyword.UrlEncode())); return(json.ToObject <List <UserlocalSearchItem> >()); } }
public static async Task <UserlocalVtuberInfo> GetVtuberInfoAsync(string id) { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JToken.Parse( await client.GetStringAsync( $"https://social.userlocal.jp/apis/data/youtube.php?user_name={id}&output=json")); return(json.ToObject <UserlocalVtuberInfo>()); } }
public static async Task <List <UserlocalSchedule> > GetSchedulesAsync() { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JToken.Parse( await client.GetStringAsync( "https://social.userlocal.jp/apis/data/youtube_vy_live_program.php?output=json")); return(json.ToObject <List <UserlocalSchedule> >()); } }
public static async Task <string> GetTweetCardHtmlAsync(long id) { var url = "https://twitter.com/kmnzlita/status/" + id; using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JToken.Parse(await client.GetStringAsync( $"https://publish.twitter.com/oembed?url={url.UrlEncode()}&theme=light&link_color=%23981CEB&lang=zh-cn")); return(json["html"].ToString()); } }
public void InitDanmakuServer() { using (var client = HttpClientExtensions.CreateClient()) { var xml = client.GetStringAsync("https://live.bilibili.com/api/player?id=cid:" + RoomId).GetAwaiter().GetResult(); xml = $"<root>{xml}</root>"; var doc = new XmlDocument(); doc.LoadXml(xml); DanmakuServer = doc["root"]["dm_host_list"].InnerText.Split(',').First(); } }
public static async Task <List <BilibiliDynamic> > GetDynamicsByUser(long userId) { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JToken.Parse(await client.GetStringAsync(Sign( "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history", new { host_uid = userId }))); if (json.Value <int>("code") != 0) { return(new List <BilibiliDynamic>()); } return(json["data"]["cards"].ToArray().Select(v => v.ToObject <BilibiliDynamic>()).ToList()); } }
public static async Task <YoutubeLiveChatInfo> GetLiveChatInfoAsync(string liveChatId) { try { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) return(JsonConvert.DeserializeObject <YoutubeLiveChatInfo>(await client.GetStringAsync( $"https://www.googleapis.com/youtube/v3/liveChat/messages?liveChatId={liveChatId}&part=id%2Csnippet&key={ApiKey}&maxResults=2000"))); } catch { return(null); } }
public static async Task <TweetCard> GetTweetCardAsync(string screenName, long id) { using (var client = HttpClientExtensions.CreateClient(referer: "https://twitter.com/" + screenName, useGZip: true)) { client.DefaultRequestHeaders.Accept.ParseAdd("application/json, text/javascript, */*; q=0.01"); client.DefaultRequestHeaders.Add("x-overlay-request", "true"); client.DefaultRequestHeaders.Add("x-previous-page-name", "profile"); client.DefaultRequestHeaders.Add("x-twitter-active-user", "yes"); var json = JToken.Parse(await client.GetStringAsync( $"https://twitter.com/{screenName}/status/{id}?conversation_id={id}")); var doc = new HtmlDocument(); doc.LoadHtml(json["page"].ToString()); var content = doc.DocumentNode.SelectSingleNode("/div/div[1]/div[1]/div/div[2]/p")?.InnerText; var minPosition = doc.DocumentNode.SelectSingleNode("//*[@id=\"descendants\"]/div").Attributes.First(v => v.Name == "data-min-position").Value; var rootComments = new List <TweetCard>(); var commentsNode = doc.DocumentNode.SelectSingleNode("//*[@id=\"stream-items-id\"]"); foreach (var threadNode in commentsNode.ChildNodes.Where(v => v.Name == "li")) { foreach (var divNode in threadNode.ChildNodes.First(v => v.Name == "ol").ChildNodes.Where(v => v.Name == "div")) { var a = divNode.ChildNodes.First(v => v.Name == "li").ChildNodes.First(v => v.Name == "div"); var commentTweetId = a.Attributes.First(v => v.Name == "data-tweet-id").Value; var authorDisplayName = a.Attributes.First(v => v.Name == "data-name").Value; var message = a.ChildNodes.First(v => v.Name == "div" && v.ChildNodes.Count > 2).ChildNodes .First(v => v.Attributes.Any(att => att.Name == "class" && att.Value == "js-tweet-text-container")).ChildNodes .First(v => v.Name == "p"); var authorScreenName = a.ChildNodes.First(v => v.Name == "div" && v.ChildNodes.Count > 2).ChildNodes .First(v => v.Attributes.Any(att => att.Name == "class" && att.Value == "stream-item-header")).ChildNodes .First(v => v.Name == "a").Attributes.First(v => v.Name == "href").Value; rootComments.Add(new TweetCard() { Id = long.Parse(commentTweetId), DisplayName = authorDisplayName, ScreenName = authorScreenName.Substring(1, authorScreenName.Length - 1), Content = message.InnerText }); } } return(new TweetCard() { Id = id, Content = content, ScreenName = screenName, MinPosition = minPosition, RootComments = rootComments }); } }
public bool Load() { LogHelper.Info($"正在使用 {ListenUrl} 启动 Clever Service."); Websocket = new ClientWebSocket(); Websocket.ConnectAsync(new Uri(WebsocketUrl), CancellationToken.None).GetAwaiter().GetResult(); Running = true; BeginProcessMessage(); if (!ListenUrl.EndsWith("/")) { ListenUrl += "/"; } using (var client = HttpClientExtensions.CreateClient()) client.PostJsonAsync(ListenUrl + "Api_GetQQList", new object()).GetAwaiter().GetResult(); return(true); }
public async Task CallYoutubeUploadVideoAsync(VtuberEntity vtuber, YoutubeVideo video) { using (var client = HttpClientExtensions.CreateClient()) { var body = new YoutubeVideoCallbackBody() { VtuberName = vtuber.OriginalName, VideoLink = video.VideoLink, VideoTitle = video.Title, PublishTime = video.PublishTime.ToTimestamp(), Sign = Sign }; await client.PostJsonAsync(Url + "youtube/video", body); } }
public static async Task <bool> NowLive(string channelId) { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("zh")); var html = await client.GetStringAsync($"https://www.youtube.com/channel/{channelId}/live"); var liveJson = ParseYoutubeInitData(html); var liveStatus = liveJson .SelectToken( "contents.twoColumnWatchNextResults.results.results.contents.[1].videoSecondaryInfoRenderer.dateText.simpleText")? .ToString(); return(liveStatus?.Contains("直播开始") ?? false); } }
public async Task CallBilibiliBeginLiveAsync(VtuberEntity vtuber, BilibiliLiveRoom room) { using (var client = HttpClientExtensions.CreateClient()) { var body = new BilibiliLiveCallbackBody() { VtuberName = vtuber.OriginalName, LiveLink = "https://live.bilibili.com/" + vtuber.BilibiliLiveRoomId, LiveTitle = room.Title, StartTime = DateTime.Now.ToTimestamp(), Sign = Sign }; await client.PostJsonAsync(Url + "bilibili/live", body); } }
public async Task CallYoutubeCommentedAsync(VtuberEntity commentAuthor, VtuberEntity liveAuthor, YoutubeLiveChat comment) { using (var client = HttpClientExtensions.CreateClient()) { var body = new YoutubeLiveChatCallbackBody() { VtuberName = commentAuthor.OriginalName, LiveAuthorName = liveAuthor.OriginalName, LiveLink = "https://www.youtube.com/watch?v=" + comment.VideoId, Message = comment.DisplayMessage, PublishTime = comment.PublishTime.ToTimestamp(), Sign = Sign }; await client.PostJsonAsync(Url + "youtube/live/vtuberCommented", body); } }
public static List <HiyokoTimelineItem> GetLiveTimeline(string date) { using (var client = HttpClientExtensions.CreateClient()) { var requestJson = new JObject() { ["date"] = date, ["user_token"] = null }; return(JsonConvert.DeserializeObject <List <HiyokoTimelineItem> >( JObject.Parse(client .PostJsonAsync("https://hiyoko.sonoj.net/f/avtapi/schedule/fetch_curr", requestJson) .GetAwaiter().GetResult().Content.ReadAsStringAsync().GetAwaiter().GetResult())["schedules"] .ToString())); } }
public async Task <bool> SendGroupMessageAsync(long groupId, SendingMessage message) { using (var client = HttpClientExtensions.CreateClient()) { await client.PostJsonAsync(ListenUrl + "Api_SendMsg", new { 响应QQ = QQ.ToString(), 信息类型 = MahuaMessageType.Group, 收信对象群_讨论组 = groupId.ToString(), 收信QQ = groupId.ToString(), 内容 = message.ToString(), 气泡ID = 0 }); } return(true); }
public async Task CallYoutubeStopLiveAsync(VtuberEntity vtuber, YoutubeVideo live) { using (var client = HttpClientExtensions.CreateClient()) { var body = new YoutubeLiveCallbackBody() { VtuberName = vtuber.OriginalName, LiveTitle = live.Title, LiveLink = live.VideoLink, ScheduledStartTime = live.LiveDetails.ScheduledStartTime.ToTimestamp(), ActualStartTime = live.LiveDetails.ActualStartTime?.ToTimestamp() ?? DateTime.Now.ToTimestamp(), ViewersCount = 0, Sign = Sign }; await client.PostJsonAsync(Url + "youtube/live/stop", body); } }
public async Task CallReplyAsync(VtuberEntity vtuber, TweetInfo tweet) { using (var client = HttpClientExtensions.CreateClient()) { var body = new TwitterCallbackBody() { VtuberName = vtuber.OriginalName, Content = tweet.Content, IsReply = tweet.IsReply, PublishTime = tweet.CreateTime.ToTimestamp(), ReplyScreenName = tweet.ReplyScreenname, RetweetedUsername = tweet.RetweetedTweet?.User?.Name, Sign = Sign }; await client.PostJsonAsync(Url + "tweet/reply", body); } }
public static async Task <BilibiliLiveRoom> GetLiveRoomAsync(long roomId) { try { using (var client = HttpClientExtensions.CreateClient()) { var json = JToken.Parse(await client.GetStringAsync(Sign( "https://api.live.bilibili.com/xlive/app-room/v1/index/getInfoByRoom", new { room_id = roomId }))); return(json["data"]?["room_info"]?.ToObject <BilibiliLiveRoom>()); } } catch { return(null); } }
public async Task <JToken> PostRequestAsync(string method, object requestParams) { var waitEvent = new ManualResetEvent(false); JToken result = null; using (var client = HttpClientExtensions.CreateClient()) { await client.PostJsonAsync(ListenUrl + method, requestParams); Callbacks.Add((method + "ApiOut").ToLower(), json => { result = json; waitEvent.Set(); }); } waitEvent.WaitOne(); return(result); }
public async Task <bool> SendGroupMessageAsync(long groupId, SendingMessage message) { using (var client = HttpClientExtensions.CreateClient()) { //NMD为啥MPQ变成了 ‘响应的QQ’了,太不上心了吧 await client.PostJsonAsync(ListenUrl + "Api_SendMsg", new { 响应的QQ = QQ.ToString(), 信息类型 = MahuaMessageType.Group, 参考子类型 = 0, 收信对象群_讨论组 = groupId.ToString(), 收信对象 = groupId.ToString(), 内容 = message.ToString(), }); return(true); } }
public static async Task <YoutubeChannel> GetYoutubeChannelAsync(string channelId) { using (var client = HttpClientExtensions.CreateClient(useGZip: true, referer: "https://www.youtube.com/", proxy: Proxy)) { client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("zh")); var page = await client.GetStringAsync("https://www.youtube.com/channel/" + channelId); var livePage = await client.GetStringAsync($"https://www.youtube.com/channel/{channelId}/live"); var homeJson = ParseYoutubeInitData(page); var liveJson = ParseYoutubeInitData(livePage); var liveStatus = liveJson .SelectToken( "contents.twoColumnWatchNextResults.results.results.contents.[1].videoSecondaryInfoRenderer.dateText.simpleText")? .ToString(); var subscriberText = homeJson.SelectToken("header.c4TabbedHeaderRenderer.subscriberCountText.simpleText")?.ToString(); var microData = homeJson.SelectToken("microformat.microformatDataRenderer"); var viewerCountText = liveJson.SelectToken( "contents.twoColumnWatchNextResults.results.results.contents.[0].videoPrimaryInfoRenderer.viewCount.videoViewCountRenderer.viewCount.runs.[0].text") ?.ToString(); var liveVideoId = liveJson.SelectToken( "contents.twoColumnWatchNextResults.results.results.contents.[0].videoPrimaryInfoRenderer.videoActions.menuRenderer.topLevelButtons" + ".[1].toggleButtonRenderer.defaultNavigationEndpoint.modalEndpoint.modal.modalWithTitleAndButtonRenderer.button.buttonRenderer" + ".navigationEndpoint.signInEndpoint.nextEndpoint.watchEndpoint.videoId")? .ToString(); return(new YoutubeChannel() { ChannelId = channelId, ChannelName = microData["title"].ToString(), Description = microData["description"].ToString(), Tags = microData["tags"]?.ToObject <string[]>(), SubscriberCount = subscriberText == null ? 0 : int.Parse(Regex .Match(subscriberText.Replace(",", string.Empty), "\\d+(\\.\\d+){0,1}").Groups.First() .Value), NowLive = liveStatus?.Contains("直播开始") ?? false, LiveVideoId = liveVideoId, LiveViewerCount = viewerCountText == null ? 0 : int.Parse(Regex .Match(viewerCountText.Replace(",", string.Empty), "\\d+(\\.\\d+){0,1}").Groups.First() .Value), Face = homeJson.SelectToken("responseContext.webResponseContextExtensionData.webResponseContextPreloadData.preloadThumbnailUrls.[3]")?.ToString() }); } }
public static async Task <List <TweetInfo> > GetTimelineByUserAsync(string username, int count = 5) { try { if (string.IsNullOrEmpty(AccessToken)) { await InitAccessToken(); } using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); return(JsonConvert.DeserializeObject <List <TweetInfo> >(await client.GetStringAsync( $"https://api.twitter.com/1.1/statuses/user_timeline.json?count={count}&screen_name={username}"))); } } catch { return(null); } }
private async Task <BilibiliVideoInfo> GetBaseBilibiliVideoInfoAsync(long aid) { using (var client = HttpClientExtensions.CreateClient(useGZip: true, referer: "https://www.bilibili.com/video/av" + aid, cookies: BilibiliCookies, cookiesDomain: ".bilibili.com")) { var json = JToken.Parse( await client.GetStringAsync("https://api.bilibili.com/x/web-interface/view?aid=" + aid)); if (json.Value <int>("code") != 0) { return(null); } var data = json["data"]; return(new BilibiliVideoInfo() { Aid = data["aid"].ToObject <long>(), Title = data["title"].ToString(), Cover = data["pic"].ToString(), CreatedTime = data["ctime"].ToObject <long>(), Description = data["desc"].ToString(), Uploader = data["owner"]["mid"].ToObject <long>() }); } }
public static async Task <List <BilibiliUser> > SearchBilibiliUsersAsync(string keyword) { using (var client = HttpClientExtensions.CreateClient(useGZip: true)) { var json = JToken.Parse(await client.GetStringAsync( $"https://app.bilibili.com/x/v2/search/type?&build=12080&highlight=1&keyword={Uri.EscapeDataString(keyword)}&order=totalrank&order_sort=1&type=2")); if (json["data"].HasValues) { var items = json["data"]["items"]; var users = items.Select(v => new BilibiliUser() { Username = v["title"]?.ToString(), Id = int.Parse(v["param"]?.ToString()), Description = v["sign"]?.ToString(), Follower = v["fans"]?.ToObject <int>() ?? 0, IsUploader = v["is_up"]?.ToObject <bool>() ?? false }); return(users.ToList()); } return(new List <BilibiliUser>()); } }
public static async Task <YoutubeVideo> GetYoutubeVideoAsync(string videoId) { using (var client = HttpClientExtensions.CreateClient(useGZip: true, referer: "https://www.youtube.com/")) { var json = JObject.Parse(await client.GetStringAsync( $"https://www.googleapis.com/youtube/v3/videos?id={videoId}&key={ApiKey}&part=liveStreamingDetails,snippet")); if (json["pageInfo"]["totalResults"].ToObject <int>() != 1 || json["items"].First["snippet"]["title"].ToString() == "Deleted video") { return(null); } var item = json["items"].First(); var snippet = item["snippet"]; var result = new YoutubeVideo() { Title = snippet["title"].ToObject <string>(), PublishTime = DateTime.Parse(snippet["publishedAt"].ToObject <string>()), ChannelId = snippet["channelId"].ToObject <string>(), VideoId = item["id"].ToObject <string>(), VideoLink = "https://www.youtube.com/watch?v=" + item["id"].ToObject <string>(), ChannelTitle = snippet["channelTitle"].ToObject <string>(), ThumbnailLink = snippet["thumbnails"]["default"]["url"].ToObject <string>(), Description = snippet["description"].ToObject <string>(), IsLive = snippet["liveBroadcastContent"].ToObject <string>() == "live", }; if (item["liveStreamingDetails"] != null) { result.LiveDetails = item["liveStreamingDetails"].ToObject <LiveStreamingDetail>(); } var page = await client.GetStringAsync("https://www.youtube.com/watch?v=" + videoId); var initData = ParseYoutubeInitData(page); var tempId = initData.SelectToken( "contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer.continuations.[0].reloadContinuationData.continuation")?.ToString(); result.WebLiveChatId = tempId; return(result); } }