Skip to content

Instantly share code, notes, and snippets.

@jofftiquez
Last active July 11, 2024 16:20
Show Gist options
  • Save jofftiquez/5f0c7a2e327b587aad7177a41cc83ee5 to your computer and use it in GitHub Desktop.
Save jofftiquez/5f0c7a2e327b587aad7177a41cc83ee5 to your computer and use it in GitHub Desktop.
Automatic kudos script for Strava web
// Strava Kudos Clicker Automation Script
// Purpose: Automatically clicks "Give Kudos" buttons on your Strava feed
// Features:
// - Handles dynamic loading of buttons.
// - Smoothly scrolls to each button before clicking.
// - Timeouts between clicks and retries to avoid overloading the page.
// - Maximum retry limit to prevent infinite loops.
// How to Use in Browser's Developer Console:
// 0. Head over to https://www.strava.com/dashboard (Make sure you're logged in)
// 1. Open the Developer Console:
// * Chrome/Edge/Opera: Right-click anywhere on the page and select "Inspect" or press Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac). Then click the "Console" tab.
// * Firefox: Right-click anywhere on the page and select "Inspect Element" or press Ctrl+Shift+K (Windows/Linux) or Cmd+Option+K (Mac).
// * Safari: Enable the Develop menu in Safari's preferences (if it's not already enabled). Then, right-click on the page and select "Inspect Element."
// 2. Copy this entire script.
// 3. Paste into the developer console.
// 4. Press Enter to execute.
// 5. Observe: The script will start clicking "Give Kudos" buttons. You'll see messages in the console.
(async function() {
const clickTimeout = 3000;
const retryTimeout = 3000;
const maxRetries = 30;
const jitter = 700; // Add a jitter value, e.g., 700ms
const kudosButtonsSelector = 'button[title="Give kudos"], button[title="Be the first to give kudos!"]';
function getRandomTimeout(base, jitter) {
return base + Math.random() * jitter;
}
async function clickKudos() {
let buttons = Array.from(document.querySelectorAll(kudosButtonsSelector));
console.warn(`Number of kudos: ${buttons.length}`);
let retries = 0;
let index = 0;
let seenButtons = new Set(buttons.map(btn => btn));
while (retries < maxRetries) {
if (index < buttons.length) {
try {
buttons[index].scrollIntoView({ behavior: "smooth", block: "center" });
const timeout = getRandomTimeout(clickTimeout, jitter);
await new Promise(resolve => setTimeout(resolve, timeout));
buttons[index].click();
console.warn(`👍 Kudos ${index + 1} took ${timeout}ms`);
} catch (error) {
console.error(`👎 Error kudos ${index + 1}:`, error);
}
index++;
} else {
window.scrollBy(0, window.innerHeight);
await new Promise(resolve => setTimeout(resolve, retryTimeout));
let newButtons = Array.from(document.querySelectorAll(kudosButtonsSelector));
newButtons.forEach(btn => {
if (!seenButtons.has(btn)) {
buttons.push(btn);
seenButtons.add(btn);
}
});
console.warn(`Retrying... Number of kudos: ${buttons.length}`);
if (buttons.length === index) { // no new buttons found
retries++;
} else {
retries = 0; // Reset retries if new buttons are found
}
}
}
console.warn("Reached retry limit. Stopping.");
}
await clickKudos();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment