This is a script I wrote that would start with a given one of my friends on Facebook, poke all their friends, then move on to each of their friends and poke them, ad infinitum. Ended up poking upwards of 50,000 people and caused pandemonium among our friend group.
read moreon friendExtractionGivenan(id, type)
if type is equal to "indirect" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/" & id & "?sk=friends&v=friends');
" in doc
delay 2
end tell
end if
if type is equal to "direct" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/profile.php?id=" & id & "&sk=friends&v=friends');
" in doc
delay 2
end tell
end if
tell application "Safari"
repeat while done_loading is not equal to true
set doc to front document
set done_loading to do JavaScript "
var done = false;
if (document.readyState=='complete'){
done=true;
}
done;
" in doc
delay 1
end repeat
end tell
tell application "Safari"
set doc to front document
set this_url to URL of doc
set done_scrolling to false
set filtered_URLs to {}
set completed_once to false
set erred_once to false
repeat while done_scrolling is not equal to true
try
set done_scrolling to do JavaScript "
var completed_once = " & completed_once & ";
if(completed_once!=true){
var done;
var number_of_trys =0;
}
function scrollToBottom(){
bottom = document.body.scrollHeight;
current = window.innerHeight+ document.body.scrollTop;
done = false;
if((bottom-current) >0){
window.scrollTo(0, bottom);
setTimeout (scrollToBottom, 3500 ); //If the loading exceeds this timeout, a try will be used.
}
else {
done = true;
}
};
if(completed_once!=true){
scrollToBottom();
}
if(done==true&&number_of_trys<10){//This number changes the number of allowed timeouts
done=false;
number_of_trys++;
setTimeout(scrollToBottom, 2000);
//This number sets the allotted timeout length.
//If the loading exceeds both the timeout above and this timeout, another try will be used immediately.
}
done;
" in doc
set completed_once to true
delay 1.0
on error
end try
end repeat
set URLs to false
repeat while URLs is equal to false
set URLs to do JavaScript "
URLArray = [];
allLinks = document.links;
for (i = 0; i < allLinks.length; i++) {
URLArray.push(allLinks[i].href);
}
URLArray;
" in doc
end repeat
return URLs
end tell
end friendExtractionGivenan
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on pokedem_friends(id, type, database1)
try
if type is equal to "indirect" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/" & id & "');
" in doc
delay 1
end tell
end if
if type is equal to "direct" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/profile.php?id=" & id & "');
" in doc
delay 1
end tell
end if
tell application "Safari"
repeat while done_loading is not equal to true
set doc to front document
set done_loading to do JavaScript "
var done = false;
if (document.readyState=='complete'){
done=true;
}
done;
" in doc
delay 1
end repeat
end tell
tell application "System Events"
tell process "Safari"
click at {1898, 166} -- {from left, from top}
delay 0.5
click at {1866, 187} -- {from left, from top} this varies depending on whether the user is online
--delay 1
--if numberPoked is less than 2000 then
--click at {1565, 319} -- {from left, from top}
--else
-- click at {1565, 444} -- {from left, from top}
--end if
delay 0.5
tell application "Database Events"
open database1
tell database1
make new record with properties {name:id}
end tell
save database1
end tell
end tell
end tell
on error errormsg
if errormsg is equal to "User canceled." then
return true
else
return false
end if
end try
return false
end pokedem_friends
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on pokedem_friends_of_friends(id, type, numberPoked, database1)
try
if type is equal to "indirect" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/" & id & "');
" in doc
delay 1
end tell
end if
if type is equal to "direct" then
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('https://www.facebook.com/profile.php?id=" & id & "');
" in doc
delay 1
end tell
end if
tell application "Safari"
repeat while done_loading is not equal to true
set doc to front document
set done_loading to do JavaScript "
var done = false;
if (document.readyState=='complete'){
done=true;
}
done;
" in doc
delay 1
end repeat
end tell
tell application "System Events"
tell process "Safari"
click at {1898, 187} -- {from left, from top} {1898, 184}
delay 0.5
click at {1860, 190} -- {from left, from top}{1860, 215} this varies depending on whether the user is online
delay 1.5
if numberPoked is less than 2000 then
click at {1565, 319} -- {from left, from top}
else
click at {1565, 444} -- {from left, from top}
end if
delay 2
end tell
end tell
on error
end try
end pokedem_friends_of_friends
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on extractionOfIDsFrom(unfiltered_links)
set unfiltered to unfiltered_links
set filtered to {}
set direct_IDs to {}
set indirect_IDs to {}
set refined_IDs to {}
set returned_IDs to {}
repeat with x from 1 to count of items of unfiltered
set n to item x of unfiltered
if "=pb" is in n then
if n is not in filtered then set end of filtered to n
end if
end repeat
repeat with y from 1 to count of items of filtered
set profile to item y of filtered
if "profile.php?" is in profile then
set end of direct_IDs to text ((offset of "=" in profile) + 1) thru ((offset of "&" in profile) - 1) of profile
else
set end of indirect_IDs to text 25 thru ((offset of "?" in profile) - 1) of profile
end if
end repeat
return direct_IDs & indirect_IDs
end extractionOfIDsFrom
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on pokedExtraction(unfiltered_links)
set unfiltered to unfiltered_links
set filtered to {}
set direct_IDs to {}
set indirect_IDs to {}
set refined_IDs to {}
set returned_IDs to {}
repeat with y from 1 to count of items of unfiltered
set alreadyCaptured to false
set profile to item y of unfiltered
if "profile.php?" is in profile then
set theitem to text ((offset of "=" in profile) + 1) thru end of profile
set alreadyCaptured to true
if theitem is not in direct_IDs then set end of direct_IDs to theitem
end if
if alreadyCaptured is false then
set theitem to text 25 thru end of profile
if theitem is not in indirect_IDs then
set characters1 to count theitem
--display dialog theitem
if (characters1 is less than 40) then set end of indirect_IDs to theitem
end if
end if
end repeat
return direct_IDs & indirect_IDs
end pokedExtraction
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on direct_indirect_ID_Checker(id)
try
id as integer
return "direct"
on error
return "indirect"
end try
end direct_indirect_ID_Checker
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on existsInDatabaseChecker(user_id, database1)
tell application "Database Events"
if record user_id of database1 exists then
return true
else
return false
end if
end tell
end existsInDatabaseChecker
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on existsInplistChecker(user_id, database)
tell application "System Events"
if property list item user_id of database exists then
return true
else
return false
end if
end tell
end existsInplistChecker
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on alreadyPoked(blah, returnedIDs, database1)
tell application "Database Events"
repeat with a from 1 to count of items in blah
set anID to item a of blah
if record anID of database1 exists then
else
set end of returnedIDs to anID
end if
end repeat
end tell
return returnedIDs
end alreadyPoked
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on storePokes(returnedIDs, database1)
tell application "Database Events"
repeat with a from 1 to count of items in returnedIDs
set anID to item a of returnedIDs
tell database1
make new record with properties {name:anID}
end tell
end repeat
save database1
end tell
end storePokes
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on exportToPlist(database1)
tell application "System Events"
set parent_dictionary to make new property list item with properties {kind:record}
set the plistfile_path to ("Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:" & "Who_Youve_poked.plist")
set plist to make new property list file with properties {contents:parent_dictionary, name:plistfile_path}
end tell
tell application "Database Events"
repeat with y from 1 to count of records in database1
set currentRecordName to name of record y of database1
tell application "System Events"
tell plist
make new property list item at end with properties {kind:record, name:currentRecordName}
end tell
end tell
end repeat
end tell
end exportToPlist
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on howmanypeopleyouvepoked(database1)
tell application "Database Events"
set hep to count of records in database1
end tell
display dialog hep
end howmanypeopleyouvepoked
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on hasthisuserbeenpoked(user, database1)
tell application "Database Events"
if record user of database1 exists then
set result1 to "This user has already been poked"
else
set result1 to "This user has not been poked"
end if
end tell
display dialog result1
end hasthisuserbeenpoked
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on refreshwhohasbeenpoked(database1)
tell application "Safari"
set doc to front document
set done_loading to false
do JavaScript "
window.location.assign('http://www.facebook.com/pokes');
" in doc
delay 2
end tell
tell application "Safari"
repeat while done_loading is not equal to true
set doc to front document
set done_loading to do JavaScript "
var done = false;
if (document.readyState=='complete'){
done=true;
}
done;
" in doc
delay 1
end repeat
end tell
tell application "Safari"
set URLs to false
repeat while URLs is equal to false
set URLs to do JavaScript "
URLArray = [];
allLinks = document.links;
for (i = 0; i < allLinks.length; i++) {
URLArray.push(allLinks[i].href);
}
URLArray;
" in doc
end repeat
end tell
set unfiltered to URLs
set filtered to {}
set direct_IDs to {}
set indirect_IDs to {}
set refined_IDs to {}
set returned_IDs to {}
repeat with y from 1 to count of items of unfiltered
set alreadyCaptured to false
set profile to item y of unfiltered
if "profile.php?" is in profile then
set theitem to text ((offset of "=" in profile) + 1) thru end of profile
set alreadyCaptured to true
if theitem is not in direct_IDs then set end of direct_IDs to theitem
end if
if alreadyCaptured is false then
set theitem to text 25 thru end of profile
if theitem is not in indirect_IDs then
set characters1 to count theitem
--display dialog theitem
if (characters1 is less than 40) then set end of indirect_IDs to theitem
end if
end if
end repeat
set returnedIDs to direct_IDs & indirect_IDs
display dialog (count of returnedIDs)
tell application "Database Events"
repeat with a from 1 to count of items in returnedIDs
set anID to item a of returnedIDs
tell database1
make new record with properties {name:anID}
end tell
end repeat
end tell
save database1
end refreshwhohasbeenpoked
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
set theOutputFolder to POSIX path of "Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:"
set databaselocation to POSIX path of "Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:ThePokedUpdated.dbev"
tell application "Database Events"
set database1 to database databaselocation
end tell
tell application "System Events"
set parent_dictionary to make new property list item with properties {kind:record}
set the plistfile_path to ("Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:" & "Poked.plist")
set database to property list file plistfile_path
end tell
--howmanypeopleyouvepoked(database1)
--hasthisuserbeenpoked("Monstermac77", database1)
--display dialog existsInplistChecker("1068287181", database)
--refreshwhohasbeenpoked(database1)
--exportToPlist(database1)
set processCancelled to false
set requestingStartingID to display dialog "Press direct or indirect if you would like to poke one individual's friends" default answer "100002585480013" with title "Poker" buttons {"Indirect", "Direct", "Cancel"} default button "Direct"
set button_pressed to the button returned of the result
if the button_pressed is "Direct" then
set startingIDType to "Direct"
else if the button_pressed is "Indirect" then
set startingIDType to "Indirect"
else
set processCancelled to true
end if
if processCancelled is false then
set desiredAction to display dialog "Who would you like to poke?" with title "Poker" buttons {"Poke friends", "Poke friends' friends", "Cancel"} default button "Cancel"
set button_pressed to the button returned of the result
if the button_pressed is "Poke friends" then
set startingID to text returned of requestingStartingID
set unfiltered_links to friendExtractionGivenan(startingID, startingIDType)
set returnedIDs to extractionOfIDsFrom(unfiltered_links)
set blah to returnedIDs
set returnedIDs to {}
set returnedIDs to alreadyPoked(blah, returnedIDs, database1)
repeat with c from 1 to count of items in returnedIDs
set targetID to item c of returnedIDs
set IDType to direct_indirect_ID_Checker(targetID)
pokedem_friends(targetID, IDType, numberPoked)
end repeat
storePokes(returnedIDs, database1)
save database1
display dialog "Would you like to continue to the friends of friends?" with title "Poker Continued" buttons {"Yes", "No"} default button 2
set button_pressed to the button returned of the result
set numberPoked to 0
if the button_pressed is "Yes" then
repeat with c from 1 to count of items in returnedIDs
set currentID to item c of returnedIDs
set dataAlreadyCollected to existsInplistChecker(currentID, database)
if dataAlreadyCollected is false then
set IDType to direct_indirect_ID_Checker(currentID)
set unfiltered_links to friendExtractionGivenan(currentID, IDType)
set friends_of_friend to extractionOfIDsFrom(unfiltered_links)
set blah to friends_of_friend
set friends_of_friend to {}
set friends_of_friend to alreadyPoked(blah, friends_of_friend, database1)
repeat with d from 1 to count of items in friends_of_friend
set numberPoked to numberPoked + 1
set thetargetID to item d of friends_of_friend
set theIDType to direct_indirect_ID_Checker(thetargetID)
pokedem_friends(thetargetID, theIDType, numberPoked)
end repeat
storePokes(friends_of_friend, database1)
end if
end repeat
end if
else if the button_pressed is "Poke friends' friends" then
set startingID to text returned of requestingStartingID
set unfiltered_links to friendExtractionGivenan(startingID, startingIDType)
set returnedIDs to extractionOfIDsFrom(unfiltered_links)
set usercancelled to false
repeat with c from 1 to count of items in returnedIDs
if usercancelled is false then
try
set currentID to item c of returnedIDs
set dataAlreadyCollected to existsInplistChecker(currentID, database)
if dataAlreadyCollected is false then
set IDType to direct_indirect_ID_Checker(currentID)
set unfiltered_links to friendExtractionGivenan(currentID, IDType)
set friends_of_friend to extractionOfIDsFrom(unfiltered_links)
set blah to friends_of_friend
set friends_of_friend to {}
set friends_of_friend to alreadyPoked(blah, friends_of_friend, database1)
repeat with d from 1 to count of items in friends_of_friend
if usercancelled is false then
set thetargetID to item d of friends_of_friend
set theIDType to direct_indirect_ID_Checker(thetargetID)
set usercancelled to pokedem_friends(thetargetID, theIDType, database1)
end if
end repeat
--figure out a way to prevent this item to be stored unless all of the friends have been poked
-- this is to avoid miss-storages due to user-cancellation DONE
if usercancelled is false then
tell application "System Events"
tell database
make new property list item at end with properties {kind:record, name:currentID}
end tell
end tell
end if
end if
on error errormsg
if errormsg is equal to "User canceled." then
set usercancelled to true
end if
end try
end if
end repeat
else
end if
end if
--storePokes(friends_of_friend, database1)
--tell application "Database Events"
-- set database1 to database databaselocation
-- open database1
-- repeat with a from 1 to count of items in friends_of_friend
-- set anID to item a of friends_of_friend
-- tell database1
-- make new record with properties {name:anID}
-- end tell
-- end repeat
-- save database1
--end tell