Skip to content

Instantly share code, notes, and snippets.

@h4rkl
Last active January 10, 2024 05:36
Show Gist options
  • Save h4rkl/1ecfd1d5341f964b482df401068935a3 to your computer and use it in GitHub Desktop.
Save h4rkl/1ecfd1d5341f964b482df401068935a3 to your computer and use it in GitHub Desktop.
X rest call

How to use X api request

  • Open a private browser session and go to twitter.com/elonmusk
  • In the network tab of inspector find the fetch/xhr request to UserByScreenName
  • Copy as fetch and then feed the fetch data into fetchString as a single line flattened string (see data in example)
  • Experimental but assume that if the token is revoked you can just repeat the process for a new token
fetch("https://api.twitter.com/graphql/NimuplG1OB7Fd2btCLdBOw/UserByScreenName?variables=%7B%22screen_name%22%3A%22jack%22%2C%22withSafetyModeUserFields%22%3Atrue%7D&features=%7B%22hidden_profile_likes_enabled%22%3Atrue%2C%22hidden_profile_subscriptions_enabled%22%3Atrue%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22subscriptions_verification_info_is_identity_verified_enabled%22%3Atrue%2C%22subscriptions_verification_info_verified_since_enabled%22%3Atrue%2C%22highlights_tweets_tab_ui_enabled%22%3Atrue%2C%22responsive_web_twitter_article_notes_tab_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%7D&fieldToggles=%7B%22withAuxiliaryUserLabels%22%3Afalse%7D", {
  "headers": {
    "accept": "*/*",
    "accept-language": "en-GB,en;q=0.7",
    "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
    "content-type": "application/json",
    "sec-ch-ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Brave\";v=\"120\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"macOS\"",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-site",
    "sec-gpc": "1",
    "x-client-transaction-id": "7ALi2gX6b9+4EAMtNPo97i+LUdtj0pLNq6yVvNOeIPNS9fLr7YJm3yDD3jJ+GY+GTlQsou0kqTC1Vm0opIsP/DY+8mgB7Q",
    "x-guest-token": "1744924191483433105",
    "x-twitter-active-user": "yes",
    "x-twitter-client-language": "en-GB"
  },
  "referrer": "https://twitter.com/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": null,
  "method": "GET",
  "mode": "cors",
  "credentials": "include"
});
const generateXTXIDString = (length: number): string => {
let result = "";
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
};
export const extractXHeaders = (
fetchString: string
): { [key: string]: string } => {
const headersStart = fetchString.indexOf("{ \"headers\": {") + "{ \"headers\": {".length;
const headersEnd = fetchString.indexOf("},", headersStart);
const headersString = fetchString.substring(headersStart, headersEnd).trim();
const headersLines = headersString.split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/);
const headers: { [key: string]: string } = {};
headersLines.forEach((line) => {
const index = line.indexOf(":");
if (index > -1) {
let key = line.substring(0, index).trim().replace(/['",]/g, "");
let value = line
.substring(index + 1)
.trim()
.replace(/['",]/g, "");
if (key === "x-client-transaction-id") {
value = generateXTXIDString(value.length);
}
if (key.length > 0 && value.length > 0) {
headers[key] = value;
}
}
});
return headers;
};
export const createNewXFetch = async (
user: string,
fetchString: string
): Promise<Response> => {
const headers = extractXHeaders(fetchString);
const fetchUrl = `https://api.twitter.com/graphql/NimuplG1OB7Fd2btCLdBOw/UserByScreenName?variables=%7B%22screen_name%22%3A%22${user}%22%2C%22withSafetyModeUserFields%22%3Atrue%7D&features=%7B%22hidden_profile_likes_enabled%22%3Atrue%2C%22hidden_profile_subscriptions_enabled%22%3Atrue%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22subscriptions_verification_info_is_identity_verified_enabled%22%3Atrue%2C%22subscriptions_verification_info_verified_since_enabled%22%3Atrue%2C%22highlights_tweets_tab_ui_enabled%22%3Atrue%2C%22responsive_web_twitter_article_notes_tab_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%7D&fieldToggles=%7B%22withAuxiliaryUserLabels%22%3Afalse%7D`;
const response = await fetch(fetchUrl, {
headers: headers,
referrer: "https://twitter.com/",
referrerPolicy: "strict-origin-when-cross-origin",
body: null,
method: "GET",
mode: "cors",
credentials: "include",
});
const jsonResponse = await response?.json();
let result = null;
if (jsonResponse && jsonResponse.data && jsonResponse.data.user) {
result = jsonResponse.data.user.result;
}
return result;
};
export const fetchString = `fetch("https://api.twitter.com/graphql/NimuplG1OB7Fd2btCLdBOw/UserByScreenName?variables=%7B%22screen_name%22%3A%22jack%22%2C%22withSafetyModeUserFields%22%3Atrue%7D&features=%7B%22hidden_profile_likes_enabled%22%3Atrue%2C%22hidden_profile_subscriptions_enabled%22%3Atrue%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22subscriptions_verification_info_is_identity_verified_enabled%22%3Atrue%2C%22subscriptions_verification_info_verified_since_enabled%22%3Atrue%2C%22highlights_tweets_tab_ui_enabled%22%3Atrue%2C%22responsive_web_twitter_article_notes_tab_enabled%22%3Afalse%2C%22creator_subscriptions_tweet_preview_api_enabled%22%3Atrue%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%7D&fieldToggles=%7B%22withAuxiliaryUserLabels%22%3Afalse%7D", { "headers": { "accept": "*/*", "accept-language": "en-GB,en;q=0.7", "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA", "content-type": "application/json", "sec-ch-ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Brave\";v=\"120\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"macOS\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site", "sec-gpc": "1", "x-client-transaction-id": "7ALi2gX6b9+4EAMtNPo97i+LUdtj0pLNq6yVvNOeIPNS9fLr7YJm3yDD3jJ+GY+GTlQsou0kqTC1Vm0opIsP/DY+8mgB7Q", "x-guest-token": "1744924191483433105", "x-twitter-active-user": "yes", "x-twitter-client-language": "en-GB" }, "referrer": "https://twitter.com/", "referrerPolicy": "strict-origin-when-cross-origin", "body": null, "method": "GET", "mode": "cors", "credentials": "include" });`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment