Bumble Auto Swipe Bot

Bumble auto swipe bot

  1. /* eslint-disable func-names */
  2. // ==UserScript==
  3. // @name Bumble Auto Swipe Bot
  4. // @namespace http://tampermonkey.net/
  5. // @version 0.1
  6. // @license GNU GPLv3
  7. // @description Bumble auto swipe bot
  8. // @author Aamir khan
  9. // @url github.com/iamaamir
  10. // @namespace https://github.com/iamaamir
  11. // @match https://bumble.com/app
  12. // @icon https://www.google.com/s2/favicons?domain=bumble.com
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16. (function (win) {
  17. const swipes = []; // save all the swipes
  18. const minTime = 5000;
  19. const maxTime = 2500;
  20.  
  21. // helpers
  22. const b = (obj, f) => obj[f].bind(obj);
  23. const select = b(document, 'querySelector');
  24. const el = b(document, 'createElement');
  25. const log = b(console, 'log');
  26.  
  27. // icons
  28. 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>';
  29. 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>';
  30. 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>';
  31.  
  32. // css selectors
  33. const actionBarClass = '.encounters-controls__hotkeys';
  34. const usernameClass = '.encounters-story-profile__user';
  35. const profileBoxClass = 'picture.media-box__picture';
  36. const townClass = '.location-widget';
  37. const likeBtnClass = '.encounters-action--like';
  38.  
  39. const addAction = (title, cb = log, icon) => {
  40. log('making a new action', title);
  41. const action = el('div');
  42. const actionBar = select(actionBarClass);
  43. action.addEventListener('click', cb);
  44. const html = `<div class="hotkey tooltip-activator" title=${title}>
  45. <div class="hotkey__icon">
  46. <span class="icon icon--size-stretch" role="presentation" data-qa-role="icon">
  47. ${icon}
  48. </span>
  49. </div>
  50. </div>`;
  51. action.innerHTML = html;
  52. actionBar.appendChild(action);
  53. };
  54.  
  55. function eventFire(target, etype) {
  56. if (target.fireEvent) {
  57. target.fireEvent(`on${etype}`);
  58. } else {
  59. const evObj = document.createEvent('Events');
  60. evObj.initEvent(etype, true, false);
  61. target.dispatchEvent(evObj);
  62. }
  63. }
  64.  
  65. function getNextSwipeTime(min, max) {
  66. return Math.floor(Math.random() * (max - min) + min);
  67. }
  68.  
  69. function getUserName() {
  70. return select(usernameClass).textContent;
  71. }
  72.  
  73. function getProfilebox() {
  74. return document.querySelectorAll(profileBoxClass);
  75. }
  76.  
  77. function getSrc(pic) {
  78. return pic.firstChild.src;
  79. }
  80.  
  81. function getTown() {
  82. return select(townClass).textContent;
  83. }
  84.  
  85. let timer = null;
  86. const bumbleBot = {
  87. startSwiping: function swipe() {
  88. const likeBtn = select(likeBtnClass);
  89. if (!likeBtn) return;
  90. const nextSwipeTime = getNextSwipeTime(minTime, maxTime);
  91. log('Next Swipe is in ', nextSwipeTime);
  92. timer = setTimeout(() => {
  93. swipes.push([`${getUserName()} from ${getTown()}`, Array.from(getProfilebox()).flatMap(getSrc)]);
  94. eventFire(likeBtn, 'click');
  95. swipe();
  96. }, nextSwipeTime);
  97. },
  98.  
  99. toJson(write = false) {
  100. this.stopSwiping();
  101. const data = JSON.stringify(swipes, null, 2);
  102. const logger = write ? document.write : log;
  103. logger(data);
  104. },
  105.  
  106. stopSwiping: function stopSwiping() {
  107. log('Swiping stopped');
  108. clearTimeout(timer);
  109. },
  110. };
  111.  
  112. function waitForElm(selector) {
  113. return new Promise((resolve) => {
  114. if (select(selector)) return resolve(select(selector));
  115.  
  116. const observer = new MutationObserver(() => {
  117. if (select(selector)) {
  118. resolve(select(selector));
  119. observer.disconnect();
  120. }
  121. });
  122.  
  123. observer.observe(document.body, {
  124. childList: true,
  125. subtree: true,
  126. });
  127. });
  128. }
  129.  
  130. if (win) {
  131. win.onload = function () {
  132. log('loading auto swipe script');
  133. waitForElm(actionBarClass).then(() => {
  134. log('Action bar is ready');
  135. addAction('AutoSwipe', bumbleBot.startSwiping, swipeIcon);
  136. addAction('StopSwipe', bumbleBot.stopSwiping, stopSwipeIcon);
  137. addAction('Collect', b(bumbleBot, 'toJson'), toJsonIcon);
  138. });
  139. };
  140. }
  141. }(window));