-
-
Save simonw/848a3b91169a789bc084a459aa7ecf83 to your computer and use it in GitHub Desktop.
| # /// script | |
| # dependencies = [ | |
| # "atproto" | |
| # ] | |
| # /// | |
| from atproto import Client | |
| import getpass | |
| import time | |
| def follow_user_follows(client, target_user): | |
| "Follow everyone the target_user is following." | |
| cursor = None | |
| total_followed = 0 | |
| while True: | |
| # Step 1: Fetch a batch of accounts the target user is following | |
| # https://docs.bsky.app/docs/api/app-bsky-graph-get-follows | |
| response = client.app.bsky.graph.get_follows( | |
| {"actor": target_user, "limit": 100, "cursor": cursor} | |
| ) | |
| # Step 2: Iterate through the accounts | |
| for follow in response.follows: | |
| try: | |
| # Step 3: Follow each account | |
| client.follow(follow.did) | |
| print(f"Following {follow.handle}") | |
| total_followed += 1 | |
| # Step 4: Add a delay to respect rate limits | |
| time.sleep(2) | |
| except Exception as e: | |
| print(f"Error following {follow.handle}: {str(e)}") | |
| # Step 5: Check for more accounts to follow | |
| if not response.cursor: | |
| break | |
| cursor = response.cursor | |
| # Step 6: Print progress | |
| print(f"Followed {total_followed} users so far") | |
| # Step 7: Print final result | |
| print(f"Finished following {total_followed} users") | |
| if __name__ == "__main__": | |
| # Step 8: Set up credentials | |
| USERNAME = input("your_username.bsky.social ") | |
| APP_PASSWORD = getpass.getpass("your_app_password ") | |
| TARGET_USER = input("target_user.bsky.social ") | |
| # Step 9: Initialize and authenticate client | |
| client = Client() | |
| client.login(USERNAME, APP_PASSWORD) | |
| # Step 10: Execute the follow process | |
| follow_user_follows(client, TARGET_USER) |
To clarify: this is a fork of the original script by Hamel here: https://gist.github.com/hamelsmu/fb9ed633de7d784619e4b6da5039e6ae
I added the inline dependency metadata and the input() and getpass() bits.
You can see the changes I made here, I also ran it through Black: https://gist.github.com/simonw/848a3b91169a789bc084a459aa7ecf83/revisions
This skips the actual following:
# Step 2: Iterate through the accounts
for follow in response.follows:
print(follow)
continue # never follows
try:
...This skips the actual following:
Oops! Fixed that now, thanks.
One small suggestion: it might be worth mentioning in the README that users should create a Bluesky App Password before running the script.
I initially misunderstood the prompt and entered the name of my app password instead of my Bluesky handle, then got a 401 AuthenticationRequired error. It also wasn't immediately obvious to me where to create an App Password.
A short note like "Go to Settings → Privacy & Security → App Passwords and create an App Password for this script (don't use your main account password)" could save first-time users a bit of confusion.
Uh oh!
There was an error while loading. Please reload this page.