Skip to content

Commit 00c3c92

Browse files
authored
Twitter followers overlap (HarshCasper#1007)
* initial setup * twitter functions added * pseudo code * functions initialized * printLongArray func added * overlap followers function done * minor changes * Readme added * readme updated
1 parent f2625a2 commit 00c3c92

File tree

7 files changed

+357
-1
lines changed

7 files changed

+357
-1
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,4 @@ chromedriver.exe
300300
node_modules
301301

302302
#Twitter_Unfollowers
303-
db.json
303+
db.json
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Twitter_Followers_Overlap
2+
3+
**Twitter_Followers_Overlap** a script to list the followers that are common between two twitter users.
4+
- It uses Twitter API to fetch followers of any user *(provided as input)*.
5+
- Then compares them to give names of people that are common between both the users.
6+
7+
## Setup instructions
8+
9+
- Get your [Twitter developer account](https://developer.twitter.com/en) and follow the steps there to generate your **bearer key**
10+
- In a file named `apiTokens.js` in the Twitter_Followers_Overlap folder, enter your bearer key : ![File content](https://i.imgur.com/qGWVd7h.png)
11+
- Open terminal and do the following :
12+
- `cd Rotten-Scripts\JavaScript\Twitter_Followers_Overlap`
13+
- Run `npm install` to install all necessary dependencies
14+
- Run `node Twitter_Followers_Overlap.js` and Voila! you are ready to go 😉
15+
16+
## Output
17+
18+
![Output Pic](https://i.imgur.com/9klb2d9.png)
19+
20+
## Author(s)
21+
22+
Hi I'm [Madhav Jha](https://github.jhamadhav.com) author of this script.
23+
24+
## Disclaimer
25+
26+
- **DO NOT forget to get your bearer key from your [Twitter developer account](https://developer.twitter.com/en) and ALWAYS keep it a SECRET!!!**
27+
- **Do not try for accounts with followers count more than few thousands, even though the script works you will exhaust your twitter API limit before the process ends.**
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
exports.data = {
2+
"bearer": "Enter your bearer key here"
3+
}

JavaScript/Twitter_Followers_Overlap/package-lock.json

Lines changed: 158 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "twitter_followers_overlap",
3+
"version": "1.0.0",
4+
"description": "A script to list the followers that are common between two twitter users.",
5+
"main": "twitter_followers_overlap.js",
6+
"scripts": {
7+
"twitter_followers_overlap_run": "node twitter_followers_overlap.js"
8+
},
9+
"author": "Madhav Jha",
10+
"license": "ISC",
11+
"dependencies": {
12+
"needle": "^2.6.0",
13+
"prompt-sync": "^4.2.0"
14+
}
15+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
const needle = require('needle');
2+
const api = require("./apiTokens")
3+
4+
const bearerToken = api.data.bearer;
5+
6+
const getUserId = async (username) => {
7+
let endpointURL = "https://api.twitter.com/2/users/by?usernames="
8+
const params = {
9+
usernames: `${username}`,
10+
"expansions": "pinned_tweet_id"
11+
}
12+
13+
// this is the HTTP header that adds bearer token authentication
14+
const res = await needle('get', endpointURL, params, {
15+
headers: {
16+
"User-Agent": "v2UserLookupJS",
17+
"authorization": `Bearer ${bearerToken}`
18+
}
19+
})
20+
21+
if (res.body) {
22+
return res.body;
23+
} else {
24+
throw new Error('Unsuccessful request')
25+
}
26+
}
27+
const getFollowers = async (userId) => {
28+
let url = `https://api.twitter.com/2/users/${userId}/followers`;
29+
let users = [];
30+
let params = {
31+
"max_results": 1000
32+
}
33+
34+
const options = {
35+
headers: {
36+
"User-Agent": "v2FollowersJS",
37+
"authorization": `Bearer ${bearerToken}`
38+
}
39+
}
40+
41+
let hasNextPage = true;
42+
let nextToken = null;
43+
44+
while (hasNextPage) {
45+
let resp = await getPage(params, options, nextToken, url);
46+
if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) {
47+
if (resp.data) {
48+
users.push.apply(users, resp.data);
49+
}
50+
if (resp.meta.next_token) {
51+
nextToken = resp.meta.next_token;
52+
} else {
53+
hasNextPage = false;
54+
}
55+
} else {
56+
hasNextPage = false;
57+
}
58+
}
59+
60+
return users
61+
}
62+
63+
const getPage = async (params, options, nextToken, url) => {
64+
if (nextToken) {
65+
params.next_token = nextToken;
66+
}
67+
68+
try {
69+
const resp = await needle('get', url, params, options);
70+
71+
if (resp.statusCode != 200) {
72+
console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`);
73+
return;
74+
}
75+
return resp.body;
76+
} catch (err) {
77+
throw new Error(`Request failed: ${err}`);
78+
}
79+
}
80+
module.exports = { getUserId, getFollowers };
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const prompt = require("prompt-sync")();
2+
const twt = require("./twitterFunc")
3+
4+
const printLongArray = (arr, step = 100) => {
5+
if (arr.length <= 0) {
6+
return 0;
7+
}
8+
let start = 0, end = 0;
9+
end = Math.min(step, arr.length);
10+
11+
let userInp = prompt(`Do you want to see list from ${start} to ${end} (y/n): `) || "n"
12+
while (userInp == "y" && end <= arr.length && start != end) {
13+
subArr = arr.slice(start, end)
14+
console.table(subArr)
15+
start = end;
16+
end = Math.min(end + step, arr.length)
17+
if (start == end) {
18+
break;
19+
}
20+
userInp = prompt(`Do you want to see list from ${start} to ${end} (y/n): `) || "n"
21+
}
22+
}
23+
24+
const getOverlappingFollowers = (arr1, arr2) => {
25+
let arr1IDs = arr1.map(user => user.id);
26+
let arr2IDs = arr2.map(user => user.id);
27+
let overlap = []
28+
let overlapIDs = []
29+
30+
// from arr1IDs -> arr2IDs
31+
for (let i = 0; i < arr1IDs.length; i++) {
32+
if (arr2IDs.indexOf(arr1IDs[i]) != -1 && overlapIDs.indexOf(arr1IDs[i]) == -1) {
33+
overlapIDs.push(arr1IDs[i])
34+
overlap.push(arr1[i]);
35+
}
36+
};
37+
38+
// from arr2IDs -> arr1IDs
39+
for (let i = 0; i < arr2IDs.length; i++) {
40+
if (arr1IDs.indexOf(arr2IDs[i]) != -1 && overlapIDs.indexOf(arr2IDs[i]) == -1) {
41+
overlapIDs.push(arr2IDs[i])
42+
overlap.push(arr2[i]);
43+
}
44+
};
45+
return overlap;
46+
}
47+
48+
const init = async () => {
49+
console.log("\n===============================");
50+
console.log("---Twitter Followers Overlap---");
51+
console.log("===============================\n");
52+
53+
let user1 = prompt("Enter first username : ");
54+
let user2 = prompt("Enter second username : ");
55+
56+
console.log("\nFetching...Data....Please..Wait...!\n");
57+
58+
let user1ID = await twt.getUserId(user1)
59+
let user2ID = await twt.getUserId(user2)
60+
61+
let user1Followers = await twt.getFollowers(user1ID["data"][0].id);
62+
let user2Followers = await twt.getFollowers(user2ID["data"][0].id);
63+
64+
let overlapFollowers = getOverlappingFollowers(user1Followers, user2Followers);
65+
66+
console.log(`There are ${overlapFollowers.length} Overlapping followers!!! \n`);
67+
printLongArray(overlapFollowers);
68+
console.log("\n---END---\n");
69+
70+
}
71+
72+
// entry function
73+
init()

0 commit comments

Comments
 (0)