Bumble Auto Swipe Bot

Bumble auto swipe bot

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

/* eslint-disable func-names */
// ==UserScript==
// @name         Bumble Auto Swipe Bot
// @namespace    http://tampermonkey.net/
// @version      0.1
// @license      GNU GPLv3
// @description  Bumble auto swipe bot
// @author       Aamir khan
// @url          github.com/iamaamir
// @namespace    https://github.com/iamaamir
// @match        https://bumble.com/app
// @icon         https://www.google.com/s2/favicons?domain=bumble.com
// @grant        none
// ==/UserScript==

(function (win) {
  const swipes = []; // save all the swipes
  const minTime = 5000;
  const maxTime = 2500;

  // helpers
  const b = (obj, f) => obj[f].bind(obj);
  const select = b(document, 'querySelector');
  const el = b(document, 'createElement');
  const log = b(console, 'log');

  // icons
  const swipeIcon = '<svg viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"><path  d="M30.4 17.6c-1.8-1.9-4.2-3.2-6.7-3.7-1.1-.3-2.2-.5-3.3-.6 2.8-3.3 2.3-8.3-1-11.1s-8.3-2.3-11.1 1-2.3 8.3 1 11.1c.6.5 1.2.9 1.8 1.1v2.2l-1.6-1.5c-1.4-1.4-3.7-1.4-5.2 0-1.4 1.4-1.5 3.6-.1 5l4.6 5.4c.2 1.4.7 2.7 1.4 3.9.5.9 1.2 1.8 1.9 2.5v1.9c0 .6.4 1 1 1h13.6c.5 0 1-.5 1-1v-2.6c1.9-2.3 2.9-5.2 2.9-8.1v-5.8c.1-.4 0-.6-.2-.7zm-22-9.4c0-3.3 2.7-5.9 6-5.8 3.3 0 5.9 2.7 5.8 6 0 1.8-.8 3.4-2.2 4.5v-5a3.4 3.4 0 0 0-3.4-3.2c-1.8-.1-3.4 1.4-3.4 3.2v5.2c-1.7-1-2.7-2.9-2.8-4.9zM28.7 24c.1 2.6-.8 5.1-2.5 7.1-.2.2-.4.4-.4.7v2.1H14.2v-1.4c0-.3-.2-.6-.4-.8-.7-.6-1.3-1.3-1.8-2.2-.6-1-1-2.2-1.2-3.4 0-.2-.1-.4-.2-.6l-4.8-5.7c-.3-.3-.5-.7-.5-1.2 0-.4.2-.9.5-1.2.7-.6 1.7-.6 2.4 0l2.9 2.9v3l1.9-1V7.9c.1-.7.7-1.3 1.5-1.2.7 0 1.4.5 1.4 1.2v11.5l2 .4v-4.6c.1-.1.2-.1.3-.2.7 0 1.4.1 2.1.2v5.1l1.6.3v-5.2l1.2.3c.5.1 1 .3 1.5.5v5l1.6.3v-4.6c.9.4 1.7 1 2.4 1.7l.1 5.4z"/></svg>';
  const stopSwipeIcon = '<svg class="has-solid" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"><path class="clr-i-outline clr-i-outline-path-1" d="M30 32H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h24a2 2 0 0 1 2 2v24a2 2 0 0 1-2 2ZM6 6v24h24V6Z"/></svg>';
  const toJsonIcon = '<svg viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"><path d="M28.09 9.74a4 4 0 0 0-1.16.19c-.19-1.24-1.55-2.18-3.27-2.18a4 4 0 0 0-1.53.25A3.37 3.37 0 0 0 19 6.3a3.45 3.45 0 0 0-2.87 1.32 3.65 3.65 0 0 0-1.89-.51A3.05 3.05 0 0 0 11 9.89v.91c-1.06.4-4.11 1.8-4.91 4.84s.34 8 2.69 11.78a25.21 25.21 0 0 0 5.9 6.41.9.9 0 0 0 .53.17h10.34a.92.92 0 0 0 .55-.19 13.13 13.13 0 0 0 3.75-6.13A25.8 25.8 0 0 0 31.41 18v-5.5a3.08 3.08 0 0 0-3.32-2.76ZM29.61 18a24 24 0 0 1-1.47 9.15 12.46 12.46 0 0 1-2.94 5.05h-9.73a23.75 23.75 0 0 1-5.2-5.72c-2.37-3.86-3-8.23-2.48-10.39A5.7 5.7 0 0 1 11 12.76v7.65a.9.9 0 0 0 1.8 0V9.89c0-.47.59-1 1.46-1s1.49.52 1.49 1v5.72h1.8v-6.8c0-.28.58-.71 1.46-.71s1.53.48 1.53.75v6.89h1.8V10l.17-.12a2.1 2.1 0 0 1 1.18-.32c.93 0 1.5.44 1.5.68v6.5H27v-4.87a1.91 1.91 0 0 1 1.12-.33c.86 0 1.52.51 1.52.94Z" class="clr-i-outline clr-i-outline-path-1"/></svg>';

  // css selectors
  const actionBarClass = '.encounters-controls__hotkeys';
  const usernameClass = '.encounters-story-profile__user';
  const profileBoxClass = 'picture.media-box__picture';
  const townClass = '.location-widget';
  const likeBtnClass = '.encounters-action--like';

  const addAction = (title, cb = log, icon) => {
    log('making a new action', title);
    const action = el('div');
    const actionBar = select(actionBarClass);
    action.addEventListener('click', cb);
    const html = `<div class="hotkey tooltip-activator" title=${title}>
  <div class="hotkey__icon">
      <span class="icon icon--size-stretch" role="presentation" data-qa-role="icon">
          ${icon}
      </span>
  </div>
  </div>`;
    action.innerHTML = html;
    actionBar.appendChild(action);
  };

  function eventFire(target, etype) {
    if (target.fireEvent) {
      target.fireEvent(`on${etype}`);
    } else {
      const evObj = document.createEvent('Events');
      evObj.initEvent(etype, true, false);
      target.dispatchEvent(evObj);
    }
  }

  function getNextSwipeTime(min, max) {
    return Math.floor(Math.random() * (max - min) + min);
  }

  function getUserName() {
    return select(usernameClass).textContent;
  }

  function getProfilebox() {
    return document.querySelectorAll(profileBoxClass);
  }

  function getSrc(pic) {
    return pic.firstChild.src;
  }

  function getTown() {
    return select(townClass).textContent;
  }

  let timer = null;
  const bumbleBot = {
    startSwiping: function swipe() {
      const likeBtn = select(likeBtnClass);
      if (!likeBtn) return;
      const nextSwipeTime = getNextSwipeTime(minTime, maxTime);
      log('Next Swipe is in ', nextSwipeTime);
      timer = setTimeout(() => {
        swipes.push([`${getUserName()} from ${getTown()}`, Array.from(getProfilebox()).flatMap(getSrc)]);
        eventFire(likeBtn, 'click');
        swipe();
      }, nextSwipeTime);
    },

    toJson(write = false) {
      this.stopSwiping();
      const data = JSON.stringify(swipes, null, 2);
      const logger = write ? document.write : log;
      logger(data);
    },

    stopSwiping: function stopSwiping() {
      log('Swiping stopped');
      clearTimeout(timer);
    },
  };

  function waitForElm(selector) {
    return new Promise((resolve) => {
      if (select(selector)) return resolve(select(selector));

      const observer = new MutationObserver(() => {
        if (select(selector)) {
          resolve(select(selector));
          observer.disconnect();
        }
      });

      observer.observe(document.body, {
        childList: true,
        subtree: true,
      });
    });
  }

  if (win) {
    win.onload = function () {
      log('loading auto swipe script');
      waitForElm(actionBarClass).then(() => {
        log('Action bar is ready');
        addAction('AutoSwipe', bumbleBot.startSwiping, swipeIcon);
        addAction('StopSwipe', bumbleBot.stopSwiping, stopSwipeIcon);
        addAction('Collect', b(bumbleBot, 'toJson'), toJsonIcon);
      });
    };
  }
}(window));