Created
July 31, 2019 15:21
-
-
Save ronaldluc/2adbad3703e9a61a7e584f0b30afd07f to your computer and use it in GitHub Desktop.
victor_violates_GDPR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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