Skip to content

Instantly share code, notes, and snippets.

@ronaldluc
Created July 31, 2019 15:21
Show Gist options
  • Save ronaldluc/2adbad3703e9a61a7e584f0b30afd07f to your computer and use it in GitHub Desktop.
Save ronaldluc/2adbad3703e9a61a7e584f0b30afd07f to your computer and use it in GitHub Desktop.
victor_violates_GDPR
// ==UserScript==
// @name One-click add All LinkedIn People
// @description One-click add all LinkedIn "Recommended for you" people in the My Network page
// @namespace nickpapoutsis
// @author nickpapoutsis
// @copyright 2019, nickpapoutsis (https://openuserjs.org/users/nickpapoutsis)
// @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A6EL76QADA2YY&source=url
// @license MIT
// @include https://bioprocessintl.com/*
// @version 0.8
// @grant none
// @icon data:image/png;base64,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
// ==/UserScript==
// window.onload = function () { console.log("It's loaded!") };
window.clearTimeout = window.clearTimeout.bind(window);
window.clearInterval = window.clearInterval.bind(window);
window.setTimeout = window.setTimeout.bind(window);
window.setInterval = window.setInterval.bind(window);
(function () {
'use strict';
if (window.self == window.top) {
createButton();
createPopup();
}//this makes sure we don't create extra buttons inside iframes, ads, etc
function createButton() {
let div = document.createElement('div');
div.innerHTML = '<a id="connectBtn">Connect!</a>';
div.style.display = "inline-block";
div.style.position = "fixed";
div.style.right = "3em";
div.style.top = "5em";
div.style.zIndex = '995';
div.style.cursor = 'pointer';
document.body.append(div);
let btn = document.getElementById('connectBtn');
btn.style.background = 'white';
btn.style.color = 'blue';
btn.style.fontWeight = '800';
btn.style.padding = '5px';
btn.style.border = 'solid 2px black';
btn.style.borderRadius = '7px';
btn.style.textDecoration = 'none';
btn.style.fontSize = '0.8em';
document.getElementById('connectBtn').addEventListener('click', clicked, false);
}
function createPopup() {
let div = document.createElement('div');
div.innerHTML = '<a id="popup">This button works on the "My Network" section only</a>';
div.style.display = "none";
div.style.position = "fixed";
div.style.right = "3em";
div.style.top = "7.5em";
div.style.zIndex = '996';
div.style.cursor = 'pointer';
document.body.append(div);
let btn = document.getElementById('popup');
btn.style.background = 'palevioletred';
btn.style.color = 'white';
btn.style.marginTop = '0.5em';
btn.style.padding = '4px';
btn.style.borderRadius = '7px';
btn.style.textDecoration = 'none';
btn.style.fontSize = '1em';
}
function clicked() {
var url = location.pathname.split('/');
// alert(url.join(' '));
connectFilteredProfiles();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ACTUAL CODE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function connectFilteredProfiles(texts = []) {
var timeout = getRandomInt(2410, 3720);
// var timeout = getRandomInt(3010, 4224);
var iterate_posts_cls = "archive-default post type-post status-publish format-standard has-post-thumbnail";
var header_cls = "entry-title";
var body_cls = "artdeco-button__icon";
var date_cls = "artdeco-modal__header ip-fuse-limit-alert__header ember-view";
var next_cls = "";
let posts = document.getElementsByClassName(iterate_posts_cls);
console.log("Iterating posts. ");
for (let post of posts) {
let header = post.getElementsByClassName(header_cls)[0].textContent.replace(/([ \n\t])+/g, " ");
// body = post.getEle
var str = post.textContent;
str = str.replace(/([ \n\t,])+/g, " ");
// continue;
console.log(str);
texts.push([str.toString(), "1", Date.now().toString()]);
window.scrollTo(0, document.body.scrollHeight);
}
const rows = texts;
var twoDArrStr = arrayToCSV(rows);
downloadString(twoDArrStr, "csv", "dump.csv");
// TODO: Find the NEXT button
// TODO: click it ```button.click()```
// TODO: run the function after several minileconds again
// setTimeout(() => {
// connectFilteredProfiles(texts)
// }, timeout);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// EXAMPLE OF JS CODE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function iterJobs(texts = [], counter = 0) {
// var btn_cls = "search-result__info pt3 pb4 ph0";
var btn_cls = "search-result__wrapper";
var social_cls = "search-result__social-proof ember-view";
var profiles = document.getElementsByClassName(btn_cls);
for (let profile of profiles) {
// console.log(profile.textContent);
var str = profile.textContent;
var social_str = "";
try {
social_str = profile.getElementsByClassName(social_cls)[0].textContent.replace(/( |\n|\t)+/g, " ");
} catch (err) {
}
str = str.replace(/( |\n|\t)+/g, " ");
// var patt = /machine[a-z ]*learning.*at/i;
console.log(str);
var body_patt = /2nd.*machine/i;
var name_patt = /([^,.\- ]+) [^,.\- ]+(,.+)? 2nd degree connection 2nd/i;
var company_patt = /machine[a-z ]*learning .* at (\w+)/i;
var research_patt = /research/i;
var social_patt = /([^,.\- ]+ [^,.\- ]+)/i;
var body_text = str.match(body_patt);
var name = str.match(name_patt);
var company = str.match(company_patt);
var research = str.match(research_patt);
var social_connection = social_str.match(social_patt);
// console.log(result);
// console.log(result[1] + " | " + result[0]);
console.log(profile);
console.log(name);
var connect_cls = "search-result__action-button search-result__actions--primary artdeco-button artdeco-button--default artdeco-button--2 artdeco-button--secondary";
var connect_btns = profile.getElementsByClassName(connect_cls);
var add_note_cls = "artdeco-button artdeco-button--secondary artdeco-button--3 mr1";
var send_inv_cls = "artdeco-button artdeco-button--3 ml1";
var custom_id = "custom-message";
if (connect_btns.length < 1) {
continue;
}
console.log(customMsg(name, company, research, social_connection));
// continue; //TODO: remove
let connect_btn = connect_btns[0];
// console.log(connect_btn);
console.log(connect_btn.textContent);
if (connect_btn.textContent.includes("Connect")) {
connect_btn.click();
let add_notes = document.getElementsByClassName(add_note_cls);
for (let add_note of add_notes) {
if (add_note.textContent.includes("Add a note")) {
add_note.click();
let custom_msg = document.getElementById(custom_id);
custom_msg.value = customMsg(name, company, research, social_connection);
console.log("Send:\n" + custom_msg.value);
texts.push([str, custom_msg.value]);
counter++;
break;
}
}
let send_invs = document.getElementsByClassName(send_inv_cls);
for (let send_inv of send_invs) {
if (send_inv.textContent.includes("Send invitation")) {
send_inv.click();
}
}
}
// console.log(body_text);
}
var next_cls = "artdeco-pagination__button artdeco-pagination__button--next artdeco-button artdeco-button--muted artdeco-button--icon-right artdeco-button--1 artdeco-button--tertiary ember-view"
var next = document.getElementsByClassName(next_cls);
// return; //TODO: remove
var save_every = 200;
if (counter > save_every || profiles.length < 3) {
counter -= save_every;
// console.log(texts);
const rows = texts;
var twoDArrStr = arrayToCSV(rows);
downloadString(twoDArrStr, "csv", "linked_in_job_titles.csv");
}
console.log("Invited " + texts.length + " | counter " + counter);
next[0].click();
setTimeout(() => {
iterJobs(texts, counter)
}, 4200);
}
function customMsg(name, company, research, social_connection) {
// console.log("\n\nPrint customMsg inputs:");
// for (let p of [name, company, research, social_connection]) {
// console.log(p);
// }
if (name == null) {
return "Hi.";
}
name = capitalize(name[1]);
if (research !== null && research.length > 0) {
return "Hi " + name + ",\n" +
"\n" +
"it's nice to connect to other ML experts and as I was scrolling through LinkedIn, I saw you do some research in this field. \n" +
"Could you please tell me more about your research?\n" +
"\n" +
"Thanks, Ronald";
}
if (social_connection == null) {
return "Hi " + name + ",\n" +
"\n" +
"it's nice to connect to other ML experts.\n" +
"\n" +
"Ronald";
}
social_connection = capitalize(social_connection[1]);
var company_name = "";
if (company != null) {
company_name = capitalize(company[1]);
}
var exclude_patt = /free|self|deutch|austri|ww/i;
var exclude = company_name.match(exclude_patt);
console.log("Company name: " + company_name + " length " + company_name.length);
// Engineer No company name
if (exclude !== null || company_name.length < 3) {
return "Hi " + name + ",\n" +
"\n" +
"it's nice to connect to other ML experts and I saw you are connected to " + social_connection + " already.\n" +
"\n" +
"Best, Ronald";
}
// Engineer with company name
var send = "Hi " + name + ",\n" +
"\n" +
"I was scrolling through LinkedIn and saw you are connected to " + social_connection + " already.\n";
if (Math.random() >= 0.5) {
// "Could you please tell me, what is ML like at " + company_name + "?\n" +
send += "It's nice to connect to other ML experts + I would like to ask you, what is ML like at " + company_name + ".\n";
} else {
send += "It's nice to connect to other ML experts + Could you please tell me more about ML at " + company_name + "?\n";
}
return send +
"\n" +
"Thanks, Ronald";
}
function clickOnProfile(skip = 0) {
var url = location.pathname.split('/');
//TODO: Check if the page is really loaded
if (url[1] === 'search' && url[2] === 'results') {
console.log("Processed " + name_links + " with skip === " + skip);
var mx = 5;
var btn_cls = "name actor-name";
var name_links = document.getElementsByClassName(btn_cls);
processName(name_links[skip], skip + 1);
} else {
console.log("Waiting to get to search/results");
setTimeout(() => {
clickOnProfile(skip)
}, 500);
}
}
function processName(name_link, skip) {
name_link.click();
console.log("Processed " + name_link);
// processProfile();
setTimeout(() => {
processProfile(skip)
}, 1000);
return 1;
}
function processProfile(skip) {
var text_cls = "pv-entity__secondary-title";
// var texts = document.getElementsByClassName(text_cls);
if (document.getElementsByClassName(text_cls).length === 0) {
setTimeout(() => {
processProfile(skip)
}, 500);
} else {
setTimeout(() => {
var texts = document.getElementsByClassName(text_cls);
console.log("texts!");
// console.log(texts);
for (let text of texts) {
// console.log(text.innerText);
console.log(text.outerText);
}
setTimeout(() => {
goBack(skip)
}, 500);
}, 2000)
}
}
function goBack(skip) {
window.history.back();
console.log("Going back!");
setTimeout(() => {
clickOnProfile(skip)
}, 3000);
}
})();
// HELP FUNCTIONS
function arrayToCSV(twoDiArray) {
var csvRows = [];
for (var i = 0; i < twoDiArray.length; ++i) {
for (var j = 0; j < twoDiArray[i].length; ++j) {
twoDiArray[i][j] = '\"' + twoDiArray[i][j] + '\"'; // Handle elements that contain commas
}
csvRows.push(twoDiArray[i].join(','));
}
var csvString = csvRows.join('\r\n');
return csvString;
}
function downloadString(text, fileType, fileName) {
var blob = new Blob([text], {type: fileType});
var a = document.createElement('a');
a.download = fileName;
a.href = URL.createObjectURL(blob);
a.dataset.downloadurl = [fileType, a.download, a.href].join(',');
a.style.display = "none";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(function () {
URL.revokeObjectURL(a.href);
}, 1500);
}
function capitalize(s) {
if (typeof s !== 'string') return '';
return s.charAt(0).toUpperCase() + s.slice(1)
}
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment