Skip to content

Instantly share code, notes, and snippets.

@jwmann
Created July 20, 2023 06:09
Show Gist options
  • Save jwmann/85275ab1ccd0b959b56ec5abfb9e6411 to your computer and use it in GitHub Desktop.
Save jwmann/85275ab1ccd0b959b56ec5abfb9e6411 to your computer and use it in GitHub Desktop.
Auto-Like Garmin Posts for TamperMonkey userscripts. Based on my stravaAutoLike.js
// ==UserScript==
// @name Auto-Like Garmin Posts
// @namespace http://tampermonkey.net/
// @version 0.1.0
// @description Like all the posts!
// @author James W Mann
// @match https://connect.garmin.com/modern/newsfeed
// @icon https://www.google.com/s2/favicons?sz=64&domain=connect.garmin.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
const debug = true;
const log = (...params) => debug ? console.log(...params) : null;
log('Auto-Like Garmin Posts Script Initialized.');
const YourGarminFullName = 'James Mann'
const pageLoadWait = 5000 // Amount of time in milliseconds to wait until the page is loaded
const waitLimit = 60; // 30 Seconds timeout for how long to wait for loading more posts
const emptyLimit = 1; // How many times it double checks for any more unliked posts by loading more
const container = document.querySelector('div.main-body'); // Normally this should be left undefined unless the site scrolls within a container/frame
const heightPadding = 60; // Amount of pixels to accomodate for when scrolling down
const waitTick = 500; // Amount of time in milliseconds to wait to check if posts have loaded yet
let emptyAmount = 0;
let postsAmount = 0
const getScrollHeight = () => {
const scrollHeight = container ? container.scrollHeight : document.body.scrollHeight;
log(`Getting a scroll height of: ${scrollHeight}px`, { container });
return scrollHeight;
}
const scrollToY = (y = 0) => new Promise( (r, j) => {
log(`Attempting to scroll to: ${y}px position on the page.`, { container });
if (container) container.scrollTo(0, y);
else window.scrollTo(0, y);
log('Waiting for scroll to complete...');
setTimeout(() => r(log('Scrolling complete.')), waitTick || 500);
});
const getPosts = () => document.querySelectorAll('main div[class^=ActivityCard_activityContainer]');
const clickPosts = async () => {
let unclickedPosts = 0;
const posts = getPosts();
postsAmount = posts.length;
log(`${postsAmount} posts currently found.`);
posts.forEach( el => {
const author = el.querySelector('div[class^="ActivityCard_nameTimeWrapper"] a')?.title;
if (author && author !== YourGarminFullName) {
const likeBtn = el.querySelector('button[aria-label="Like"]');
if (likeBtn) {
unclickedPosts++;
likeBtn.click();
}
}
});
if (unclickedPosts === 0) {
if (emptyAmount < emptyLimit) {
emptyAmount++;
log(`All posts already liked. Loading more posts to double check... ${emptyAmount} out of ${emptyLimit} times`);
await loadMorePosts();
} else {
log('Done Liking');
await scrollToY(); // Scroll to the top of the page
}
} else await loadMorePosts();
}
const loadMorePosts = async () => {
let waitAmount = 0;
log(`Loading more posts...`);
await scrollToY(getScrollHeight() + (heightPadding || 0)); // Scroll to the bottom of the page
const checkPosts = () => setTimeout(() => {
if (waitAmount < waitLimit) {
log('Waiting for posts...');
waitAmount++;
} else {
log('Waiting too long, halting...');
return;
}
const newPostsAmount = getPosts().length;
if (postsAmount === newPostsAmount) checkPosts();
else clickPosts();
}, waitTick || 500);
checkPosts();
};
setTimeout(clickPosts, pageLoadWait || 1000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment