// ==UserScript==
// @name AutoSwipe for Tinder
// @name:pt AutoSwipe para Tinder
// @name:pt-BR AutoSwipe para Tinder
// @version 1.1
// @description Script para auto like/deslike no Tinder com base em palavras proibidas, sliders e melhorias visuais no painel.
// @description:pt Script para auto like/deslike no Tinder com base em palavras proibidas, sliders e melhorias visuais no painel.
// @description:pt-BR Script para auto like/deslike no Tinder com palavras proibidas, sliders e melhorias visuais no painel.
// @compatible chrome
// @compatible firefox
// @author Nox
// @match https://tinder.com/app/recs
// @grant none
// @icon https://www.google.com/s2/favicons?sz=64&domain=tinder.com
// @license MIT
// @namespace https://greasyfork.org/users/1416065
// ==/UserScript==
(function () {
'use strict';
// Configurações iniciais
let interval = 3000; // Intervalo entre ações (ms)
let profileOpenWait = 3000; // Tempo de espera ao abrir o perfil (ms)
let forbiddenWords = ['exemplo', 'louca', 'proibido']; // Palavras proibidas padrão
let likesCount = 0;
let dislikesCount = 0;
let isPaused = false;
// Carregar valores armazenados no localStorage, se existirem
interval = parseInt(localStorage.getItem('interval')) || interval;
profileOpenWait =
parseInt(localStorage.getItem('profileOpenWait')) || profileOpenWait;
// Criação do painel de controle
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '10px';
container.style.right = '10px';
container.style.zIndex = '1000';
container.style.width = '250px';
container.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
container.style.color = 'white';
container.style.padding = '15px';
container.style.borderRadius = '10px';
container.style.fontFamily = 'Arial, sans-serif';
container.style.fontSize = '14px';
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.gap = '10px';
container.style.opacity = '0.2';
container.style.transition = 'opacity 0.3s';
document.body.appendChild(container);
container.addEventListener('mouseenter', () => {
container.style.opacity = '1';
});
container.addEventListener('mouseleave', () => {
container.style.opacity = '0.2';
});
const statsContainer = document.createElement('div');
statsContainer.style.display = 'flex';
statsContainer.style.justifyContent = 'space-between';
statsContainer.style.marginBottom = '10px';
const likeCounter = document.createElement('div');
likeCounter.textContent = `Likes: ${likesCount}`;
statsContainer.appendChild(likeCounter);
const dislikeCounter = document.createElement('div');
dislikeCounter.textContent = `Dislikes: ${dislikesCount}`;
statsContainer.appendChild(dislikeCounter);
container.appendChild(statsContainer);
forbiddenWords =
JSON.parse(localStorage.getItem('forbiddenWords')) || forbiddenWords;
const forbiddenWordsInput = document.createElement('textarea');
forbiddenWordsInput.value = forbiddenWords.join(', ');
forbiddenWordsInput.style.width = '100%';
forbiddenWordsInput.style.height = '50px';
forbiddenWordsInput.style.borderRadius = '8px';
forbiddenWordsInput.style.padding = '5px';
forbiddenWordsInput.style.marginTop = '5px';
const forbiddenWordsLabel = document.createElement('label');
forbiddenWordsLabel.textContent =
'Palavras proibidas (separadas por vírgula)';
container.appendChild(forbiddenWordsLabel);
container.appendChild(forbiddenWordsInput);
forbiddenWordsInput.addEventListener('input', () => {
forbiddenWords = forbiddenWordsInput.value
.split(',')
.map((word) => word.trim())
.filter((word) => word.length > 0);
localStorage.setItem('forbiddenWords', JSON.stringify(forbiddenWords)); // Salvar no localStorage
});
const pauseButton = document.createElement('button');
pauseButton.textContent = 'Pausar';
pauseButton.style.padding = '10px';
pauseButton.style.borderRadius = '8px';
pauseButton.style.cursor = 'pointer';
container.appendChild(pauseButton);
const createSlider = (
labelText,
min,
max,
step,
initialValue,
nameInterval,
onChange
) => {
const sliderContainer = document.createElement('div');
sliderContainer.style.display = 'flex';
sliderContainer.style.flexDirection = 'column';
const label = document.createElement('label');
label.textContent = labelText;
label.style.marginBottom = '5px';
sliderContainer.appendChild(label);
const valueDisplay = document.createElement('div');
valueDisplay.style.textAlign = 'right';
valueDisplay.textContent = `${(initialValue / 1000).toFixed(1)}s`;
sliderContainer.appendChild(valueDisplay);
const slider = document.createElement('input');
slider.type = 'range';
slider.min = min;
slider.max = max;
slider.step = step;
slider.value = initialValue;
slider.style.width = '100%';
slider.addEventListener('input', (e) => {
const value = parseFloat(e.target.value);
valueDisplay.textContent = `${(value / 1000).toFixed(1)}s`;
onChange(value);
localStorage.setItem(nameInterval, value);
});
sliderContainer.appendChild(slider);
return sliderContainer;
};
const intervalSlider = createSlider(
'Intervalo entre ações (segundos)',
100,
10000,
100,
interval,
'interval',
(value) => {
interval = value;
}
);
container.appendChild(intervalSlider);
const profileWaitSlider = createSlider(
'Espera ao abrir perfil (segundos)',
100,
10000,
100,
profileOpenWait,
'profileOpenWait',
(value) => {
profileOpenWait = value;
}
);
container.appendChild(profileWaitSlider);
pauseButton.addEventListener('click', () => {
isPaused = !isPaused;
pauseButton.textContent = isPaused ? 'Continuar' : 'Pausar';
});
// Criação do contêiner de informações do perfil
const profileInfoContainer = document.createElement('div');
profileInfoContainer.style.padding = '10px';
profileInfoContainer.style.backgroundColor = '#1c1c1c';
profileInfoContainer.style.borderRadius = '8px';
profileInfoContainer.style.color = '#ffcc00';
profileInfoContainer.style.marginTop = '10px';
profileInfoContainer.style.display = 'flex';
profileInfoContainer.style.flexDirection = 'column';
profileInfoContainer.style.gap = '5px';
container.appendChild(profileInfoContainer);
// Função para criar cada linha de informação
function createInfoRow(label, value) {
const row = document.createElement('div');
row.style.display = 'flex';
row.style.justifyContent = 'space-between';
const labelSpan = document.createElement('span');
labelSpan.textContent = label + ':';
labelSpan.style.fontWeight = 'bold';
const valueSpan = document.createElement('span');
valueSpan.textContent = value;
row.appendChild(labelSpan);
row.appendChild(valueSpan);
return row;
}
// Função de extração das informações
function extractProfileInfo() {
const profileContainer = document.querySelector(
'.Bgc\\(--color--background-sparks-profile\\)'
);
if (!profileContainer) {
console.log('Perfil não encontrado.');
return null;
}
const sections = profileContainer.querySelectorAll('.D\\(f\\).Ai\\(c\\)');
const profileInfo = {};
sections.forEach((section) => {
const svg = section.querySelector('svg path');
const textElement = section.querySelector(
'.Typs\\(body-1-regular\\), .Typs\\(body-1-strong\\)'
);
if (!svg || !textElement) return;
const svgPath = svg.getAttribute('d').trim();
const textContent = textElement.textContent.trim();
if (svgPath.includes('M12.301')) {
profileInfo.distance = textContent;
} else if (svgPath.includes('M16.95')) {
profileInfo.height = textContent;
} else if (svgPath.includes('M16.995')) {
profileInfo.profession = textContent;
} else if (svgPath.includes('M11.171')) {
profileInfo.university = textContent;
} else if (svgPath.includes('M2.25')) {
profileInfo.location = textContent;
} else if (svgPath.includes('M12.225')) {
profileInfo.genderPronoun = textContent;
} else if (svgPath.includes('M12 21.994')) {
profileInfo.genderIdentity = textContent;
} else if (svgPath.includes('M22.757')) {
profileInfo.languages = textContent;
} else {
profileInfo.other = textContent; // Caso algum ícone não mapeado apareça
}
});
return profileInfo;
}
const profileInfo = document.createElement('div');
profileInfo.style.padding = '10px';
profileInfo.style.backgroundColor = '#1c1c1c';
profileInfo.style.borderRadius = '8px';
profileInfo.style.color = '#ffcc00';
profileInfo.textContent = 'Sobre mim: Não disponível';
container.appendChild(profileInfo);
const forbiddenWordReason = document.createElement('div');
forbiddenWordReason.style.padding = '10px';
forbiddenWordReason.style.backgroundColor = '#8b0000';
forbiddenWordReason.style.color = 'white';
forbiddenWordReason.style.borderRadius = '8px';
forbiddenWordReason.style.display = 'none';
forbiddenWordReason.textContent = 'Motivo do deslike: Nenhum';
container.appendChild(forbiddenWordReason);
function updateLikeCounter() {
likeCounter.textContent = `Likes: ${likesCount}`;
}
function updateDislikeCounter() {
dislikeCounter.textContent = `Dislikes: ${dislikesCount}`;
}
function updateProfileInfo(text) {
const profileInfo = extractProfileInfo();
if (!profileInfo) {
console.log('Não foi possível extrair as informações do perfil.');
return;
}
const {
distance = 'Não informado',
height = 'Não informado',
profession = 'Não informado',
university = 'Não informado',
location = 'Não informado',
genderPronoun = 'Não informado',
genderIdentity = 'Não informado',
languages = 'Não informado',
} = profileInfo;
console.log('Informações extraídas:', profileInfo);
// Limpa o contêiner antes de atualizar
profileInfoContainer.innerHTML = '';
// Adiciona as informações capturadas
profileInfoContainer.appendChild(createInfoRow('Distância', distance));
profileInfoContainer.appendChild(createInfoRow('Altura', height));
profileInfoContainer.appendChild(createInfoRow('Profissão', profession));
profileInfoContainer.appendChild(createInfoRow('Universidade', university));
profileInfoContainer.appendChild(createInfoRow('Localização', location));
profileInfoContainer.appendChild(createInfoRow('Pronomes', genderPronoun));
profileInfoContainer.appendChild(
createInfoRow('Identidade de Gênero', genderIdentity)
);
profileInfoContainer.appendChild(createInfoRow('Idiomas', languages));
// Atualiza a seção "Sobre mim"
profileInfo.textContent = `Sobre mim: ${text}`;
}
function showForbiddenWordReason(reason) {
forbiddenWordReason.textContent = `Motivo do deslike: ${reason}`;
forbiddenWordReason.style.display = 'block';
}
function findLikeButton() {
return document.querySelector(
'.gamepad-button-wrapper .button.Bgc\\(\\$c-ds-background-gamepad-sparks-like-default\\)'
);
}
function findDislikeButton() {
return document.querySelector(
'.gamepad-button-wrapper .button.Bgc\\(\\$c-ds-background-gamepad-sparks-nope-default\\)'
);
}
function findProfileButton() {
return document.querySelector(
'button.P\\(0\\).Trsdu\\(\\$normal\\).Sq\\(28px\\)'
);
}
function findProfileInfo() {
const aboutHeader = Array.from(document.querySelectorAll('div')).find(
(div) => div.textContent.includes('Sobre mim')
);
if (aboutHeader) {
const content = aboutHeader.parentElement.querySelector(
'.Typs\\(body-1-regular\\)'
);
console.log(content);
if (content) return content;
}
return 'Não disponível';
}
async function autoAction() {
if (isPaused) return;
const profileButton = findProfileButton();
if (profileButton) {
profileButton.click();
console.log('Botão de abrir perfil clicado.');
await new Promise((resolve) => setTimeout(resolve, profileOpenWait)); // Esperar o perfil carregar
const aboutText = findProfileInfo();
updateProfileInfo(aboutText);
console.log(`Sobre mim: ${aboutText}`);
await new Promise((resolve) =>
setTimeout(resolve, profileOpenWait + interval)
);
}
const profileContainer = document.querySelector(
'.Bgc\\(--color--background-sparks-profile\\)'
);
const profileText = profileContainer
? Array.from(profileContainer.querySelectorAll('*'))
.map((element) => element.textContent.trim())
.filter((text) => text.length > 0)
.join('\n')
: '';
console.log(`InfoProfile:\n${profileText}`);
const profileInfo = extractProfileInfo();
console.log('Informações detalhadas do perfil:', profileInfo);
// Verifica palavras proibidas
for (const word of forbiddenWords) {
if (profileText.toLowerCase().includes(word.toLowerCase())) {
const dislikeButton = findDislikeButton();
if (dislikeButton) {
dislikeButton.click();
dislikesCount++;
updateDislikeCounter();
showForbiddenWordReason(word);
console.log(`Deslike dado! Motivo: ${word}`);
const delay = interval;
await new Promise((resolve) => setTimeout(resolve, delay));
return;
}
}
}
// Ação de like se não houver palavras proibidas
const likeButton = findLikeButton();
if (likeButton) {
likeButton.click();
likesCount++;
updateLikeCounter();
console.log(`Like dado!`);
}
await new Promise((resolve) => setTimeout(resolve, interval));
}
async function main() {
while (true) {
if (!isPaused) {
await autoAction();
} else {
await new Promise((resolve) => setTimeout(resolve, 100)); // Aguardar brevemente enquanto pausado
}
}
}
main();
})();