Greasy Fork

Greasy Fork is available in English.

PixivのリンクをTweetに添えて

Tweetの画像の下に(プロフィール欄にあれば)その人のPixivのリンクを表示します。

当前为 2023-04-01 提交的版本,查看 最新版本

// ==UserScript==
// @name			PixivのリンクをTweetに添えて
// @name:ja			PixivのリンクをTweetに添えて
// @name:en			Show me your Pixiv.
// @version			1145141919810.0.16
// @description			Tweetの画像の下に(プロフィール欄にあれば)その人のPixivのリンクを表示します。
// @description:ja			Tweetの画像の下に(あれば)その人のPixivのリンクを表示します。
// @description:en			Display a Pixiv link below the Tweet image.
// @author			ゆにてぃー
// @match			https://twitter.com/*
// @match			https://mobile.twitter.com/*
// @connect			api.twitter.com
// @connect			api.fanbox.cc
// @connect			skeb.jp
// @connect			fantia.jp
// @connect			booth.pm
// @connect			linktr.ee
// @connect			profcard.info
// @connect			lit.link
// @connect			potofu.me
// @icon			https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant			GM_xmlhttpRequest
// @license			MIT
// @namespace			http://greasyfork.icu/ja/users/1023652
// ==/UserScript==
var is_debug = false;

function echo(hoge = 'debug') {
	if(is_debug == true){
		console.log(hoge)
	}
};

function getCookieArray() {
	var arr = [];
	if(document.cookie != '') {
		var tmp = document.cookie.split('; ');
		for(var i = 0; i < tmp.length; i++) {
			var data = tmp[i].split('=');
			arr[data[0]] = decodeURIComponent(data[1]);
		}
	}
	return arr;
}
function SetCookie(name, value, days) {
	let Days = 180;
	if (days) {
		Days = days;
	}
	let exp = new Date();
	exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
	let str = JSON.stringify(value);
	document.cookie = name + "=" + str + ";expires=" + exp.toGMTString() + ';path=\/';
}
let Twitter_Bearer_Token_graphql = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA';
class requestObject_twitter {
	constructor(ID, cookies) {
		this.method = 'GET';
		this.respType = 'json';
		this.url = `https://api.twitter.com/graphql/rePnxwe9LZ51nQ7Sn_xN_A/UserByScreenName?variables=%7B%22screen_name%22%3A%22${ID}%22%2C%22withSafetyModeUserFields%22%3Afalse%2C%22withSuperFollowsUserFields%22%3Afalse%7D&features=%7B%22responsive_web_twitter_blue_verified_badge_is_enabled%22%3Afalse%2C%22responsive_web_graphql_exclude_directive_enabled%22%3Afalse%2C%22verified_phone_label_enabled%22%3Afalse%2C%22responsive_web_graphql_skip_user_profile_image_extensions_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Afalse%7D`;
		this.body = null;
		this.headers = {
			"Content-Type": "application/json",
			'User-agent': window.navigator.userAgent,
			'accept': '*/*',
			'Referer': "https://twitter.com/",
			'Host': 'api.twitter.com',
			'authorization': `Bearer ${Twitter_Bearer_Token_graphql}`,
			'x-csrf-token': cookies.ct0,
			'Accept-Encoding': 'br'
//			'x-twitter-client-language': 'ja',
//			'cookie': `auth_token=${cookies.auth_token}; ct0=${cookies.ct0}`
		};
		this.package = null;
		this.anonymous = false;
		this.screen_name = ID;
	}
}
class requestObject_fanbox {
	constructor(URL, screen_name, fanbox_URL) {
		this.method = 'GET';
		this.respType = 'json';
		this.url = `${URL}`;
		this.body = null;
		this.headers = {
			'User-agent': window.navigator.userAgent,
			'origin': fanbox_URL,
			'Host': 'api.fanbox.cc',
			'cookie': '',
		};
		this.package = null;
		this.anonymous = false;
		this.site_name = 'fanbox';
		this.screen_name = screen_name;
	}
}
class requestObject {
	constructor(URL, screen_name, site_name) {
		this.method = 'GET';
		this.respType = '';
		this.url = `${URL}`;
		this.body = null;
		this.headers = {
			"Content-Type": "text/html; charset=utf-8",
			'User-agent': window.navigator.userAgent,
			'accept': '*/*',
			'Referer': URL,
			"Sec-Fetch-Mode": "navigate",
		};
		this.package = null;
		this.anonymous = false;
		this.site_name = site_name;
		this.screen_name = screen_name;
	}
}

function request(object, func, timeout = 60000) {
	GM_xmlhttpRequest({
		method: object.method,
		url: object.url,
		headers: object.headers,
		responseType: object.respType,
		data: object.body,
		anonymous: object.anonymous,
		timeout: timeout,
		onload: function(responseDetails) {
//			console.log(responseDetails);
			func(responseDetails, object);
		},
		ontimeout: function(responseDetails) {
			console.log("time out.");
			console.log(responseDetails);
		},
		ononerror: function(responseDetails) {
			console.log("error.");
			console.log(responseDetails);
		}
	});
}
(function() {
	'use strict';
	var desktop_selector = {'media_field': '.css-1dbjc4n.r-1ssbvtb.r-1s2bzr4','profile_field':'.css-901oao.r-vlxjld.r-1tl8opc.r-a023e6.r-16dba41.r-56xrmm.r-bcqeeo.r-qvutc0'};
	var mobile_selector = {'media_field': '.css-1dbjc4n.r-9aw3ui','profile_field':'.css-901oao.r-vlxjld.r-1tl8opc.r-1b43r93.r-16dba41.r-1p6fy00.r-bcqeeo.r-qvutc0'};
	var env_selector;
    if(document.location.href.match(/https?:\/\/mobile\.twitter\.com.*/)){
		env_selector = mobile_selector;
    }else{
		env_selector = desktop_selector;
    }
	let currentUrl = document.location.href;
	let Tweet_ID, Obj;
	let cookies = getCookieArray();
	locationChange();
	let already_acquisition_arr = [];
	let updating = false;
	init(1);
	window.addEventListener("scroll", update);
	function write_content(target_node,screen_name,additional_linefeed = ''){
		if(already_acquisition_arr[screen_name].pixiv_url && !target_node.querySelector('.display_pixiv_link')) {
			var new_content = document.createElement("span");
			new_content.innerHTML = `${additional_linefeed}<a class="display_pixiv_link" href="${already_acquisition_arr[screen_name].pixiv_url}" target="_blank" rel="noopener">Pixiv🔗</a>`;
			target_node.appendChild(new_content);
		}
	}
	async function show_pixiv_link_in_profile(){
		var tmp_pixiv_link_node = document.querySelectorAll(`${env_selector.profile_field}`)[0].querySelector('.display_pixiv_link');
		if(tmp_pixiv_link_node !== null){
			tmp_pixiv_link_node.parentNode.remove();
		}
		var profile_field = document.querySelector(`${env_selector.profile_field}`);
		var screen_name = currentUrl.split('/')[3];
		find_pixiv_link(screen_name);
		setTimeout(() => write_content(profile_field,screen_name,'<br>'),500);
	}
	function add_data_to_array(response_data, obj){
		var tmp_urls = [];
		var t_obj, tmp;
		try {
			for(let i = 0; i < response_data.response.data.user.result.legacy.entities.description.urls.length; i++) {
				tmp = response_data.response.data.user.result.legacy.entities.description.urls[i].expanded_url;
				if(tmp.match(/^https?:\/\/(((www|touch)\.)?pixiv\.(net\/([a-z]{2}\/)?((member(_illust)?\.php\?id\=|(users|u)\/)[0-9].*)|me\/.*))$/)) {
					already_acquisition_arr[obj.screen_name] = {'pixiv_url': tmp,'is_pixiv_url': true};
					return;
				}
				tmp_urls.push(tmp);
			}
		} catch {}
		try {
			for(let i = 0; i < response_data.response.data.user.result.legacy.entities.url.urls.length; i++) {
				tmp = response_data.response.data.user.result.legacy.entities.url.urls[i].expanded_url;
				if(tmp.match(/^https?:\/\/(((www|touch)\.)?pixiv\.(net\/([a-z]{2}\/)?((member(_illust)?\.php\?id\=|(users|u)\/)[0-9].*)|me\/.*))$/)) {
					already_acquisition_arr[obj.screen_name] = {'pixiv_url': tmp,'is_pixiv_url': true};
					return;
				}
				tmp_urls.push(tmp);
			}
		} catch {}
		for(const target of tmp_urls) {
			if(target.match(/https?:\/\/www\.pixiv\.net\/fanbox\/creator\/[0-9].*/)) {
				already_acquisition_arr[obj.screen_name] = {'pixiv_url': target.replace('fanbox/creator', 'users'),'is_pixiv_url': true};
				console.log("pixivのリンクをfanboxから発見!PixivのURLも載せてくれよなー");
			} else if(target.match(/https?:\/\/.*\.fanbox\.cc\/?/)) {
				t_obj = new requestObject_fanbox(`https://api.fanbox.cc/creator.get?creatorId=${target.replace(/(https?:\/\/|\.fanbox.*)/g,'')}`, obj.screen_name, target.replace(/^http:/, 'https:').replace(/\/$/, ''));
				request(t_obj, add_data_to_array2);
			} else if(target.match(/https?:\/\/((skeb\.jp\/\@.*)|(fantia\.jp\/fanclubs\/[0-9].*)|(.*\.booth\.pm)|(.*linktr\.ee)|(.*profcard\.info)|(.*lit\.link)|(potofu\.me))\/?/)) {
				t_obj = new requestObject(target.replace(/^http:/, 'https:'), obj.screen_name);
				request(t_obj, add_data_to_array2);
			}
			if(already_acquisition_arr[obj.screen_name].is_pixiv_url == "ture") {
				break;
			}
		}
	}

	function add_data_to_array2(response_data, obj) {
		if(obj.site_name == "fanbox") {
			for(const target of response_data.response.body.profileLinks) {
				if(target.match(/^https?:\/\/(((www|touch)\.)?pixiv\.(net\/([a-z]{2}\/)?((member(_illust)?\.php\?id\=|(users|u)\/)[0-9].*)|me\/.*))$/)) {
					already_acquisition_arr[obj.screen_name] = {'pixiv_url': target,'is_pixiv_url': true};
					console.log("pixivのリンクをfanboxから発見!PixivのURLも載せてくれよなー");
					break;
				}
			}
			already_acquisition_arr[obj.screen_name] = {'pixiv_url': `https://www.pixiv.net/users/${response_data.response.body.user.userId}`,'is_pixiv_url': true};
		} else {
//			echo(response_data.response.toString())
			if(response_data.response.toString().replace(/(\<|\>|\")/g, '\n').match(/https?:\/\/(((www|touch)\.)?pixiv\.(net\/([a-z]{2}\/)?((member(_illust)?\.php\?id\=|(users|u)\/)[0-9].*)|me\/.*))/)[0]) {
				already_acquisition_arr[obj.screen_name] = {'pixiv_url': response_data.response.toString().replace(/\"/g, '\n').match(/https?:\/\/(((www|touch)\.)?pixiv\.(net\/([a-z]{2}\/)?((member(_illust)?\.php\?id\=|(users|u)\/)[0-9].*)|me\/.*))/)[0],'is_pixiv_url': true};
				console.log(`pixivのリンクを${obj.url.split("/")[2]}から発見!PixivのURLも載せてくれよなー`);
			}
		}
	}
	 async function find_pixiv_link(auther_screen_name){
		if(!already_acquisition_arr[auther_screen_name]) {
			var obj = new requestObject_twitter(auther_screen_name, cookies);
			already_acquisition_arr[auther_screen_name] = {is_pixiv_url: false};
			request(obj, add_data_to_array);
			echo(auther_screen_name);
			echo(already_acquisition_arr);
		}
	}

	function init(times) {
		wait_load_Element_and_do_function(`${env_selector.profile_field}`,show_pixiv_link_in_profile);
		for(let i = 0; i < times; i++) {
				setTimeout(() => findTarget(`${env_selector.media_field}`), 500 * i);
		}
	}
	function findTarget(target){
		document.querySelectorAll(`${target}`).forEach(t => {
			var auther_screen_name = t.parentElement.parentElement.parentElement.parentElement.querySelector('.css-4rbku5.css-18t94o4.css-1dbjc4n.r-1niwhzg.r-1loqt21.r-1pi2tsx.r-1ny4l3l.r-o7ynqc.r-6416eg.r-13qz1uu').getAttribute('href').replace(/^\//, '');
			find_pixiv_link(auther_screen_name);
            write_content(t,auther_screen_name);
		});
	}

	function update() {
		if(updating) return;
		updating = true;
		init(1);
		setTimeout(() => {updating = false;}, 1000);
	}

	function locationChange() {
		const observer = new MutationObserver(mutations => {
			mutations.forEach(() => {
				if(currentUrl !== document.location.href) {
					currentUrl = document.location.href;
					init(1);
//                    setTimeout(() => show_pixiv_link_in_profile(),1000);
				}
			});
		});
		const target = document.body;
		const config = {childList: true,subtree: true};
		observer.observe(target, config);
	}
    function wait_load_Element_and_do_function(Element_Name,func,func_argument){
		const MAX_RETRY_COUNT = 15;
		var retry_counter = 0;
		var set_interval_id = setInterval(find_target_element, 500);
		function find_target_element() {
			retry_counter++;
			if(retry_counter > MAX_RETRY_COUNT) {
			clearInterval(set_interval_id);
                return;
			}
			var target_elements = document.querySelectorAll(`${Element_Name}`);
			if(target_elements.length > 0) {
				if(typeof(set_interval_id) != 'undefined') {
					clearInterval(set_interval_id);
					func(func_argument,target_elements);
				}else {
					return target_elements;
				}
			}
		}
		find_target_element();
	}
})();