Skip to content

Instantly share code, notes, and snippets.

@shmidtelson
Last active March 25, 2024 09:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shmidtelson/ebd807e2cf64069ee96d36f7d4894f53 to your computer and use it in GitHub Desktop.
Save shmidtelson/ebd807e2cf64069ee96d36f7d4894f53 to your computer and use it in GitHub Desktop.
Linkedin invite sender
/**
@description Auto-adding connections in linkedin
@instruction Open url https://www.linkedin.com/search/results/people/ and type your query.
When you see the result, you should paste the code (below) into the console of your browser and press enter.
This bot can add connections automatically, and it also uses page pagination.
When you reach the weekly limit, the bot will stop.
*/
const currentLanguage = document.querySelector('html').lang
const languageMap = {
'invite': {
'ru': 'Пригласить',
'en': 'Invite',
},
'howknow': {
'ru': 'Откуда вы знаете',
'en': 'How do you know',
},
'dontknow': {
'ru': 'Мы не знакомы',
'en': 'We don\'t know each other',
},
'connect': {
'ru': 'Добавить', // это не точно
'en': 'Connect',
},
'sendNow': {
'ru': '', // это не точно
'en': 'Send now',
},
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function getButtonByAriaLabel(ariaLabel) {
return document.querySelector(`button[aria-label="${ariaLabel}"]`)
}
async function waitForContentAfterPaginationClick() {
const totalSecondsOfWaiting = 120
const TRIES_LIMIT = 5
let tries = 1
let i = 1
while (tries <= TRIES_LIMIT) {
if (i > totalSecondsOfWaiting) {
console.log('Page waiting timeout');
tries++;
i = 1;
}
if (document.querySelectorAll('.reusable-search__entity-result-list .artdeco-button').length) {
return true
}
await sleep(1000)
i++
}
throw new Error('Page waiting error')
}
async function sendPollResponseIfActiveModal() {
const pollModalText = document.querySelector('#send-invite-modal');
if (!pollModalText) return
console.log('pollModalText', pollModalText)
if (pollModalText.outerText.startsWith(languageMap.howknow[currentLanguage])) {
const btnDontKnowEachOther = getButtonByAriaLabel(languageMap.dontknow[currentLanguage])
const btnConnect = getButtonByAriaLabel(languageMap.connect[currentLanguage])
await btnDontKnowEachOther.click()
await sleep(500)
await btnConnect.click()
await sleep(500)
const getNewButtonConnect = getButtonByAriaLabel(languageMap.connect[currentLanguage])
getNewButtonConnect.click()
await sleep(500)
const getSendNow = getButtonByAriaLabel(languageMap.sendNow[currentLanguage])
getSendNow.click()
await sleep(500)
}
}
async function waitForNextButtonAndThenClickIt() {
const totalSecondsOfWaiting = 300
let i = 1
while (true) {
if (i > totalSecondsOfWaiting) throw new Error('Page waiting timeout')
const btn = document.querySelector('.artdeco-pagination__button.artdeco-pagination__button--next')
if (btn) {
console.log('Try to click ', document.querySelector('.artdeco-pagination__button.artdeco-pagination__button--next'))
btn.click()
return true
}
await sleep(1000)
i++
}
}
async function clicks() {
const btns = document.querySelectorAll(`.entity-result__actions [aria-label^="${languageMap['invite'][currentLanguage]}"].artdeco-button:not(.artdeco-button--muted)`)
for (let btn of btns) {
await sleep(1000);
if (document.querySelector('.ip-fuse-limit-alert__warning')) throw new Error('LIMIT');
btn.scrollIntoView();
btn.click();
console.log('clicked at ', btn);
await sleep(3000);
const btnSend = document.querySelector('.artdeco-modal__actionbar .artdeco-button.artdeco-button--primary');
btnSend.click();;
console.log('clicked at ', btnSend);
await sendPollResponseIfActiveModal();
new Error(' FINISH ');
}
console.log('Done');
}
async function scrollToBottom() {
await window.scrollTo(0, document.body.scrollHeight);
}
async function navigation() {
while(true) {
await clicks();
console.log('PAGE COMPLETE');
await sleep(2000);
await scrollToBottom();
console.log('SCROLLED TO BOTTOM');
await sleep(2000);
await waitForNextButtonAndThenClickIt();
await waitForContentAfterPaginationClick();
}
}
navigation()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment