Skip to content

Instantly share code, notes, and snippets.

@sts10
Last active October 25, 2018 17:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sts10/e811765393c391b81d1257bb2c59714a to your computer and use it in GitHub Desktop.
Save sts10/e811765393c391b81d1257bb2c59714a to your computer and use it in GitHub Desktop.
A Ruby script that's (trying to) find moved accounts for you to follow

Find Lost Fediverse Friends

Purpose

The goal of this Ruby script is to parse the Mastodon accounts you follow in search of accounts that: (a) Have moved, and (b) where you don't follow the new ("moved') accounts.

It then asks you if you want to follow each of those "moved" accounts that you don't follow. If user responds "yes", you can follow them!

How do I run it?

If you don't already have Ruby installed, you'll have to download it and install an up-to-date version, like 2.5.1. Then you'll need to install a Ruby gem called mastodon-api (you can do this by running gem install mastodon-api in the terminal from the command line).

Next, download (or copy and paste) the masto_following_updater.rb file on to to your computer.

Back in the terminal, run ruby masto_following_updater.rb while in the same directory as the file. You should then be prompted for a couple pieces of information, which I explain a bit below.

Information the program will ask for

In order to check your follows to see if they've moved, this program is going to need some information from you.

  1. Your instance's base URL. For example, https://mastodon.social or https://octodon.social

  2. An access token from a Mastodon application. To get this, on your Mastodon account, in the web interface, go to Settings > Development and create a new app. Give the app permission to "read all your account data", "see your follows", and "follow people".

  3. A spreadsheet of all the accounts you currently follow. To get this, again in the web interface of your Mastodon account, go to Settings > "Data export" and click the "CSV" link next to "You follow". This will download a spreadsheet on to your computer. The program will ask where this local file is stored.

After it gets those three pieces of information, the script should start churning through your follows. It takes some time, but eventually it (may) find some accounts for you to follow or not.

Good luck! If you run into problems, leave a comment here or reach out on Mastodon.

Troubleshooting

If you have a Ruby gem called "mastodon" and "mastodon-api" installed, you'll get an error. Run gem uninstall mastodon && gem install mastodon-api and try again.

Proof of concept?

This is also a bit of a proof of concept for a feature to (ideally) be built into Mastodon as a button in the Setting UI that explains "Find users you've followed that have moved" and then asks if they'd like to follow their new accounts.

Obviously, implementing this at scale in Mastodon's code would be way more difficult than this script.

Note that there are already two Github issues about this: #6955 and, more broadly, #177

Other notes

If you're looking for a tool to help you move fediverse accounts, check out Migrannounce, a "tool lets you message each of your followers so you can tell them you moved elsewhere."

License

The MIT License (MIT)

Copyright (c) 2018 Sam Schlinkert

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

require 'mastodon'
require 'csv'
system("clear")
puts "Welcome to the Mastodon Following Updater!"
puts "\n"
puts "First, enter the URL of your home instance. For example, https://mastodon.social or https://octodon.social"
base_url = gets.chomp
system("clear")
puts "Cool. Now I'm going to need you to create a Mastodon \"Application\"."
puts "\n"
puts "To do this, in the Mastodon web interface, go to Settings > Development and create a new app. Be sure to give the app permission to \"read all your account data\", \"see your follows\", and \"follow people\"."
puts "\n"
puts "Once you've done that, click into the Application and copy the long string that's labeled \"Your access token\". (It should be the thired one down)."
puts "Paste that long string here."
access_token = gets.chomp
client = Mastodon::REST::Client.new(base_url: base_url, bearer_token: access_token)
class Account
attr_reader :id, :url, :moved, :moved_id, :moved_url
def initialize(account_response)
@id = account_response.attributes['id']
@url = account_response.attributes['url']
@moved = account_response.attributes['moved'] != nil
if @moved
@moved_id = account_response.attributes['moved']['id']
@moved_url = account_response.attributes['moved']['url']
else
@moved_id = nil
@moved_url = nil
end
end
end
my_id = client.verify_credentials.attributes['id'].to_i # my id is 2439
system("clear")
puts "We're chugging right along!"
puts "\n"
puts "Last thing: I need a CSV (or spreadsheet) of the account you follow, so I can check if they're moved."
puts "\n"
puts "You can export such a spreadsheet from your Mastodon account. Go to Settings > Data export and click 'CSV' next to 'You follow'. Then enter the local file path here."
puts "\n"
puts "For example: /home/sschlinkert/Downloads/following_accounts.csv"
csv_file_path = gets.chomp.gsub("'","").strip
my_follows = []
CSV.foreach(csv_file_path) do |row|
my_follows << row[0]
end
my_follows.uniq!
my_follows.each_with_index do |account_handle, i|
# Since I need to find the account's id (not URL), I perform a follow request. In the request response, I get an id
begin
follow_attempt_response = client.follow_by_uri(account_handle)
rescue
puts "Couldn't find an id for #{account_handle}, so I can't see if they're moved or not. But you can check manually!"
next
end
account = Account.new(follow_attempt_response)
puts "Checking account ##{i+1} of #{my_follows.size} accounts you follow"
if account.moved_id != nil
already_follow = client.perform_request_with_collection(:get, '/api/v1/accounts/relationships', {:id => account.moved_id}, Mastodon::Relationship).to_a[0].attributes['following']
if already_follow
puts "#{account.url} has moved to #{account.moved_url}, but you already follow #{account.moved_url}"
else
puts "#{account.url} has moved to #{account.moved_url}, and you don't yet follow their new account!"
end
if !already_follow
puts "Would you like to attempt to follow their new account? (y/n)"
response = gets.chomp.downcase
if response == "y"
puts "Attempting to follow #{account.moved_url}..."
follow_attempt_response = client.follow(account.moved_id)
# alternatively... (via https://www.rubydoc.info/gems/mastodon-api/Mastodon/REST/Accounts#follow_by_uri-instance_method)
# follow_attempt_response = client.follow_by_uri(account.moved_id + account.moved_url.split('/')[3])
if follow_attempt_response.attributes['following']
puts "Awesome, you're now following #{account.moved_url}"
elsif follow_attempt_response.attributes['requested']
puts "You've requested to follow #{account.moved_url}"
else
puts "Hmmmm something went wrong"
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment