From 9542e414f26fa8b366245bdccf63050630ca021f Mon Sep 17 00:00:00 2001 From: Jagruti Date: Sat, 12 Mar 2022 09:26:53 +0530 Subject: [PATCH 1/3] Script to npm package files --- NPM_conversion/JavaScript/twitter_unfollowers | 1 + 1 file changed, 1 insertion(+) create mode 160000 NPM_conversion/JavaScript/twitter_unfollowers diff --git a/NPM_conversion/JavaScript/twitter_unfollowers b/NPM_conversion/JavaScript/twitter_unfollowers new file mode 160000 index 000000000..73ae70d21 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers @@ -0,0 +1 @@ +Subproject commit 73ae70d2136a5adf9a81992330902aafb374b5c0 From 5782b6c014c62d8ab14aede18efa8c34de20f7f8 Mon Sep 17 00:00:00 2001 From: Jagruti Date: Sat, 12 Mar 2022 10:08:28 +0530 Subject: [PATCH 2/3] Files used to converting --- NPM_conversion/JavaScript/twitter_unfollowers | 1 - .../JavaScript/twitter_unfollowers/README.md | 29 +++++ .../twitter_unfollowers/apiTokens.js | 3 + .../JavaScript/twitter_unfollowers/app.js | 114 ++++++++++++++++++ .../JavaScript/twitter_unfollowers/dbFunc.js | 23 ++++ .../twitter_unfollowers/package-lock.json | 28 +++++ .../twitter_unfollowers/package.json | 25 ++++ .../twitter_unfollowers/twitterFunc.js | 76 ++++++++++++ 8 files changed, 298 insertions(+), 1 deletion(-) delete mode 160000 NPM_conversion/JavaScript/twitter_unfollowers create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/README.md create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/apiTokens.js create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/app.js create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/dbFunc.js create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/package-lock.json create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/package.json create mode 100644 NPM_conversion/JavaScript/twitter_unfollowers/twitterFunc.js diff --git a/NPM_conversion/JavaScript/twitter_unfollowers b/NPM_conversion/JavaScript/twitter_unfollowers deleted file mode 160000 index 73ae70d21..000000000 --- a/NPM_conversion/JavaScript/twitter_unfollowers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 73ae70d2136a5adf9a81992330902aafb374b5c0 diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/README.md b/NPM_conversion/JavaScript/twitter_unfollowers/README.md new file mode 100644 index 000000000..7ef67c557 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/README.md @@ -0,0 +1,29 @@ +# Twitter_Unfollowers + +**Twitter_Unfollowers** is a script to track people that recently unfollowed you on Twitter. +- It uses Twitter API to fetch followers of any user *(provided as input)*. +- Then stores it into a `json` file. +- When compared again it gives name and number of people that unfollowed. +- *(Additionally) :* After multiple queries it provides search/query history in tabular form. + +## Setup instructions + +- Get your [Twitter developer account](https://developer.twitter.com/en) and follow the steps there to generate your **bearer key** +- In a file named `apiTokens.js` in the Twitter_Unfollowers folder, enter your bearer key : ![File content](https://i.imgur.com/4UlveGE.png) +- Open terminal and do the following : +- `cd Rotten-Scripts\JavaScript\Twitter_unfollowers` +- Run `npm install` to install all necessary dependencies +- Run `node Twitter_Unfollowers.js` and Voila! you are ready to go 😉 + +## Output + +![Output Pic](https://i.imgur.com/HQ68vDj.png) + +## Author(s) + +Hi I'm [Madhav Jha](https://github.jhamadhav.com) author of this script. + +## Disclaimer + +- **DO NOT forget to get your bearer key from your [Twitter developer account](https://developer.twitter.com/en) and ALWAYS keep it a SECRET!!!** +- **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.** diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/apiTokens.js b/NPM_conversion/JavaScript/twitter_unfollowers/apiTokens.js new file mode 100644 index 000000000..bdbfe1e37 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/apiTokens.js @@ -0,0 +1,3 @@ +exports.data = { + "bearer": "Paste your bearer key here!" +} \ No newline at end of file diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/app.js b/NPM_conversion/JavaScript/twitter_unfollowers/app.js new file mode 100644 index 000000000..f9f240d68 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/app.js @@ -0,0 +1,114 @@ +const prompt = require("prompt-sync")(); +const db = require("./dbFunc") +const api = require("./apiTokens") +const twt = require("./twitterFunc") +const dbFileLoc = "db.json"; + +// api data +const bearerToken = api.data.bearer; + +const getUserData = async (username) => { + let user = new Object(); + user.name = username; + let res = await twt.getUserId(user.name, bearerToken) + user.id = res.data[0].id; + user.followers = await twt.getFollowers(user.id, bearerToken); + return user; +} + +const displayUser = (user) => { + console.log("\nUser Info :"); + console.log(`Username : ${user.name} \nuserID : ${user.id}`); +} + +const getUnfollowers = (current, fromDB) => { + // separate usernames from the json array using map + tempCurrent = current.map((user) => { + return user.name; + }) + tempFromDB = fromDB.map((user) => { + return user.name; + }) + + // new list to store users that have unfollowed the user + let unfollows = []; + tempFromDB.forEach(user => { + if (tempCurrent.indexOf(user) == -1) { + unfollows.push(user); + } + }); + + return unfollows; +} + +const getDate = () => { + let d = new Date(); + return `${d.getDate()}/${d.getMonth() + 1}/${d.getFullYear()}` +} + +const updateDB = (dbData, currentData, unfollows) => { + + // assign current new user followers changes to db + dbData[currentData.name]["followers"] = currentData["followers"]; + if (unfollows > 0) { + let d = getDate(); + let newCheck = { + "On-Date": d, + "People-unfollowed": unfollows + } + // update time + dbData[currentData.name].time = d; + // make history of checking + dbData[currentData.name]["history"].push(newCheck); + } + // write the data into the db + db.write(dbFileLoc, dbData); + return dbData; +} +const init = async () => { + + let username = prompt("Enter Twitter Username : "); //this info will be taken through input + let user = await getUserData(username) + let dbData = db.read(dbFileLoc); + dbData = (dbData === "" || dbData.length == 0) ? "{}" : dbData; + dbData = JSON.parse(dbData); + + if (Object.prototype.hasOwnProperty.call(dbData, user.name)) { + // display basic info + displayUser(user); + + // get list of people that have unfollowed you + let people = getUnfollowers(user.followers, dbData[user.name]["followers"]); + + // displaying their number + console.log(`\nNOTE : ${people.length} people unfollowed you(him/her) After ${dbData[user.name].time}`); + + // display their names + if (people.length > 0) { + console.log(`\nThose are(is) : `); + console.table(people); + } + + // to update the db with new data + dbData = updateDB(dbData, user, people.length); + + if (dbData[user.name]["history"].length > 0) { + console.log(`\Query history is as follows :`); + console.table(dbData[user.name]["history"]); + } + } else { + + // assign current new user to db + dbData[user.name] = user; + // add date of addition + dbData[user.name].time = getDate(); + // make history of checking + dbData[user.name].history = []; + // write the data into the db + db.write(dbFileLoc, dbData); + + // inform us about the user not being in the db + console.log("\nNOTE : User didn't exist! Now it has been added to DB.\nCheck after some time!!!"); + } +} +init(); diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/dbFunc.js b/NPM_conversion/JavaScript/twitter_unfollowers/dbFunc.js new file mode 100644 index 000000000..45b657834 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/dbFunc.js @@ -0,0 +1,23 @@ +const fs = require('fs') +const read = (fileName) => { + if (!fs.existsSync(fileName)) { + write(fileName, {}); + return "{}"; + } + return fs.readFileSync(fileName, 'utf-8', (err, data) => { + if (err) { + throw err; + } + + return data; + }); +} +const write = (fileName, data) => { + fs.writeFile(fileName, JSON.stringify(data), (err) => { + if (err) { + throw err; + } + }); +} + +module.exports = { read, write } diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/package-lock.json b/NPM_conversion/JavaScript/twitter_unfollowers/package-lock.json new file mode 100644 index 000000000..e2af83e28 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "twitter-unfollowers", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "twitter-unfollowers", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "twitter-unfollowers": "^1.0.0" + } + }, + "node_modules/twitter-unfollowers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/twitter-unfollowers/-/twitter-unfollowers-1.0.0.tgz", + "integrity": "sha512-OOz8gHI2XlY53dYg6q0lN/YrPr/AZSPSC85wBCNhQ6tKC0034vmwhOKaguvsTKHN6P3vHoBJBea98qJK9h8Ulw==" + } + }, + "dependencies": { + "twitter-unfollowers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/twitter-unfollowers/-/twitter-unfollowers-1.0.0.tgz", + "integrity": "sha512-OOz8gHI2XlY53dYg6q0lN/YrPr/AZSPSC85wBCNhQ6tKC0034vmwhOKaguvsTKHN6P3vHoBJBea98qJK9h8Ulw==" + } + } +} diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/package.json b/NPM_conversion/JavaScript/twitter_unfollowers/package.json new file mode 100644 index 000000000..32e071f96 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/package.json @@ -0,0 +1,25 @@ +{ + "name": "twitter-unfollowers", + "version": "1.0.0", + "description": "Displays a list of users unfollowed a Twitter account.", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/HarshCasper/Rotten-Scripts.git" + }, + "keywords": [ + "twitter" + ], + "author": "jagruti tiwari (https://github.com/HarshCasper/Rotten-Scripts)", + "license": "MIT", + "bugs": { + "url": "https://github.com/HarshCasper/Rotten-Scripts/issues" + }, + "homepage": "https://github.com/HarshCasper/Rotten-Scripts#readme", + "dependencies": { + "twitter-unfollowers": "^1.0.0" + } +} diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/twitterFunc.js b/NPM_conversion/JavaScript/twitter_unfollowers/twitterFunc.js new file mode 100644 index 000000000..3dd50e705 --- /dev/null +++ b/NPM_conversion/JavaScript/twitter_unfollowers/twitterFunc.js @@ -0,0 +1,76 @@ +const needle = require('needle'); +const getUserId = async (username, bearerToken) => { + let endpointURL = "https://api.twitter.com/2/users/by?usernames=" + const params = { + usernames: `${username}`, + "expansions": "pinned_tweet_id" + } + + // this is the HTTP header that adds bearer token authentication + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2UserLookupJS", + "authorization": `Bearer ${bearerToken}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request') + } +} +const getFollowers = async (userId, bearerToken) => { + let url = `https://api.twitter.com/2/users/${userId}/followers`; + let users = []; + let params = { + "max_results": 1000 + } + + const options = { + headers: { + "User-Agent": "v2FollowersJS", + "authorization": `Bearer ${bearerToken}` + } + } + + let hasNextPage = true; + let nextToken = null; + + while (hasNextPage) { + let resp = await getPage(params, options, nextToken, url); + if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { + if (resp.data) { + users.push.apply(users, resp.data); + } + if (resp.meta.next_token) { + nextToken = resp.meta.next_token; + } else { + hasNextPage = false; + } + } else { + hasNextPage = false; + } + } + + return users +} + +const getPage = async (params, options, nextToken, url) => { + if (nextToken) { + params.next_token = nextToken; + } + + try { + const resp = await needle('get', url, params, options); + + if (resp.statusCode != 200) { + console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); + return; + } + return resp.body; + } catch (err) { + throw new Error(`Request failed: ${err}`); + } +} +module.exports = { getUserId, getFollowers }; From dd677b4686074ebfb65902827711427725ebf5ca Mon Sep 17 00:00:00 2001 From: Jagruti Date: Mon, 14 Mar 2022 19:10:25 +0530 Subject: [PATCH 3/3] Adding new changes to the package --- .../JavaScript/twitter_unfollowers/app.js | 31 +++++++++++++------ .../twitter_unfollowers/package.json | 13 ++++++-- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/app.js b/NPM_conversion/JavaScript/twitter_unfollowers/app.js index f9f240d68..3bcbb8259 100644 --- a/NPM_conversion/JavaScript/twitter_unfollowers/app.js +++ b/NPM_conversion/JavaScript/twitter_unfollowers/app.js @@ -5,15 +5,26 @@ const twt = require("./twitterFunc") const dbFileLoc = "db.json"; // api data -const bearerToken = api.data.bearer; - -const getUserData = async (username) => { - let user = new Object(); - user.name = username; - let res = await twt.getUserId(user.name, bearerToken) - user.id = res.data[0].id; - user.followers = await twt.getFollowers(user.id, bearerToken); - return user; +var bearerToken = api.data.bearer; + +const getUserData = async (username, t) => { + + try{ + let user = new Object(); + user.name = username; + let res = await twt.getUserId(user.name, bearerToken) + user.id = res.data[0].id; + user.followers = await twt.getFollowers(user.id, bearerToken); + return user; + + }catch (error) { + console.error(error); + } + +} + +const setUserBearerKey = async(bearerKey) => { + bearerToken=bearerKey; } const displayUser = (user) => { @@ -67,6 +78,8 @@ const updateDB = (dbData, currentData, unfollows) => { } const init = async () => { + let userBearerToken = prompt("Enter Bearer Token : "); + let token = await setUserBearerKey(userBearerToken); let username = prompt("Enter Twitter Username : "); //this info will be taken through input let user = await getUserData(username) let dbData = db.read(dbFileLoc); diff --git a/NPM_conversion/JavaScript/twitter_unfollowers/package.json b/NPM_conversion/JavaScript/twitter_unfollowers/package.json index 32e071f96..ec933092a 100644 --- a/NPM_conversion/JavaScript/twitter_unfollowers/package.json +++ b/NPM_conversion/JavaScript/twitter_unfollowers/package.json @@ -1,6 +1,6 @@ { "name": "twitter-unfollowers", - "version": "1.0.0", + "version": "1.0.1", "description": "Displays a list of users unfollowed a Twitter account.", "main": "app.js", "scripts": { @@ -11,7 +11,11 @@ "url": "git+https://github.com/HarshCasper/Rotten-Scripts.git" }, "keywords": [ - "twitter" + "twitter", + "twitter-api", + "twitter-utility", + "unfollowers", + "api" ], "author": "jagruti tiwari (https://github.com/HarshCasper/Rotten-Scripts)", "license": "MIT", @@ -20,6 +24,9 @@ }, "homepage": "https://github.com/HarshCasper/Rotten-Scripts#readme", "dependencies": { - "twitter-unfollowers": "^1.0.0" + "twitter-unfollowers": "^1.0.0", + "needle": "^2.6.0", + "prompt-sync": "^4.2.0" + } }