Following a rather radical pruning of my Twitter followings (people who I am following) my timeline has got both better and less exciting. So I wanted to follow some new people but not just random accounts.
I have a list of ununfollowables: the followings I like best. Those people are probably good judges of the people I should follow – or in any case better at it than random followings.
This script looks who they are following and follows those account. The result is that periodically I automatically follow some of my friends’ friends. It keeps a list of those I’ve followed automatically. If it doesn’t work out I unfollow them again. Of course nothing is keeping me from re-following them manually.
The script relies heavily on @sferik’s Twitter client for Ruby called ‘t’. It’s easy to install but it helps if you read the help file and get to know it a bit should you need to troubleshoot or adjust the script.
It is designed to be run from cron and written on a Debian 8 system but it should run on any Linux flavour. Be sure to add t’s path to your cron file.
The script is called freshmeat.sh on my system.
#!/bin/bash ####################################################################### # Purpose of this script: # # Follow random followings from followings from the ununfollowables # # list, hopefully generating a bit more diversity in your timeline. # # # # The ununfollowables list is just a list of people you like. # # A 'following' is someone you are following. It is the reverse of # # a follower. # # # # Requires: # # - Working and authenticated installation of Ruby gem t: # # https://github.com/sferik/t # # - Twitter list called 'Ununfollowables' (change as needed) # # containing friends whose followings you might like to follow # # - Twitter list called 'freshmeat' for the new followings # # # # Feel free to use, change and redistribute this script as long as # # you include a link to https://vorkbaard.nl and this text. Enjoy :) # # # # @Vorkbaard, 2017 # ####################################################################### ####################################################################### # Settings # ####################################################################### # Ununfollowables list UNUNFOLLOWABLES_LIST=de-onontvolgbaren # Freshmeat list FRESHMEAT_LIST=freshmeat # Number to days to wait before unfollowing if they're not interested WAITDAYS=13 # Number of new random followings to add - must be more than 0. # Note that this script uses up your api access allowance: # https://dev.twitter.com/rest/public/rate-limiting # Also note that a list cannot contain over 5000 members. NEWADDINGS=5 # Do not follow people with the following words in their bio. NOTFOLLOW="entrepreneur|founder|coach" ## MAIL - Make sure your server can send out mail first. ## I'm using xmail but you may want to change it. # Send mail here: MY_EMAIL=your@email.here # The mail's from address FROMADDR=your@servers_email.here ####################################################################### # End of settings # ####################################################################### # Change to directory this script is in so we can use relative file locations when running from cron cd "$(dirname "$0")"; # Retrieve Twitter handle ME=@$(t whoami | head -4 | tail -1 | cut -d'@' -f2) if [ "$?" != "0" ] ; then echo "Unable to retrieve Twitter handle, please make sure t is installed and working correctly." echo "Either that or we've ran out of api calls." exit fi echo "---------------------- $(date) --------------------" >> freshmeat.log echo "Twitter handle: $ME" >> freshmeat.log if [ -e mailtext ] ; then rm mailtext; fi # Ok, here's the gist. # Unfollow those not interested # 1. Get list of randomfollowings followed over two weeks ago. # 2. If they're not interested then unfollow them. # 3. Remove them from the freshmeat list and the inprocess file. # Get new users # 4. Select random user from ununfollowables list. # 5. Select random following from selected user. # 6. Check if we're not already following the random following. If we do, select another one. # 7. Follow the random following. # 8. Put following on the freshmeat list. # Create list of leaders so we only need to retrieve it once. # Leaders are people who you are following but who don't follow you. echo "Creating list of leaders. Please hold." >> freshmeat.log t leaders > leaderslist if [ "$?" != "0" ] ; then echo "Error: probably not enough api calls left. Try again later." >> freshmeat.log echo "We ran out of api calls. Better luck next time!" | mailx -a "From: Freshmeat provider <$FROMADDR>" -s "Fresh meat!" $MY_EMAIL exit fi if [ -e freshmeat.inprocess ] ; then let WAITSECONDS=$WAITDAYS*60*60*24 echo "WAITSECONDS: $WAITSECONDS" >> freshmeat.log echo "Getting list of randomfollowings followed over two weeks ago" >> freshmeat.log NOW=`date +%s` while read RANDOMFOLLOWING; do SINCE=$(echo $RANDOMFOLLOWING | cut -d' ' -f2) RAFO=$(echo $RANDOMFOLLOWING | cut -d' ' -f1) echo "Rafo: $RAFO" >> freshmeat.log echo "Since: $SINCE" >> freshmeat.log echo "NOW..: $NOW" >> freshmeat.log let DIFF=$NOW-$SINCE let HDIFF=$DIFF/3600 echo "Time difference: $DIFF ($HDIFF hours)" >> freshmeat.log if [ "$DIFF" -lt "$WAITSECONDS" ] ; then echo "Time difference is less than $WAITDAYS days." >> freshmeat.log # Not doing anything with them now, just add them to the list for next time echo $RANDOMFOLLOWING >> freshmeat.inprocess_new.log else echo "Time difference is greater than $WAITDAYS days." >> freshmeat.log # Check if they're following back grep -iq "^$RAFO$" leaderslist if [ "$?" == "1" ] ; then # They're following back echo "$RAFO is following back!" >> freshmeat.log echo "$RAFO" >> newfollowers.log echo "New connection made: $RAFO - https://twitter.com/$RAFO" >> mailtext else # They're not following back echo "$RAFO is not interested so unfollowing them." >> freshmeat.log t unfollow $RAFO >/dev/null 2>&1 echo "Unfollowed $RAFO." >> mailtext fi echo "Removing $RAFO from freshmeat list." >> freshmeat.log t list remove $FRESHMEAT_LIST $RAFO >/dev/null 2>&1 if [ "$?" == "0" ] ; then echo "Removing $RAFO from random follower log file." >> freshmeat.log else echo "Error unfollowing $RAFO. Perhaps we've ran out of api calls." >> freshmeat.log fi fi echo "----" >> freshmeat.log done <freshmeat.inprocess # Recreate freshmeat.inprocess file with only remaining (current) followings mv freshmeat.inprocess_new.log freshmeat.inprocess else # if not exist freshmeat.inprocess echo "freshmeat.inprocess doesn't exist; nothing to compare so skipping the unfollow part." >> freshmeat.log fi # Create list of ununfollowables so we only need to retrieve it once echo "Creating list of ununfollowables. This may take a while." >> freshmeat.log t list members $ME/$UNUNFOLLOWABLES_LIST > ununfollowableslist if [ "$?" != "0" ] ; then echo "Error: probably not enough api calls left. Try again later." >> freshmeat.log echo "We ran out of api calls. Better luck next time!" | mailx -a "From: Freshmeat provider <$FROMADDR>" -s "Fresh meat!" $MY_EMAIL exit fi # Create list of followings so we only need to retrieve it once. echo "Creating list of followings. Please hold." >> freshmeat.log t followings > followingslist if [ "$?" != "0" ] ; then echo "Error: probably not enough api calls left. Try again later." >> freshmeat.log echo "We ran out of api calls. Better luck next time!" | mailx -a "From: Freshmeat provider <$FROMADDR>" -s "Fresh meat!" $MY_EMAIL exit fi # Initialize the number of succesfull new followings ADDINGS=0 printf "\n\n" >> mailtext echo "New followings" >> mailtext echo "------------------------------" >> mailtext while [ $ADDINGS -lt $NEWADDINGS ] ; do echo "Succesfull addings: $ADDINGS" >> freshmeat.log # Get random ununfollowable UNUNFOLLOWABLES=$(cat ununfollowableslist | shuf -n 1) echo "Following from ununfollowableslist: $UNUNFOLLOWABLES" >> freshmeat.log for UNUNFOLLOWABLE in $UNUNFOLLOWABLES; do echo "Getting random following from $UNUNFOLLOWABLES_LIST." >> freshmeat.log RANDOMFOLLOWING=$(t followings $UNUNFOLLOWABLE | shuf -n 1) echo "Randomfollowing: $RANDOMFOLLOWING" >> freshmeat.log if [ -n "$RANDOMFOLLOWING" ] ; then # Check if we're not already following this particular random following grep -iq "^$RANDOMFOLLOWING$" followingslist if [ "$?" == "1" ] ; then echo "Not already following, but is this a protected account?" >> freshmeat.log # Protected accounts don't have the 'Last update' bit set in their public profile. # Also, get to know them a bit by reading their bio. t whois $RANDOMFOLLOWING > tmpwhois # Check if the account is protected grep -q "Last update" tmpwhois if [ "$?" == "0" ] ; then # Check if they're not unwanted BIO=$(grep "Bio" tmpwhois) if echo $BIO | egrep -iqv $NOTFOLLOW; then echo "Not already following $RANDOMFOLLOWING AND not a protectect account AND they're not unwanted so following them now." >> freshmeat.log t follow $RANDOMFOLLOWING >/dev/null 2>&1 if [ "$?" == "0" ] ; then echo "Follow succesful so adding them to $FRESHMEAT_LIST." >> freshmeat.log t list add $FRESHMEAT_LIST $RANDOMFOLLOWING >/dev/null 2>&1 NOW=`date +%s` echo "$RANDOMFOLLOWING $NOW" >> freshmeat.inprocess # Increase addings number ADDINGS=$(( $ADDINGS + 1 )) SHOWBIO="$(echo $BIO|cut -c5-)" echo "Via $UNUNFOLLOWABLES: $RANDOMFOLLOWING - $SHOWBIO [https://twitter.com/$RANDOMFOLLOWING]" >> mailtext fi else echo "Not going to follow $NOTFOLLOW." >> freshmeat.log fi else echo "Not going to follow protected account." >> freshmeat.log fi else echo "Already following $RANDOMFOLLOWING." >> freshmeat.log fi echo "---- done ----" >> freshmeat.log else echo "We've probably ran out of api calls so let's call it a day." >> freshmeat.log ADDINGS=$(( $NEWADDINGS + 1 )) # if -n $RANDOMFOLLOWING fi # for UNUNFOLLOWABLE done # Addings done # Mail logfile # Get number of connections generated if [ -e newfollowers.log ] ; then FreshFollNr=$(wc -l newfollowers.log | cut -d' ' -f1) echo "Freshmeat has generated $FreshFollNr connections." >> mailtext else echo "Freshmeat has not generated any connections yet." >> mailtext fi # Get number of people in Freshmeat list FreshmeatMembersNr=$(t list information $FRESHMEAT_LIST | head -5 | tail -1 | cut -d ' ' -f7) echo "There are now $FreshmeatMembersNr people on the $FRESHMEAT_LIST list." >> mailtext # Send mail cat mailtext | mailx -a "From: Freshmeat provider <$FROMADDR>" -s "Fresh meat!" $MY_EMAIL rm mailtext # Clean up if [ -e tmpwhois ] ; then rm tmpwhois; fi if [ -e followingslist ] ; then rm followingslist; fi if [ -e ununfollowableslist ] ; then rm ununfollowableslist; fi if [ -e leaderslist ] ; then rm leaderslist; fi