|
@@ -21,16 +21,16 @@
|
|
|
|
|
|
|
|
(require 'request)
|
|
(require 'request)
|
|
|
|
|
|
|
|
-(setq exitter-url-endpoint "https://api.twitter.com/1.1"
|
|
|
|
|
- exitter-url-activate
|
|
|
|
|
- (format "%s/guest/activate.json" exitter-url-endpoint)
|
|
|
|
|
- exitter-url-task
|
|
|
|
|
- (format "%s/onboarding/task.json" exitter-url-endpoint)
|
|
|
|
|
- exitter-url-token
|
|
|
|
|
- (format "https://api.twitter.com/oauth2/token")
|
|
|
|
|
- exitter-url-tweet-detail
|
|
|
|
|
- "https://api.twitter.com/graphql/3XDB26fBve-MmjHaWTUZxA/TweetDetail")
|
|
|
|
|
-(setq exitter-tor-param "-x socks5://127.0.0.1:9050/")
|
|
|
|
|
|
|
+(defvar exitter-url-endpoint "https://api.twitter.com/1.1")
|
|
|
|
|
+(defvar exitter-url-activate
|
|
|
|
|
+ (format "%s/guest/activate.json" exitter-url-endpoint))
|
|
|
|
|
+(defvar exitter-url-task
|
|
|
|
|
+ (format "%s/onboarding/task.json" exitter-url-endpoint))
|
|
|
|
|
+(defvar exitter-url-token
|
|
|
|
|
+ (format "https://api.twitter.com/oauth2/token"))
|
|
|
|
|
+(defvar exitter-url-tweet-detail
|
|
|
|
|
+ "https://api.twitter.com/graphql/3XDB26fBve-MmjHaWTUZxA/TweetDetail")
|
|
|
|
|
+(defvar exitter-tor-param "-x socks5://127.0.0.1:9050/")
|
|
|
(defvar exitter-init-headers
|
|
(defvar exitter-init-headers
|
|
|
`(
|
|
`(
|
|
|
("Content-Type" . "application/json")
|
|
("Content-Type" . "application/json")
|
|
@@ -49,32 +49,32 @@
|
|
|
("android_graphql_skip_api_media_color_palette" . :json-false)
|
|
("android_graphql_skip_api_media_color_palette" . :json-false)
|
|
|
("blue_business_profile_image_shape_enabled" . :json-false)
|
|
("blue_business_profile_image_shape_enabled" . :json-false)
|
|
|
("creator_subscriptions_subscription_count_enabled" . :json-false)
|
|
("creator_subscriptions_subscription_count_enabled" . :json-false)
|
|
|
- ("creator_subscriptions_tweet_preview_api_enabled" . :json-true)
|
|
|
|
|
|
|
+ ("creator_subscriptions_tweet_preview_api_enabled" . t)
|
|
|
("freedom_of_speech_not_reach_fetch_enabled" . :json-false)
|
|
("freedom_of_speech_not_reach_fetch_enabled" . :json-false)
|
|
|
("graphql_is_translatable_rweb_tweet_is_translatable_enabled" . :json-false)
|
|
("graphql_is_translatable_rweb_tweet_is_translatable_enabled" . :json-false)
|
|
|
("hidden_profile_likes_enabled" . :json-false)
|
|
("hidden_profile_likes_enabled" . :json-false)
|
|
|
("highlights_tweets_tab_ui_enabled" . :json-false)
|
|
("highlights_tweets_tab_ui_enabled" . :json-false)
|
|
|
("interactive_text_enabled" . :json-false)
|
|
("interactive_text_enabled" . :json-false)
|
|
|
- ("longform_notetweets_consumption_enabled" . :json-true)
|
|
|
|
|
|
|
+ ("longform_notetweets_consumption_enabled" . t)
|
|
|
("longform_notetweets_inline_media_enabled" . :json-false)
|
|
("longform_notetweets_inline_media_enabled" . :json-false)
|
|
|
- ("longform_notetweets_richtext_consumption_enabled" . :json-true)
|
|
|
|
|
|
|
+ ("longform_notetweets_richtext_consumption_enabled" . t)
|
|
|
("longform_notetweets_rich_text_read_enabled" . :json-false)
|
|
("longform_notetweets_rich_text_read_enabled" . :json-false)
|
|
|
("responsive_web_edit_tweet_api_enabled" . :json-false)
|
|
("responsive_web_edit_tweet_api_enabled" . :json-false)
|
|
|
("responsive_web_enhance_cards_enabled" . :json-false)
|
|
("responsive_web_enhance_cards_enabled" . :json-false)
|
|
|
- ("responsive_web_graphql_exclude_directive_enabled" . :json-true)
|
|
|
|
|
|
|
+ ("responsive_web_graphql_exclude_directive_enabled" . t)
|
|
|
("responsive_web_graphql_skip_user_profile_image_extensions_enabled" . :json-false)
|
|
("responsive_web_graphql_skip_user_profile_image_extensions_enabled" . :json-false)
|
|
|
("responsive_web_graphql_timeline_navigation_enabled" . :json-false)
|
|
("responsive_web_graphql_timeline_navigation_enabled" . :json-false)
|
|
|
("responsive_web_media_download_video_enabled" . :json-false)
|
|
("responsive_web_media_download_video_enabled" . :json-false)
|
|
|
("responsive_web_text_conversations_enabled" . :json-false)
|
|
("responsive_web_text_conversations_enabled" . :json-false)
|
|
|
("responsive_web_twitter_article_tweet_consumption_enabled" . :json-false)
|
|
("responsive_web_twitter_article_tweet_consumption_enabled" . :json-false)
|
|
|
- ("responsive_web_twitter_blue_verified_badge_is_enabled" . :json-true)
|
|
|
|
|
- ("rweb_lists_timeline_redesign_enabled" . :json-true)
|
|
|
|
|
- ("spaces_2022_h2_clipping" . :json-true)
|
|
|
|
|
- ("spaces_2022_h2_spaces_communities" . :json-true)
|
|
|
|
|
|
|
+ ("responsive_web_twitter_blue_verified_badge_is_enabled" . t)
|
|
|
|
|
+ ("rweb_lists_timeline_redesign_enabled" . t)
|
|
|
|
|
+ ("spaces_2022_h2_clipping" . t)
|
|
|
|
|
+ ("spaces_2022_h2_spaces_communities" . t)
|
|
|
("standardized_nudges_misinfo" . :json-false)
|
|
("standardized_nudges_misinfo" . :json-false)
|
|
|
- ("subscriptions_verification_info_enabled" . :json-true)
|
|
|
|
|
- ("subscriptions_verification_info_reason_enabled" . :json-true)
|
|
|
|
|
- ("subscriptions_verification_info_verified_since_enabled" . :json-true)
|
|
|
|
|
|
|
+ ("subscriptions_verification_info_enabled" . t)
|
|
|
|
|
+ ("subscriptions_verification_info_reason_enabled" . t)
|
|
|
|
|
+ ("subscriptions_verification_info_verified_since_enabled" . t)
|
|
|
("super_follow_badge_privacy_enabled" . :json-false)
|
|
("super_follow_badge_privacy_enabled" . :json-false)
|
|
|
("super_follow_exclusive_tweet_notifications_enabled" . :json-false)
|
|
("super_follow_exclusive_tweet_notifications_enabled" . :json-false)
|
|
|
("super_follow_tweet_api_enabled" . :json-false)
|
|
("super_follow_tweet_api_enabled" . :json-false)
|
|
@@ -299,20 +299,22 @@
|
|
|
(message "Got error: %S" error-thrown)))
|
|
(message "Got error: %S" error-thrown)))
|
|
|
))
|
|
))
|
|
|
|
|
|
|
|
-(defun exitter-get-sign-oauth (uri method)
|
|
|
|
|
- (let* ((params `((oauth_consumer_key . ,exitter-oauth-consumer-key)
|
|
|
|
|
- (oauth_nonce . ,(exitter-nonce))
|
|
|
|
|
- (oauth_signature_method . "HMAC-SHA1")
|
|
|
|
|
- (oauth_timestamp . ,(format-time-string "%s" (current-time)))
|
|
|
|
|
- (oauth_token . ,exitter-oauth-token)
|
|
|
|
|
- (oauth_version . "1.0")))
|
|
|
|
|
|
|
+(defun exitter-get-sign-oauth (link url-params method)
|
|
|
|
|
+ (let* ((oauth-params `(("oauth_consumer_key" . ,exitter-oauth-consumer-key)
|
|
|
|
|
+ ("oauth_nonce" . ,(exitter-nonce))
|
|
|
|
|
+ ("oauth_signature_method" . "HMAC-SHA1")
|
|
|
|
|
+ ("oauth_timestamp" . ,(format-time-string "%s" (current-time)))
|
|
|
|
|
+ ("oauth_token" . ,exitter-oauth-token)
|
|
|
|
|
+ ("oauth_version" . "1.0")))
|
|
|
|
|
+ (all-params (sort (seq-concatenate 'list url-params oauth-params)
|
|
|
|
|
+ (lambda (a b) (string< (car a) (car b)))))
|
|
|
(method-up (upcase method))
|
|
(method-up (upcase method))
|
|
|
- (link (url-hexify-string uri))
|
|
|
|
|
|
|
+ (hexed-link (url-hexify-string link))
|
|
|
(param-to-sign-unencoded
|
|
(param-to-sign-unencoded
|
|
|
(mapconcat
|
|
(mapconcat
|
|
|
(lambda (pair)
|
|
(lambda (pair)
|
|
|
(format "%s=%s" (car pair) (url-hexify-string (cdr pair))))
|
|
(format "%s=%s" (car pair) (url-hexify-string (cdr pair))))
|
|
|
- params
|
|
|
|
|
|
|
+ all-params
|
|
|
"&"))
|
|
"&"))
|
|
|
(param-to-sign
|
|
(param-to-sign
|
|
|
(replace-regexp-in-string
|
|
(replace-regexp-in-string
|
|
@@ -324,7 +326,7 @@
|
|
|
(replace-regexp-in-string
|
|
(replace-regexp-in-string
|
|
|
"\\+" "%20"
|
|
"\\+" "%20"
|
|
|
param-to-sign-unencoded)))))
|
|
param-to-sign-unencoded)))))
|
|
|
- (to-sign (format "%s&%s&%s" method-up link param-to-sign))
|
|
|
|
|
|
|
+ (to-sign (format "%s&%s&%s" method-up hexed-link param-to-sign))
|
|
|
(signature (url-hexify-string
|
|
(signature (url-hexify-string
|
|
|
(base64-encode-string
|
|
(base64-encode-string
|
|
|
(hmac-sha1 (encode-coding-string
|
|
(hmac-sha1 (encode-coding-string
|
|
@@ -342,13 +344,13 @@
|
|
|
(mapconcat
|
|
(mapconcat
|
|
|
(lambda (pair)
|
|
(lambda (pair)
|
|
|
(format "%s=\"%s\"" (car pair) (cdr pair)))
|
|
(format "%s=\"%s\"" (car pair) (cdr pair)))
|
|
|
- params
|
|
|
|
|
|
|
+ oauth-params
|
|
|
", "))))
|
|
", "))))
|
|
|
|
|
|
|
|
-(defun exitter-do-fetch (uri headers)
|
|
|
|
|
|
|
+(defun exitter-do-fetch (link params &optional headers)
|
|
|
(when exitter-debug (message "entering exitter-do-fetch"))
|
|
(when exitter-debug (message "entering exitter-do-fetch"))
|
|
|
- (let ((authorization (exitter-get-sign-oauth uri "GET")))
|
|
|
|
|
- (request uri
|
|
|
|
|
|
|
+ (let ((authorization (exitter-get-sign-oauth link params "GET")))
|
|
|
|
|
+ (request link
|
|
|
:headers `(,@headers
|
|
:headers `(,@headers
|
|
|
("Connection" . "Keep-Alive")
|
|
("Connection" . "Keep-Alive")
|
|
|
("Authorization" . ,authorization)
|
|
("Authorization" . ,authorization)
|
|
@@ -370,6 +372,7 @@
|
|
|
"Dalvik/2.1.0 (Linux; U; Android 9; \
|
|
"Dalvik/2.1.0 (Linux; U; Android 9; \
|
|
|
ONEPLUS A3010 Build/PKQ1.181203.001)")
|
|
ONEPLUS A3010 Build/PKQ1.181203.001)")
|
|
|
)
|
|
)
|
|
|
|
|
+ :params params
|
|
|
:type "GET"
|
|
:type "GET"
|
|
|
:parser 'json-read
|
|
:parser 'json-read
|
|
|
:success (cl-function
|
|
:success (cl-function
|
|
@@ -387,13 +390,14 @@ ONEPLUS A3010 Build/PKQ1.181203.001)")
|
|
|
;; ("referrer" . "tweet")
|
|
;; ("referrer" . "tweet")
|
|
|
;; ("with_rux_injections" . :json-false)
|
|
;; ("with_rux_injections" . :json-false)
|
|
|
("includePromotedContent" . :json-false)
|
|
("includePromotedContent" . :json-false)
|
|
|
- ;; ("withCommunity" . :json-true)
|
|
|
|
|
|
|
+ ;; ("withCommunity" . t)
|
|
|
("withQuickPromoteEligibilityTweetFields" . :json-false)
|
|
("withQuickPromoteEligibilityTweetFields" . :json-false)
|
|
|
("includeHasBirdwatchNotes" . :json-false)
|
|
("includeHasBirdwatchNotes" . :json-false)
|
|
|
("withBirdwatchNotes" . :json-false)
|
|
("withBirdwatchNotes" . :json-false)
|
|
|
("withVoice" . :json-false)
|
|
("withVoice" . :json-false)
|
|
|
- ("withV2Timeline" . :json-true)
|
|
|
|
|
|
|
+ ("withV2Timeline" . t)
|
|
|
))))
|
|
))))
|
|
|
|
|
+ (message "VARIABLES: ")
|
|
|
(exitter-do-fetch
|
|
(exitter-do-fetch
|
|
|
exitter-url-tweet-detail
|
|
exitter-url-tweet-detail
|
|
|
`(("variables" . ,variables)
|
|
`(("variables" . ,variables)
|