/*
* @title TwitterユーザーID取得
* @description Twitterユーザーのscreen_nameからユーザーIDを取得する
* @include https://twitter.com/*
* @license MIT License
* @require
* @javascript_url
*/
(async () => {
'use strict';
const error_alert = (error_message) => {
console.error(error_message);
alert(error_message);
};
let screen_name = window.getSelection().toString() || prompt('Input screen-name of user', '');
if (screen_name === null) return;
screen_name = screen_name.trim().replace(/^@/, '');
if (! screen_name) {
error_alert('screen-name is empty');
return;
}
const api_info = await (async () => {
try {
const main_js_url = document.querySelector('link[as="script"][href*="main"]')?.href ?? document.querySelector('script[src*="main"][src$=".js"]')?.src;
if (! main_js_url) {
throw new Error(`URL of main*.js is not found`);
}
const response = await fetch(main_js_url);
if (! response.ok) {
throw new Error(`HTTP response status code=${response.status}`);
}
const main_js_text = await response.text();
const api_info_json = main_js_text.match(/\{e\.exports=(\{[^}]*?operationName:"UserByScreenName"[\s\S]*?\})\},\d+:e=>\{e.exports/)[1].replace(/(\w+)(?=:)/g, '"$1"');
const api_info = JSON.parse(api_info_json);
return api_info;
}
catch (error) {
error_alert(`Fetch API-Information failure: ${error}`);
return null;
}
})();
if (! api_info) return;
const user_id = await (async () => {
const base_url = `https://x.com/i/api/graphql/${api_info.queryId}/UserByScreenName`;
const api2_auth_bearer = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA';
const csrf_token = document.cookie.match(/ct0=(.*?)(?:;|$)/)[1];
const search_params = {
variables: {
"screen_name": screen_name,
"withGrokTranslatedBio": false
},
features: {
"hidden_profile_subscriptions_enabled": true,
"profile_label_improvements_pcf_label_in_post_enabled": true,
"responsive_web_profile_redirect_enabled": false,
"rweb_tipjar_consumption_enabled": false,
"verified_phone_label_enabled": false,
"subscriptions_verification_info_is_identity_verified_enabled": true,
"subscriptions_verification_info_verified_since_enabled": true,
"highlights_tweets_tab_ui_enabled": true,
"responsive_web_twitter_article_notes_tab_enabled": true,
"subscriptions_feature_can_gift_premium": true,
"creator_subscriptions_tweet_preview_api_enabled": true,
"responsive_web_graphql_skip_user_profile_image_extensions_enabled": false,
"responsive_web_graphql_timeline_navigation_enabled": true
},
fieldToggles: {
"withPayments": false,
"withAuxiliaryUserLabels": true
},
};
const url_object = new URL(base_url);
Object.entries(search_params).forEach(([key, value]) => {
url_object.searchParams.append(key, JSON.stringify(value));
});
try {
const response = await fetch(url_object.href, {
method: 'GET',
headers: {
'authorization': `Bearer ${api2_auth_bearer}`,
'x-csrf-token': csrf_token,
'x-twitter-active-user': 'yes',
'x-twitter-auth-type': 'OAuth2Session',
'x-twitter-client-language': 'en',
},
mode: 'cors',
credentials: 'include',
});
if (! response.ok) {
throw new Error(`HTTP response status code=${response.status}`);
}
const user_info = await response.json();
const user_id = user_info?.data?.user?.result?.rest_id;
if (! user_id) {
throw new Error('Response does not include the ID of the user');
}
return user_id;
}
catch (error) {
error_alert(`"${screen_name}" is not found: ${error}`);
return null;
}
})();
if (! user_id) return;
try {
await navigator.clipboard.writeText(user_id);
}
catch (error) {
console.error(`Copy result to clipboard failure: ${error}`);
}
finally {
let prompt_required = true;
try {
const target = window.getSelection().anchorNode.children[0];
if (target.tagName == 'INPUT') {
const event = new Event('input', {bubbles: true});
const tracker = target._valueTracker;
const last_value = target.value;
const new_value = last_value.substring(0, target.selectionStart) + user_id + last_value.substring(target.selectionEnd);
target.value = new_value;
event.simulated = true;
if (tracker) tracker.setValue(last_value);
target.dispatchEvent(event);
prompt_required = false;
}
}
catch (error) {
console.error(`Failed to rewrite screen name to user ID: ${error}`);
}
if ( prompt_required ) {
prompt(`User ID of ${screen_name}`, user_id);
}
}
})();