// ==UserScript==
// @name Onlyfans/Fansly/Fantrie "leak" finder
// @namespace http://tampermonkey.net/
// @version 0.6
// @description Checks some sites for OF/Fansly/Fantrie "leaks"
// @author You
// @match https://onlyfans.com/*
// @match *coomer.su/*
// @match *fapello.com/*
// @match https://fansly.com/*
// @match https://fantrie.com/*
// @grant GM.xmlHttpRequest
// @license Unlicense
// ==/UserScript==
(function() {
'use strict';
const MAX_RETRY_COUNT = 5;
const RETRY_DELAY_MS = 1000;
const username = getUsernameFromUrl();
function getUsernameFromUrl() {
const hostname = window.location.hostname;
const pathname = window.location.pathname;
if (hostname === 'onlyfans.com' || hostname === 'fantrie.com') {
return pathname.split('/')[1];
}
if (hostname === 'fansly.com') {
const matches = pathname.match(/^\/([^/]+)/);
return matches ? matches[1] : '';
}
return '';
}
function fetchWithRetry(url, onSuccess, onError, retryCount = 0) {
GM.xmlHttpRequest({
method: 'GET',
url,
onload(response) {
if (response.status === 200) {
onSuccess(response);
} else if (retryCount < MAX_RETRY_COUNT) {
setTimeout(() => fetchWithRetry(url, onSuccess, onError, retryCount + 1), RETRY_DELAY_MS);
} else {
console.error('Max retry attempts reached');
onError && onError(response);
}
},
onerror(error) {
console.error('Error fetching data:', error);
if (retryCount < MAX_RETRY_COUNT) {
setTimeout(() => fetchWithRetry(url, onSuccess, onError, retryCount + 1), RETRY_DELAY_MS);
} else {
console.error('Max retry attempts reached');
onError && onError(error);
}
}
});
}
function fetchUserProfileFansly(username) {
const apiUrl = `https://apiv3.fansly.com/api/v1/account?usernames=${username}`;
fetchWithRetry(apiUrl, (response) => {
const data = JSON.parse(response.responseText);
if (data.success && data.response.length > 0) {
fetchUserProfileCoomer(data.response[0].id, "fansly");
} else {
console.log(`User ${username} not found`);
}
});
}
function fetchUserProfileCoomer(username, service) {
const apiUrl = `https://coomer.su/api/v1/${service}/user/${username}/profile`;
fetchWithRetry(apiUrl, (response) => {
const profileUrl = `https://coomer.su/${service}/user/${username}`;
addLinkToMenu(profileUrl, 'Coomer.su');
}, null, 0, 404);
}
function fetchUserProfileFapello(username) {
const apiUrl = `https://fapello.com/${username}/`;
fetchWithRetry(apiUrl, (response) => {
if (response.finalUrl === apiUrl) {
addLinkToMenu(apiUrl, 'Fapello');
} else {
console.log(`Request was redirected`);
}
});
}
function fetchUserProfileLeakNudes(username) {
const apiUrl = `https://leaknudes.com/model/${username}`;
fetchWithRetry(apiUrl, (response) => {
if (response.finalUrl === apiUrl) {
addLinkToMenu(apiUrl, 'LeakNudes');
} else {
console.log(`Request was redirected`);
}
});
}
function addLinkToMenu(link, displayText) {
const hostname = window.location.hostname;
let menuElement;
if (hostname === 'fansly.com') {
menuElement = document.querySelector('.follow-profile');
if (menuElement) {
const clonedElement = menuElement.cloneNode(true);
clonedElement.querySelector("xd-localization-string").innerText = displayText;
const aElement = document.createElement('a');
aElement.setAttribute('href', link);
aElement.appendChild(clonedElement);
menuElement.after(aElement);
} else {
console.error('Follow button not found');
}
} else if (hostname === 'fantrie.com') {
menuElement = document.querySelectorAll('.left-menus')[1];
if (menuElement) {
const aElement = document.createElement('a');
aElement.setAttribute('href', link);
aElement.textContent = displayText;
menuElement.appendChild(aElement);
} else {
console.error('Left menus element not found');
}
} else {
menuElement = document.querySelector('.l-header__menu.m-native-custom-scrollbar.m-scrollbar-y.m-invisible-scrollbar');
if (menuElement) {
const aElement = document.createElement('a');
aElement.setAttribute('href', link);
aElement.textContent = displayText;
aElement.style.marginRight = "10px";
if (menuElement.querySelectorAll('a').length > 0) {
menuElement.appendChild(document.createElement('br'));
}
menuElement.appendChild(aElement);
} else {
console.error('Menu element not found');
}
}
}
function waitForElement(selector, callback) {
const observer = new MutationObserver((mutations, observer) => {
const element = document.querySelector(selector);
if (element) {
observer.disconnect();
callback(element);
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
if (username) {
const fetchFunctions = [
() => fetchUserProfileFansly(username),
() => fetchUserProfileCoomer(username, "onlyfans"),
() => fetchUserProfileFapello(username),
() => fetchUserProfileLeakNudes(username)
];
const alternateUsername = username.includes("_") ? username.replaceAll("_", "-") : null;
if (window.location.hostname === 'fansly.com') {
waitForElement('.profile-details', () => {
fetchFunctions.forEach(fetch => fetch());
if (alternateUsername) {
fetchUserProfileFapello(alternateUsername);
}
});
} else if (window.location.hostname === 'fantrie.com') {
waitForElement('.left-menus', () => {
fetchFunctions.slice(2).forEach(fetch => fetch());
});
} else {
waitForElement('.l-header__menu.m-native-custom-scrollbar.m-scrollbar-y.m-invisible-scrollbar', () => {
fetchFunctions.forEach(fetch => fetch());
if (alternateUsername) {
fetchUserProfileFapello(alternateUsername);
}
});
}
}
})();