The --user-agent is to fake being a web browser even though I don't use a full agent. Facebook requires one to prevent automatic downloading of files (even though it only fools the newest of users)
The --cookies loads a authenticated sessions credentials and is only needed for some people if they have their friend list hidden from non friends. Although it is impossible to block people from seeing your list if they know this url.
To find a users uid go to their profile and it will be in the url if they don't have a vanity url.
example
http://www.facebook.com/profile.php?id=3826483428If they use a vanity url I get their uid by viewing the filename of their profile picture it will be everything after the letter and before the _
example n3826483428_5393.jpg
you save the uid and name in a external "uids" file using the following format note the ;'s
2386423842;John Doe;
8329164832;Jane Doe;
Here is my most up to date version of the script
Code:
#!/bin/bash
#Couple variables to edit
COOKIEDIR=~/.mozilla/firefox/gwatdpoo.SecondaryProfile
#Shows logs on terminal, recommended or you have to open each log individually.
VERBOSE=yes
#Checks if needed directories exist and creates them if needed
for directory in base old log; do
if [ ! -d $directory ]; then mkdir $directory; fi
done
#Copies the cookies database to get around it being locked and attempts to find it if not properly told the location
if [[ -e $COOKIEDIR/cookies.sqlite ]] ; then cp $COOKIEDIR/cookies.sqlite . ; else cp `locate cookies.sqlite | head -n 1` . ; fi
#Extracts the Facebook cookies to text then deletes the database file
sqlite3 cookies.sqlite <<EOF
.output cookies.txt
.mode tabs
.header off
select host as domain,
case substr(host,1,1)='.' when 0 then 'FALSE' else 'TRUE' end as flag,
path,
case isSecure when 0 then 'FALSE' else 'TRUE' end as secure,
expiry as expiration, name, value
from moz_cookies;
EOF
rm cookies.sqlite
#Saves the date and time in a variable
DATE=`date`
#Loop to run for every uid
while IFS=';' read uid name
do
#Downloads friend list
curl --silent --user-agent "Firefox" --cookie cookies.txt http://www.facebook.com/ajax/typeahead_friends.php/\?u\=`echo $uid`\&__a\=1 -o "$name".fl
#If download is empty exits and tells you to login to Facebook
grep facebook "$name".fl > "$name".test
if [[ ! -s "$name".test ]]
then
rm "$name".fl "$name".test
echo "Please login to Facebook to generate a valid session cookie then retry"
exit 1
else
rm "$name".test
fi
#Formats it so it can be diff'd and easily read
#Makes each person have their own line since the default is one long line
sed s/\{\"t\"\:/'\n'/g "$name".fl | \
#Nothing to do with the script it just cleans up the urls so they can be copy and pasted to a browser
sed 's/\\\//\//g' | \
#Cleanup
sed s/\,\"i\"\:/'\t''\t'/g | \
#More cleanup
sed s/\,\"u\"\:\"/'\t'/g | \
#Even more cleanup
sed s/\"\,\"n\".*$// | \
#Creates new file that only has people and not random info at beginning of file
grep facebook | \
#Rearranges list for sorting incase Facebook sent any in the wrong order which prevents extra output from diff
sed 's/\([^\t]*\)\t\t\([^\t]*\)\t\(.*\)/\2\t\1\t\3/' | \
#Sorts the list
sort -n > "$name".new
#Removes unformatted friend list
rm "$name".fl
#Finds differences against old version and logs it
diff base/"$name".base "$name".new > log/"$name"."$DATE".log
#I want to see what is happening as it happens so this shows log followed by some space to easily see where different people start
if [[ $VERBOSE == yes ]]
then
echo $name
cat log/"$name"."$DATE".log
echo ""
echo ""
echo ""
echo ""
echo ""
fi
#Removes the log if it is empty
if [[ ! -s log/"$name"."$DATE".log ]]
then
rm log/"$name"."$DATE".log
fi
#Keeps copy then moves new version to the base that will be used next time
cp "$name".new old/"$name"."$DATE"
mv "$name".new base/"$name".base
done < uids