-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsnippet.js
More file actions
198 lines (193 loc) · 9.82 KB
/
snippet.js
File metadata and controls
198 lines (193 loc) · 9.82 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
Linkedin = {
config: {
scrollDelay: 1500,
actionDelay: 2500,
nextPageDelay: 2500,
// set to -1 for no limit
maxRequests: -1,
totalRequestsSent: 0,
// set to false to skip adding note in invites
addNote: true,
note: `Hi, I’m Dhruv. I’m a CS Undergrad with experience in Data Science and Dev roles. I was hoping to find a role in your organisation that would be a good fit. I’d appreciate if you could refer me. Resume Link: https://drive.google.com/file/d/1-R6GT0dh83n-4i7ywle7Vx8GjTCqYWjs/view?usp=sharing`,
addHeadlineFilter: true,
profileHeadlineKeywords: ["developer", "data", "analyst", "ceo", "cto"]
},
init: function (data, config) {
console.info("INFO: script initialized on the page...");
console.debug("DEBUG: scrolling to bottom in " + config.scrollDelay + " ms");
setTimeout(() => this.scrollBottom(data, config), config.actionDelay);
},
scrollBottom: function (data, config) {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
console.debug("DEBUG: scrolling to top in " + config.scrollDelay + " ms");
setTimeout(() => this.scrollTop(data, config), config.scrollDelay);
},
scrollTop: function (data, config){
window.scrollTo({ top: 0, behavior: 'smooth' });
console.debug("DEBUG: inspecting elements in " + config.scrollDelay + " ms");
setTimeout(() => this.inspect(data, config), config.scrollDelay);
},
inspect: function (data, config) {
var totalRows = this.totalRows();
console.debug("DEBUG: total search results found on page are " + totalRows);
if (totalRows >= 0) {
this.compile(data, config);
} else {
console.warn("WARN: end of search results!");
this.complete(config);
}
},
compile: function (data, config) {
var elements = document.querySelectorAll('button');
data.pageButtons = [...elements].filter(function (element) {
return element.textContent.trim() === "Connect";
});
if (!data.pageButtons || data.pageButtons.length === 0) {
console.warn("ERROR: no connect buttons found on page!");
console.info("INFO: moving to next page...");
setTimeout(() => { this.nextPage(config) }, config.nextPageDelay);
} else {
data.pageButtonTotal = data.pageButtons.length;
console.info("INFO: " + data.pageButtonTotal + " connect buttons found");
data.pageButtonIndex = 0;
data.connectNames = [...data.pageButtons].map(function (element) {
return element.parentNode.previousElementSibling.firstElementChild.children[1].children[0].textContent.trim();
});
data.profileHeadlines = [...data.pageButtons].map(function (element) {
return element.parentNode.previousElementSibling.firstElementChild.children[1].children[2].textContent.trim();
});
console.debug("DEBUG: starting to send invites in " + config.actionDelay + " ms");
setTimeout(() => { this.sendInvites(data, config) }, config.actionDelay);
}
},
sendInvites: function (data, config) {
// Check if profile headline contains any of the specified keywords
if (config.addHeadlineFilter && this.containsKeyword(data.profileHeadlines[data.pageButtonIndex], config.profileHeadlineKeywords)) {
console.debug("remaining requests " + config.maxRequests);
if (config.maxRequests == 0){
console.info("INFO: max requests reached for the script run!");
this.complete(config);
} else {
console.debug('DEBUG: sending invite to ' + (data.pageButtonIndex + 1) + ' out of ' + data.pageButtonTotal);
var button = data.pageButtons[data.pageButtonIndex];
button.click();
if (config.addNote && config.note) {
console.debug("DEBUG: clicking Add a note in popup, if present, in " + config.actionDelay + " ms");
setTimeout(() => this.clickAddNote(data, config), config.actionDelay);
} else {
console.debug("DEBUG: clicking done in popup, if present, in " + config.actionDelay + " ms");
setTimeout(() => this.clickDone(data, config), config.actionDelay);
}
}
}
else if (config.addHeadlineFilter) {
console.debug("DEBUG: profile headline doesn't match, skipping invite");
setTimeout(() => this.clickClose(data, config), config.actionDelay);
}
else {
console.debug("remaining requests " + config.maxRequests);
if (config.maxRequests == 0){
console.info("INFO: max requests reached for the script run!");
this.complete(config);
} else {
console.debug('DEBUG: sending invite to ' + (data.pageButtonIndex + 1) + ' out of ' + data.pageButtonTotal);
var button = data.pageButtons[data.pageButtonIndex];
button.click();
if (config.addNote && config.note) {
console.debug("DEBUG: clicking Add a note in popup, if present, in " + config.actionDelay + " ms");
setTimeout(() => this.clickAddNote(data, config), config.actionDelay);
} else {
console.debug("DEBUG: clicking done in popup, if present, in " + config.actionDelay + " ms");
setTimeout(() => this.clickDone(data, config), config.actionDelay);
}
}
}
},
containsKeyword: function (headline, keywords) {
headline = headline.toLowerCase();
for (var i = 0; i < keywords.length; i++) {
if (headline.includes(keywords[i].toLowerCase())) {
return true;
}
}
return false;
},
clickAddNote: function (data, config) {
var buttons = document.querySelectorAll('button');
var addNoteButton = Array.prototype.filter.call(buttons, function (el) {
return el.textContent.trim() === 'Add a note';
});
// adding note if required
if (addNoteButton && addNoteButton[0]) {
console.debug("DEBUG: clicking add a note button to paste note");
addNoteButton[0].click();
console.debug("DEBUG: pasting note in " + config.actionDelay);
setTimeout(() => this.pasteNote(data, config), config.actionDelay);
} else {
console.debug("DEBUG: add note button not found, clicking send on the popup in " + config.actionDelay);
setTimeout(() => this.clickDone(data, config), config.actionDelay);
}
},
pasteNote: function (data, config) {
noteTextBox = document.getElementById("custom-message");
noteTextBox.value = config.note.replace("{{name}}", data.connectNames[data.pageButtonIndex]);
noteTextBox.dispatchEvent(new Event('input', {
bubbles: true
}));
console.debug("DEBUG: clicking send in popup, if present, in " + config.actionDelay + " ms");
setTimeout(() => this.clickDone(data, config), config.actionDelay);
},
clickDone: function (data, config) {
var buttons = document.querySelectorAll('button');
var doneButton = Array.prototype.filter.call(buttons, function (el) {
return el.textContent.trim() === 'Send';
});
// Click the first send button
if (doneButton && doneButton[0]) {
console.debug("DEBUG: clicking send button to close popup");
doneButton[0].click();
} else {
console.debug("DEBUG: send button not found, clicking close on the popup in " + config.actionDelay);
}
setTimeout(() => this.clickClose(data, config), config.actionDelay);
},
clickClose: function (data, config) {
var closeButton = document.getElementsByClassName('artdeco-modal__dismiss artdeco-button artdeco-button--circle artdeco-button--muted artdeco-button--2 artdeco-button--tertiary ember-view');
if (closeButton && closeButton[0]) {
closeButton[0].click();
}
console.info('INFO: invite sent to ' + (data.pageButtonIndex + 1) + ' out of ' + data.pageButtonTotal);
config.maxRequests--;
config.totalRequestsSent++;
if (data.pageButtonIndex === (data.pageButtonTotal - 1)) {
console.debug("DEBUG: all connections for the page done, going to next page in " + config.actionDelay + " ms");
setTimeout(() => this.nextPage(config), config.actionDelay);
} else {
data.pageButtonIndex++;
console.debug("DEBUG: sending next invite in " + config.actionDelay + " ms");
setTimeout(() => this.sendInvites(data, config), config.actionDelay);
}
},
nextPage: function (config) {
var pagerButton = document.getElementsByClassName('artdeco-pagination__button--next');
if (!pagerButton || pagerButton.length === 0 || pagerButton[0].hasAttribute('disabled')) {
console.info("INFO: no next page button found!");
return this.complete(config);
}
console.info("INFO: Going to next page...");
pagerButton[0].children[0].click();
setTimeout(() => this.init({}, config), config.nextPageDelay);
},
complete: function (config) {
console.info('INFO: script completed after sending ' + config.totalRequestsSent + ' connection requests');
},
totalRows: function () {
var search_results = document.getElementsByClassName('search-result');
if (search_results && search_results.length != 0) {
return search_results.length;
} else {
return 0;
}
}
}
Linkedin.init({}, Linkedin.config);