Skip to content

Instantly share code, notes, and snippets.

@JulianNorton
Created November 15, 2024 16:09
Show Gist options
  • Save JulianNorton/d063063a55032ffb8a88b979e6569d65 to your computer and use it in GitHub Desktop.
Save JulianNorton/d063063a55032ffb8a88b979e6569d65 to your computer and use it in GitHub Desktop.
Removed old linkedin connection requests
// remove this line before pasting in the console https://www.linkedin.com/mynetwork/invitation-manager/sent/?invitationType=CONNECTION
(function() {
const max_limit = undefined; // Set a number to limit the number of invitations to withdraw, or undefined for all
const minDelay = 1000; // Minimum delay between actions in milliseconds
const maxDelay = 3000; // Maximum delay between actions in milliseconds
const maxInvitationAgeDays = 7; // Invitations sent within the last 7 days will not be withdrawn
var getInvitations = () => {
var withdrawInvitationContainers = document.querySelectorAll("div.invitation-card__action-container");
return withdrawInvitationContainers;
}
var sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
}
var randomDelay = () => {
return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
}
var parseTimeBadge = (timeText) => {
if (!timeText) return Infinity;
const lowerText = timeText.toLowerCase().trim();
if (lowerText.includes('sent today')) {
return 0;
} else if (lowerText.includes('sent yesterday')) {
return 1;
} else {
const match = lowerText.match(/sent\s+(\d+)\s+(\w+)\s+ago/);
if (match) {
const num = parseInt(match[1], 10);
const unit = match[2];
switch (unit) {
case 'day':
case 'days':
return num;
case 'week':
case 'weeks':
return num * 7;
case 'month':
case 'months':
return num * 30;
case 'year':
case 'years':
return num * 365;
default:
return Infinity;
}
}
}
return Infinity;
}
var removeInvitations = async () => {
let invitations = getInvitations();
let counter = 0;
for (let invitation of invitations) {
if (max_limit !== undefined && counter >= max_limit)
break;
try {
// Get the time badge text
const timeBadge = invitation.closest('li.invitation-card').querySelector('.time-badge');
const timeText = timeBadge ? timeBadge.textContent.trim() : '';
const daysAgo = parseTimeBadge(timeText);
// Skip if the invitation was sent recently
if (daysAgo <= maxInvitationAgeDays) {
console.log(`Skipping recent invitation sent ${timeText}.`);
continue;
}
const actionButton = invitation.querySelector('button.invitation-card__action-btn');
if (!actionButton) {
console.warn('Action button not found for an invitation, skipping.');
continue;
}
console.log(`Processing invitation sent ${timeText}: ${actionButton.getAttribute('aria-label')}`);
actionButton.click();
// Wait for the confirmation modal to appear
await new Promise((resolve, reject) => {
var attempts = 0;
var intervalId = setInterval(() => {
const confirmButton = document.querySelector('[data-test-modal-container] [data-test-dialog-primary-btn]');
if (confirmButton) {
clearInterval(intervalId);
confirmButton.click();
resolve();
} else {
attempts++;
if (attempts > 50) { // Wait up to 5 seconds (50 * 100ms)
clearInterval(intervalId);
reject('Confirmation button not found.');
}
}
}, 500);
});
// Wait for a random delay between actions
let delay = randomDelay();
console.log(`Waiting for ${delay} ms before next action...`);
await sleep(delay);
counter++;
} catch (error) {
console.error(`Error withdrawing invitation: ${error}`);
}
}
console.log(`-----------------------Withdraw invitation script completed-----------------------`);
console.log(`-----------------------${counter} pending invitation(s) withdrawn-------------------------------`);
}
removeInvitations();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment