{"id":13822024,"url":"https://github.com/PLhery/unfollowNinja","last_synced_at":"2025-05-16T15:32:18.744Z","repository":{"id":37285738,"uuid":"41703278","full_name":"PLhery/unfollowNinja","owner":"PLhery","description":"Get notified when your Twitter account loses a follower.","archived":false,"fork":false,"pushed_at":"2023-08-11T10:52:21.000Z","size":8125,"stargazers_count":219,"open_issues_count":10,"forks_count":23,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-11-08T02:41:11.837Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"https://unfollow.ninja","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PLhery.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-08-31T22:13:54.000Z","updated_at":"2024-10-27T20:47:24.000Z","dependencies_parsed_at":"2024-01-15T15:58:10.390Z","dependency_job_id":null,"html_url":"https://github.com/PLhery/unfollowNinja","commit_stats":null,"previous_names":["mrpointvirgule/unfollowninja"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLhery%2FunfollowNinja","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLhery%2FunfollowNinja/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLhery%2FunfollowNinja/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLhery%2FunfollowNinja/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PLhery","download_url":"https://codeload.github.com/PLhery/unfollowNinja/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225436441,"owners_count":17474146,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2024-08-04T08:01:38.598Z","updated_at":"2024-11-19T22:31:51.937Z","avatar_url":"https://github.com/PLhery.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Unfollow Ninja [![Server CI status](https://github.com/PLhery/unfollowNinja/workflows/Server%20CI/badge.svg)](https://github.com/PLhery/unfollowNinja/actions?query=workflow%3A%22Server+CI%22)\n\nGet notified when your Twitter account loses a follower\n\nUsed by ~500 000 Twitter users (11/2021)\n\n🇬🇧 https://unfollow-monkey.com\n🇫🇷 https://unfollow.ninja  \n\n![Screenshot](https://raw.githubusercontent.com/PLhery/unfollowNinja/master/unfollow-monkey-ui/public/preview.png)\n\n---\n\n**[Deprecated] This app was built mostly on top of Twitter API V1.1, which is now deprecated.**\n\n\n\nFeel free to reuse the UI on a personal server, but please don't reuse the name/logo on a public instance.\n\nIndeed, this software is under apache v2 license which means:\n\n- You need to aknowledge the use of this software and its license somewhere\n- A modified version can't have the same name\n\n## Build the UI\n\n- clone the repo `git clone git@github.com:PLhery/unfollowNinja.git`\n- `cd unfollowNinja/unfollow-monkey-ui`\n- change `api.unfollow-monkey.com` to you own server endpoints in ui/src/components/MiniApp.js\n- `npm install \u0026\u0026 npm start` to serve the UI in dev mode\n- `npm run build` to build the UI static files in the `build` folder.\n\nThen you can host it on github pages, amazon s3, netlify, your own nginx server...\n\n\n## Launch the server with docker-compose\n\n- clone the repo `git clone git@github.com:PLhery/unfollowNinja.git`\n- `cd unfollowNinja/unfollow-ninja-server`\n- create a .env file (see [.env file](#.env-file))\n- `docker-compose up  --build`\n\nThe server will be accessible on http://localhost:4000/  \n\nBy default, the db files and logs are stored in /data subfolders. Feel free to edit these, and the port/address in `docker-compose.yml`\n\n## Launch the server manually\n\n- clone the repo `git clone git@github.com:PLhery/unfollowNinja.git`\n- `cd unfollowNinja/unfollow-ninja-server`\n- install the dependencies and build the project `npm ci \u0026\u0026 npm build`\n- create a .env file (see [.env file](#.env-file))\n- install redis and optionally set a custom REDIS_URI + REDIS_BULL_URI in .env\n- launch the workers `node ./dist/api/workers`\n- launch the api server `node ./dist/api`\n- or launch both in the as a daemon with pm2 `pm2 start pm2.yml`\n\n## .env file\n\nTo get started, you'll need to create one or two twitter app https://developer.twitter.com/en/apps:  \n- One for the first step, which only need a read access, and a callback url = https://your-ui-url/1\n- One for the second step, which needs a DM sending access, and a callback url = https://your-ui-url/2\n- Both need to have sign in with twitter enabled\n\nThen you can create a .env in unfollow-ninja-server to set some parameters:\n\n```\n# your first step app API key and secret\nCONSUMER_KEY=xxx \nCONSUMER_SECRET=xxx\n# your second step app API key\nDM_CONSUMER_KEY=xxx\nDM_CONSUMER_SECRET=xxx # your second step app API secret key\n\n# Front-end URL (without any ending /)\nWEB_URL=https://unfollow.ninja\n\n# a secret key to sign cookies (ex. generate yours on https://password.new)\nCOOKIE_SIGNING_KEY=Kg8hfQoGj9GHjdKjsYqPtk6ShJqaoP\n\n# optionally:\n\n# -- The twitter account quoted in the notifications (ex. welcome to @[TWITTER_ACCOUNT]!)\nTWITTER_ACCOUNT=unfollowninja\n\n# -- The timezone use for follow time. ex: Europe/Paris\nTIMEZONE=UTC \n\n# -- Default language for the notifications (for new users).\nDEFAULT_LANGUAGE=en\n\n# -- Number of workers, defaults to number of CPUs\nCLUSTER_SIZE=2\n# -- Number of unique tasks managed at the same time, defaults to 15\nWORKER_RATE_LIMIT=15\n\n# -- When this twitter user is logged in, it has access to the /admin/user/[username] debug enpoint\nADMIN_USERID=\n\n# -- Sentry (API) DSN, if you want to report workers (or API) errors on sentry\nSENTRY_DSN=\nSENTRY_DSN_API=\n\n# -- If you set these variables, the server will send some metrics to these statsd / datadog servers\nSTATSD_HOST=\nDD_AGENT_HOST=\n# -- The metrics will start with this prefix (ex metric: [prefix].check-duration.worker.[cluster-nb])\nMETRICS_PREFIX=uninja\n```\n\nYou can also set these parameters as environment variables.\n\n## Contribute\n\nOpen an issue with your suggestions or assign yourself to an existing issue\n\n### Translate the app to your language\n\nYou can help to translate the app on https://hosted.weblate.org/projects/unfollow-monkey/notifications/\n\nWeblate will automatically open a PR to update or add the language in this repository.\n\n## Motivation behind improving the legacy version\n\nLegacy version: https://github.com/PLhery/unfollowNinja/tree/legacy\n\nThe legacy version couldn't scale and manage thousands of users, while still checking every 2 minutes the followers.\nNow, the program checks 100 000 users's followers in about 3 minutes with 12 cpus.\n\n- Based on a job queue for:\n    - Monitoring: I can see how many jobs/sec are happening, their errors, and rate limit them.\n    - Scalability: Everything was happening in one thread. Now the work is shared between 8 workers/vCPUs.\n    - Atomicity: When the server restart, wait for every atomic job to finish instead of interrupting them. (causing messages not sent or sent twice)\n    - Reliability: If a job fails, prepare better retry strategies.\n- Use Typescript to make code more bug-proof and clearer for contributors\n- Split the webserver from the worker: When the worker was busy, the webserver was slow because everything was happening in the same thread.\n- Use redis to store the list of followers as we need to read/write them really often/quickly\n- I18n\n- Use twitter's SnowFlake IDs to get the exact follow time\n- New UI\n\n# Licensing\n\n[License](./license.md) (Apache V2)\n\nUnfollowNinja uses multiple open-source projects:\n\n#### Twemoji\n\nCopyright 2020 Twitter, Inc and other contributors  \nCode licensed under the MIT License: http://opensource.org/licenses/MIT  \nGraphics licensed under CC-BY 4.0: https://creativecommons.org/licenses/by/4.0/","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPLhery%2FunfollowNinja","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPLhery%2FunfollowNinja","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPLhery%2FunfollowNinja/lists"}