-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
155 lines (136 loc) · 4.98 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
const puppeteer = require('puppeteer');
const express = require('express');
const path = require('path');
const app = express();
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
let searchResults = {};
app.get('/logo.png', function(req, res) {
res.sendFile(__dirname + "/logo.png");
});
app.get('/favicon.ico', function(req, res) {
res.sendFile(__dirname + "/favicon.ico");
});
app.get('/bg.jpg', function(req, res) {
res.sendFile(__dirname + "/bg.jpg");
});
app.get('/master.css', function(req, res) {
res.sendFile(__dirname + "/master.css");
});
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/api/searchConnections/:skill', async (req, res) => {
var skill = req.params.skill;
getLinkedInConnections(skill, false, (result) => {
console.log(result); // "Some User token"
res.json(result);
});
})
app.post('/api/sendMessage/:skill', async (req, res) => {
var skill = req.params.skill;
console.log(req.body);
var linkedInMsg = req.body.msg;
var name = req.body.name;
console.log(linkedInMsg);
getLinkedInConnections(skill, true, (result) => {
res.json(req.body);
}, name, linkedInMsg);
})
app.listen(3000, console.log('Listening on port 3000...'));
async function getLinkedInConnections(keyword, sendMsg, callback, name, msg) {
const wsChromeEndpointurl = 'ws://127.0.0.1:9222/devtools/browser/29f61f48-65dc-4480-8882-4f32cafc4258';
const browser = await puppeteer.connect({
browserWSEndpoint: wsChromeEndpointurl,
headless: true
});
const page = await browser.newPage();
const url = 'https://www.linkedin.com/search/results/people/?facetNetwork=%5B%22F%22%5D&keywords=' + keyword + '&origin=FACETED_SEARCH';
await page.goto(url, {
});
await page.setViewport({
width: 1200,
height: 800
});
await autoScroll(page);
await page.waitForFunction(
'document.querySelector("body").innerText.includes("Try searching for")'
);
await buildObjectFromElements(page, callback);
if (sendMsg) {
await sendMessage(page, name, msg, false, callback);
}
}
async function sendMessage(page, name, msg, confirm, callback) {
console.log(msg);
let elements = await page.$$('.message-anywhere-button');
await elements.map(async (element) => {
const outerHtml = await page.evaluate(element => element.outerHTML, element);
if (outerHtml.indexOf(name) > -1){
await element.click();
console.log(msg);
await page.type('.msg-form__contenteditable', msg , {delay: 20})
if (confirm) {
await page.keyboard.press('Enter');
}
}
});
}
async function buildObjectFromElements(page, callback) {
let userSearchResults = [];
let counter = 0;
let elements = await page.$$('.search-result__info');
console.log(elements);
await elements.map(async (element) => {
console.log(element);
let properties = {};
let names = await element.$$(".actor-name");
properties.name = await parseTextElement(page, names);
let curTitles = await element.$$('.subline-level-1');
properties.curTitle = await parseTextElement(page, curTitles);
let locations = await element.$$('.subline-level-2');
properties.location = await parseTextElement(page, locations);
let profileSnippets = await element.$$('.search-result__snippets');
properties.profileSnippet = await parseTextElement(page, profileSnippets);
let keyName = await transformToKey(properties.name);
let userObj = {};
userObj[keyName] = properties;
userSearchResults.push(userObj);
counter += 1;
if (counter == elements.length) {
callback({"searchResults" : userSearchResults});
}
});
}
async function autoScroll(page){
await page.evaluate(async () => {
await new Promise((resolve, reject) => {
var totalHeight = 0;
var distance = 100;
var timer = setInterval(() => {
var scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
if(totalHeight >= scrollHeight){
clearInterval(timer);
resolve();
}
}, 100);
});
});
}
async function transformToKey(text) {
return (text.replace(/\s/g, '')).toLowerCase();
}
async function parseTextElement(page, elements) {
if (page && elements.length > 0) {
let element = elements[0];
const text = await page.evaluate(element => element.textContent, element);
return text ? sanitizeText(text) : "";
}
return "";
}
async function sanitizeText(text) {
return (text.replace(/(\r\n|\n|\r)/gm,"")).trim();
}