Skip to content

Instantly share code, notes, and snippets.

@eramdam
Created August 12, 2018 20:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eramdam/eaf508dc9122ab3b0cbf022b874699c7 to your computer and use it in GitHub Desktop.
Save eramdam/eaf508dc9122ab3b0cbf022b874699c7 to your computer and use it in GitHub Desktop.
A small script to unfollow non-mutuals on Mastodon (useful if you need to do some cleaning)
const Masto = require('mastodon');
const fs = require('fs')
const M = new Masto({
access_token: 'ACCESS_TOKEN',
api_url: 'https://YOUR-INSTANCE.TLD/api/v1/'
});
function getNextPage(req) {
return (req.headers && req.headers.link && req.headers.link.includes('rel="next"')) ? req.headers.link.split(/<([^>]+)>/)[1] : null;
}
function toCsv(accountsArray) {
return [
['id', 'handle', 'url', 'Toots', 'Following', 'Followers', 'Created at'],
...accountsArray.map(i => [
i.id,
i.moved ? i.moved.acct : i.acct,,
i.moved ? i.moved.url : i.url,
i.statuses_count,
i.following_count,
i.followers_count,
i.created_at
])
].map(i => i.join(',')).join('\n')
}
(async () => {
const accountRequest = await M.get('accounts/verify_credentials');
const {id} = accountRequest.data;
const accounts = new Map();
let lastData = await M.get(`accounts/${id}/following`)
lastData.data.forEach(i => {
accounts.set(i.id, i)
})
while (getNextPage(lastData.resp)) {
const nextPageUrl = getNextPage(lastData.resp);
console.log('fetching ', {nextPageUrl})
lastData = await M.get(nextPageUrl)
lastData.data.forEach(i => {
accounts.set(i.id, i)
})
}
console.log('done!!')
console.log('found', accounts.size, 'accounts followed')
const ids = Array.from(accounts.keys());
const relationshipReq = await M.get('accounts/relationships', {id: ids});
const {data} = relationshipReq;
const nonMutuals = data.filter(i => i.following && !i.followed_by).map(i => accounts.get(i.id));
fs.writeFileSync('./non-mutuals.csv', toCsv(nonMutuals), {encoding: 'utf8'});
console.log(`Wrote list of ${nonMutuals.length} non-mutuals to ./non-mutuals.csv`);
// for (acct of nonMutuals) {
// await M.post(`/accounts/${acct.id}/unfollow`)
// console.log('Unfollowed ', acct.acct)
// }
})();
{
"name": "masto-mutuals",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"mastodon": "^1.2.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment