// ==UserScript==
// @name #pixivのリンクを載せろ
// @name:ja #pixivのリンクを載せろ
// @name:en Show me your Pixiv.
// @version 1145141919810.0.2
// @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 booth.pm
// @connect linktr.ee
// @connect profcard.info
// @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
// @grant GM_xmlhttpRequest
// @license MIT
// @namespace https://greasyfork.org/ja/users/1023652
// ==/UserScript==
function echo(hoge) {
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;
}
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': 'p_ab_id_2=4;',
};
this.package = null;
this.anonymous = true;
this.site_name = 'fanbox';
this.screen_name = screen_name;
}
}
class requestObject {
constructor(URL, screen_name,site_name) {
this.method = 'GET';
this.respType = 'document';
this.url = `${URL}`;
this.body = null;
this.headers = {
"Content-Type": "text/html; charset=utf-8",
'User-agent': window.navigator.userAgent,
'accept': '*/*',
'Referer': URL,
};
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';
let currentUrl = document.location.href;
let Tweet_ID, Obj;
let cookies = getCookieArray();
locationChange();
let already_acquisition_arr = [];
let updating = false;
init(1);
locationChange();
window.addEventListener("scroll", update);
const add_data_to_array = async(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};
echo("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(/\/$/,''));
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))\/?/)) {
t_obj = new requestObject(target,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};
echo("pixivのリンクをfanboxから発見!PixivのURLも載せてくれよなー")
break;
}
}
} else {
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\/.*))$/)) {
already_acquisition_arr[obj.screen_name] = {'pixiv_url': response_data.response.toString().match(/^https?:\/\/(((www|touch)\.)?pixiv\.(net\/([a-z]{2}\/)?((member(_illust)?\.php\?id\=|(users|u)\/)[0-9].*)|me\/.*))$/),'is_pixiv_url': true};
echo("PixivのURLも載せてくれよなー")
}
}
}
const find_pixiv_link = async (tweet, 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) {
for (let i = 0; i < times; i++) {
setTimeout(() => findTarget('.css-1dbjc4n.r-1ssbvtb.r-1s2bzr4'), 500 * i);
}
}
const findTarget = async(target) => {
document.querySelectorAll(`${target}`).forEach(t => {
var auther_screen_name = t.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(t, auther_screen_name)
if (already_acquisition_arr[auther_screen_name].pixiv_url && !t.querySelector('.display_pixiv_link')) {
var write_content = document.createElement("span");
write_content.innerHTML =`<a class="display_pixiv_link" href="${already_acquisition_arr[auther_screen_name].pixiv_url}" target="_blank" rel="noopener">Pixiv🔗</a>`;
t.appendChild(write_content);
}
});
}
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);
}
});
});
const target = document.body;
const config = {
childList: true,
subtree: true
};
observer.observe(target, config);
}
})();