TwitterユーザーID取得
by
furyu-tei
01/29 [2026/01/29 20:10:49]
Twitterユーザーのscreen_nameからユーザーIDを取得する
@@ -7,73 +7,138 @@
* @javascript_url
*/
-( () => {
+(async () => {
'use strict';
-let screen_name = window.getSelection().toString() || prompt( 'Input screen name of user', '' );
+const error_alert = (error_message) => {
+ console.error(error_message);
+ alert(error_message);
+};
-if ( screen_name === null ) return;
-screen_name = screen_name.trim().replace( /^@/, '' );
-if ( ! screen_name ) return;
-
-fetch( 'https://api.twitter.com/1.1/users/show.json?screen_name=' + encodeURIComponent( screen_name ), {
- method: 'GET',
- headers: {
- 'authorization' : 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA',
- 'x-csrf-token' : document.cookie.match( /ct0=(.*?)(?:;|$)/ )[ 1 ],
- 'x-twitter-active-user' : 'yes',
- 'x-twitter-auth-type' : 'OAuth2Session',
- 'x-twitter-client-language' : 'en',
- },
- mode: 'cors',
- credentials : 'include',
-} )
-.then( response => {
- if ( ! response.ok ) {
- throw new Error( 'Network response was not ok' );
- }
- return response.json()
-} )
-.then( user_info => {
- let user_id = user_info.id_str;
-
- if ( ! user_id ) {
- throw new Error( 'Response does not include the ID of the user' );
+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));
+ });
- navigator.clipboard.writeText( user_id )
- .then( () => {
- } )
- .catch( error => {
- console.error( 'Copy result to clipboard failure:', error );
- } )
- .finally( () => {
- let prompt_required = true;
+ 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;
- try {
- let target = window.getSelection().anchorNode.children[ 0 ];
-
- if ( target.tagName == 'INPUT' ) {
- let event = new Event( 'input', { bubbles : true } ),
- tracker = target._valueTracker,
- last_value = target.value,
- 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;
- }
+ if (! user_id) {
+ throw new Error('Response does not include the ID of the user');
}
- catch ( error ) {
+ 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;
}
-
- if ( prompt_required ) prompt( 'User ID of ' + screen_name, user_id );
- } );
-} )
-.catch( error => {
- console.error( screen_name, error );
- alert( '"' + screen_name + '" is not found: ' + error );
-} );
-} )();
+ }
+ catch (error) {
+ console.error(`Failed to rewrite screen name to user ID: ${error}`);
+ }
+ if ( prompt_required ) {
+ prompt(`User ID of ${screen_name}`, user_id);
+ }
+}
+})();
/*
* @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);
}
}
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。