Mercurial > rsstweet
comparison app/lib/legit_client.rb @ 238:a04b4830eef2 legit-client
Filter out non-own tweets included for replies
author | nanaya <me@nanaya.net> |
---|---|
date | Sat, 15 Jul 2023 01:53:05 +0900 |
parents | 961d362e42c7 |
children | c454ea4f7b34 |
comparison
equal
deleted
inserted
replaced
237:961d362e42c7 | 238:a04b4830eef2 |
---|---|
3 resp = fetch("https://twitter.com/i/api/graphql/1-5o8Qhfc2kWlu_2rWNcug/UserTweetsAndReplies?variables=%7B%22userId%22%3A#{escape_param user_id}%2C%22count%22%3A50%2C%22includePromotedContent%22%3Atrue%2C%22withCommunity%22%3Atrue%2C%22withVoice%22%3Atrue%2C%22withV2Timeline%22%3Atrue%7D&features=%7B%22rweb_lists_timeline_redesign_enabled%22%3Atrue%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22tweetypie_unmention_optimization_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Afalse%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_media_download_video_enabled%22%3Afalse%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withAuxiliaryUserLabels%22%3Afalse%2C%22withArticleRichContentState%22%3Afalse%7D") | 3 resp = fetch("https://twitter.com/i/api/graphql/1-5o8Qhfc2kWlu_2rWNcug/UserTweetsAndReplies?variables=%7B%22userId%22%3A#{escape_param user_id}%2C%22count%22%3A50%2C%22includePromotedContent%22%3Atrue%2C%22withCommunity%22%3Atrue%2C%22withVoice%22%3Atrue%2C%22withV2Timeline%22%3Atrue%7D&features=%7B%22rweb_lists_timeline_redesign_enabled%22%3Atrue%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22tweetypie_unmention_optimization_enabled%22%3Atrue%2C%22responsive_web_edit_tweet_api_enabled%22%3Atrue%2C%22graphql_is_translatable_rweb_tweet_is_translatable_enabled%22%3Atrue%2C%22view_counts_everywhere_api_enabled%22%3Atrue%2C%22longform_notetweets_consumption_enabled%22%3Atrue%2C%22responsive_web_twitter_article_tweet_consumption_enabled%22%3Afalse%2C%22tweet_awards_web_tipping_enabled%22%3Afalse%2C%22freedom_of_speech_not_reach_fetch_enabled%22%3Atrue%2C%22standardized_nudges_misinfo%22%3Atrue%2C%22tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled%22%3Atrue%2C%22longform_notetweets_rich_text_read_enabled%22%3Atrue%2C%22longform_notetweets_inline_media_enabled%22%3Atrue%2C%22responsive_web_media_download_video_enabled%22%3Afalse%2C%22responsive_web_enhance_cards_enabled%22%3Afalse%7D&fieldToggles=%7B%22withAuxiliaryUserLabels%22%3Afalse%2C%22withArticleRichContentState%22%3Afalse%7D") |
4 | 4 |
5 begin | 5 begin |
6 json = JSON.parse(resp) | 6 json = JSON.parse(resp) |
7 { | 7 { |
8 timeline: normalize_timeline(json['data']['user']['result']['timeline_v2']['timeline']['instructions']), | 8 timeline: normalize_timeline(json['data']['user']['result']['timeline_v2']['timeline']['instructions'], user_id), |
9 raw: resp, | 9 raw: resp, |
10 } | 10 } |
11 rescue => e | 11 rescue => e |
12 return if (json || {}).dig('data').is_a? Hash | 12 return if (json || {}).dig('data').is_a? Hash |
13 Rails.logger.error("timeline fail: #{user_id}: #{resp}") | 13 Rails.logger.error("timeline fail: #{user_id}: #{resp}") |
100 end | 100 end |
101 | 101 |
102 ret | 102 ret |
103 end | 103 end |
104 | 104 |
105 def self.normalize_timeline(json) | 105 def self.normalize_timeline(json, user_id) |
106 json.find { |instruction| instruction['type'] == 'TimelineAddEntries' }['entries'] | 106 json.find { |instruction| instruction['type'] == 'TimelineAddEntries' }['entries'] |
107 .filter { |entry| entry['entryId'] =~ /\A(profile-conversation|tweet)-/ } | 107 .filter { |entry| entry['entryId'] =~ /\A(profile-conversation|tweet)-/ } |
108 .reduce([]) do |acc, entry| | 108 .reduce([]) do |acc, entry| |
109 if entry['content']['entryType'] == 'TimelineTimelineItem' | 109 if entry['content']['entryType'] == 'TimelineTimelineItem' |
110 acc.push(entry['content']) | 110 acc.push(entry['content']) |
113 acc.push(item['item']) | 113 acc.push(item['item']) |
114 end | 114 end |
115 end | 115 end |
116 acc | 116 acc |
117 end.map { |rawTweet| normalize_tweet(rawTweet['itemContent']['tweet_results']['result']) } | 117 end.map { |rawTweet| normalize_tweet(rawTweet['itemContent']['tweet_results']['result']) } |
118 .filter { |tweet| !tweet.nil? && tweet.dig(:user, :id) == user_id } | |
118 end | 119 end |
119 | 120 |
120 def self.normalize_tweet(json) | 121 def self.normalize_tweet(json) |
121 return nil if json.nil? | 122 return nil if json.nil? |
122 | 123 |