Created
January 4, 2011 02:00
-
-
Save hac/764284 to your computer and use it in GitHub Desktop.
A class for automating basic user tasks on FaceBook.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require 'rubygems' | |
require 'mechanize' | |
# We will probably want to start using JSON instead of regular expressions sometime. | |
#require 'json' | |
class Mechanize::Page | |
# This is a workaround for a problem with Mechanize. It lets you search for forms by id when scraping a page. | |
def form_id(formId) | |
formContents = (self/:form).find { |elem| elem['id'] == formId } | |
if formContents then return Mechanize::Form.new(formContents) end | |
end | |
end | |
class FacebookBot | |
def initialize(email, pass) | |
@fbUrl = "http://www.facebook.com/" | |
@mobileUrl = "http://m.facebook.com/" | |
@email, @pass = email, pass | |
@agent = Mechanize.new | |
@agent.user_agent_alias = 'Mac Safari' | |
@cookies = File.dirname(__FILE__) + "/cookies-" + @email + ".yml" | |
if (File.file?(@cookies)) | |
@agent.cookie_jar.load(@cookies) | |
puts "Saved cookies:", @agent.cookies | |
else | |
puts "No saved cookies." | |
end | |
self.login | |
end | |
def login | |
page = @agent.get(@fbUrl) | |
# Read stored cookies. | |
if (loginf = page.form_id("login_form")) | |
puts "Logging in..." | |
loginf.set_fields(:email => @email, :pass => @pass) | |
page = @agent.submit(loginf, loginf.buttons.first) | |
puts page.form_id("logout_form")? "Login Successful" : "Login Failed" | |
else | |
puts "Not logging in. Already Logged In!" | |
end | |
# Write login cookies. Once these are written your password is not used again until your session expires. | |
@agent.cookie_jar.save_as(@cookies) | |
body = page.root.to_html | |
# @uid = %r{\\"user\\":(\d+),\\"hide\\"}.match(body)[1] # This is a UID given to each Facebook user. | |
@uid = %r{user:(\d+),}.match(body)[1] # This is a UID given to each Facebook user. | |
# @post_form_id = %r{<input type="hidden" id="post_form_id" name="post_form_id" value="([^"]+)}.match(body)[1] # This is a token we need to submit forms. | |
@post_form_id = %r{name=\\"post_form_id\\" value=\\"([^"]+)\\"}.match(body)[1] # This is a token we need to submit forms. | |
end | |
def postStatus(status) | |
puts "Sharing text..." | |
page = @agent.get(@mobileUrl) | |
composerForm = page.form_id("composer_form") | |
composerForm.set_fields(:fb_dtsg => "A6vyP", :post_form_id => @post_form_id, :charset_test => "€,´,€,´,水,Д,Є", :status => status) | |
@agent.submit(composerForm, composerForm.buttons.first) | |
puts "Done." | |
end | |
def suggestedFriends | |
page = @agent.get(@fbUrl + "find-friends") | |
friends = [] | |
page.search(".friend_browser_page_name_box/a").each do | |
|my_tag| friends.push(%r{\?id=(\d+)"}.match(my_tag.to_html)[1]) # Add the person's id to an array. | |
# The person's display name would be (my_tag.to_html.gsub(/<\/?[^>]*>/, "") | |
end | |
friends | |
end | |
def requestFriend(friendId) | |
r = @agent.post('http://www.facebook.com/ajax/profile/connect.php?profile_id=' + friendId.to_s + '&rel_dialog=1&src=fbx_top_bar&ref=none&__a=1', | |
'profile_id' => friendId, | |
'rel_dialog' => 1, | |
'src' => 'fbx_top_bar', | |
'ref' => 'none', | |
'__d' => 1, | |
'post_form_id' => @post_form_id, | |
'fb_dtsg' => 'A6vyP', | |
'lsd' => '', | |
'post_form_id_source' => 'AsyncRequest').body | |
submit_token = %r{\\"submit_token\\":\\"([0-9a-z]+)\\"}.match(r)[1] | |
r = @agent.post('http://www.facebook.com/ajax/profile/connect.php?__a=1', | |
'user' => @uid, | |
'profile_id' => friendId, | |
'submit_token' => submit_token, | |
'source' => 'profile_button', | |
'src' => 'fbx_top_bar', | |
'submit' => 1, | |
'post_form_id' => @post_form_id, | |
'fb_dtsg' => 'A6vyP', | |
'lsd' => '', | |
'post_form_id_source' => 'AsyncRequest').body | |
end | |
def acceptRequests | |
puts "Accepting all requests..." | |
page = @agent.get(@mobileUrl + "friends.php") | |
page.forms.each { |form| if (form.buttons.first.value=="Confirm" || form.buttons.first.value=="Add Friend") then @agent.submit(form, form.buttons.first) end } | |
puts "Done." | |
end | |
# Get recent status changes or text posts on other people's walls. | |
def recentPosts | |
page = @agent.get(@mobileUrl + "stories.php") | |
posts = [] | |
page.search(".c div").each do |my_tag| | |
if (authorLink = my_tag.search("a").first) then | |
author = authorLink.inner_text | |
authorLink.remove | |
end | |
if (my_tag.to_html.scan("\342\226\266").count) then # It's a conversation. | |
if (recieverLink = my_tag.search("a").first) then recieverLink.remove end | |
end | |
post = {"text" => my_tag.inner_text.gsub("\342\226\266", "").strip, "authorName" => author} | |
if (recieverLink) then post["recieverName"] = recieverLink.inner_text end; | |
posts.push(post) | |
end | |
posts | |
end | |
def personalMessages(showRead = false) | |
page = @agent.get(@mobileUrl + (showRead ? "inbox#!/inbox/" : "inbox#!/inbox/?unread")) | |
messages = [] | |
page.search("table.results/*/td").each do |my_tag| | |
senderTag = my_tag.search("a[@href^='/profile']").first | |
subjectTag = my_tag.search("a[@href^='/inbox']").first | |
replyTag = my_tag.search("a[@href^='/inbox/readmessage.php']").first | |
messageId = %r{\?t=(\d+)}.match(replyTag.attributes["href"])[1] | |
message = {"subject" => subjectTag.inner_text.gsub("\342\200\242", ''), "senderName" => senderTag.inner_text, "messageId" => messageId} | |
# Remove all divs except the one with the message. | |
my_tag.search("div.note").remove | |
my_tag.search("div.mfss").remove | |
message["body"] = my_tag.inner_text | |
messages.push(message) | |
end | |
messages | |
end | |
# This method is unfinished. | |
def replyToMessageWithText(messageId, messageText) | |
page = @agent.get(@mobileUrl + "inbox/readmessage.php?t=" + messageId) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment