Module: FBCLI

Defined in:
lib/fbcli/auth.rb,
lib/fbcli/version.rb,
lib/fbcli/facebook.rb

Constant Summary collapse

API_VERSION =
"2.10"
VERSION =
'1.6.3.1'
@@api =
nil

Class Method Summary collapse

Class Method Details

.api_call(lambda) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/fbcli/facebook.rb', line 29

def self.api_call(lambda)
  @@api = init_api if @@api.nil?

  begin
    lambda.call(@@api)
  rescue Koala::Facebook::APIError => e
    exit_now! koala_error_str e
  end
end

.get_access_token(app_id, auth_code, app_secret, redirect_uri) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fbcli/auth.rb', line 60

def self.get_access_token(app_id, auth_code, app_secret, redirect_uri)
  # The redirect_uri doesn't play the same role as in capturing the auth code, however
  # it must match the one used in the previous case, otherwise the server will reject
  # the request.
  #
  # See: https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/
  auth_uri = "https://graph.facebook.com/v#{API_VERSION}/oauth/access_token?" +
    "client_id=#{app_id}" +
    "&redirect_uri=#{redirect_uri}" +
    "&client_secret=#{app_secret}" +
    "&code=#{auth_code}"

  res = Net::HTTP.get_response(URI.parse(auth_uri))
  res = JSON.parse(res.body)

  res["access_token"]
end

.init_apiObject



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/fbcli/facebook.rb', line 6

def self.init_api
  if $config['access_token'].nil? or $config['access_token'].empty?
    exit_now! <<-EOM
Obtain an access token to interact with the Facebook API.

Run: #{APP_NAME} login
    EOM
  end

  Koala::Facebook::API.new($config['access_token'])
end

.koala_error_str(e) ⇒ Object



18
19
20
21
22
23
24
25
26
27
# File 'lib/fbcli/facebook.rb', line 18

def self.koala_error_str(e)
  str = "Koala #{e.fb_error_type}"
  str << " (code #{e.fb_error_code.to_s +
           (e.fb_error_subcode.nil? ? "" : ", subcode: " + e.fb_error_subcode.to_s)})"
  str << " HTTP status: #{e.http_status}" unless e.http_status.nil?
  str << "\n  #{e.fb_error_user_msg.nil? ? e.fb_error_message : e.fb_error_user_msg}"
  str << " (FB trace id: #{e.fb_error_trace_id})"

  str
end

.login(app_id, app_secret, local_port) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/fbcli/auth.rb', line 9

def self.(app_id, app_secret, local_port)
  redirect_uri = "http://localhost:#{local_port}/"

  uri = "https://www.facebook.com/dialog/oauth?client_id=#{app_id}" +
    "&redirect_uri=#{redirect_uri}" +
    "&scope=user_likes,user_friends,user_posts,user_photos,user_videos,user_events,publish_actions"

  puts <<-EOM
Open this URL in a web browser and allow access to the Facebook Graph on behalf of your user account:

#{uri}

Waiting to receive authorization code on port #{local_port}...

  EOM

  server = WEBrick::HTTPServer.new(
    :Port => local_port,
    :SSLEnable => false,
    :Logger => WEBrick::Log.new(File.open(File::NULL, 'w')),
    :AccessLog => []
  )

  access_token = nil

  server.mount_proc '/' do |req, res|
    key, value = req.query_string.split '=', 2

    if key == "code"
      puts "Received authorization code. Exchanging it for an access token..."
      puts

      access_token = get_access_token(app_id, value, app_secret, redirect_uri)
    else
      puts "Received unexpected request: #{req.query_string}"
    end

    res.body = 'You may now close this window.'
    server.shutdown
  end

  # Allow CTRL+C intervention
  trap 'INT' do server.shutdown end

  # Block execution on this thread until server shuts down
  server.start

  # Return access token
  access_token
end

.logoutObject



45
46
47
48
49
# File 'lib/fbcli/facebook.rb', line 45

def self.logout
  api_call lambda { |api|
    api.delete_object("me/permissions")
  }
end

.page_items(cmd, separator = nil, filter = nil) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/fbcli/facebook.rb', line 73

def self.page_items(cmd, separator = nil, filter = nil)
  items = request_personal_connections(cmd)

  virgin = true
  count = 0

  while not (items.nil? or count == $global_options['pages']) do
    items.each_with_index { |item, idx|
      if filter.nil? or not filter.call(item)
        unless separator.nil? or virgin
          puts separator
        end

        yield item

        virgin = false
      end
    }

    count += 1
    items = items.next_page
  end
end

.publish_image(target, msg, image_file_or_url) ⇒ Object



105
106
107
108
109
110
111
# File 'lib/fbcli/facebook.rb', line 105

def self.publish_image(target, msg, image_file_or_url)
  result = api_call lambda { |api|
    api.put_picture(image_file_or_url, {:message => msg}, target)
  }

  result['post_id']
end

.publish_post(target, msg, link_metadata = {}) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/fbcli/facebook.rb', line 97

def self.publish_post(target, msg,  = {})
  result = api_call lambda { |api|
    api.put_wall_post(msg, , target)
  }

  result['id']
end

.publish_video(target, msg, video_file_or_url, title = nil) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/fbcli/facebook.rb', line 113

def self.publish_video(target, msg, video_file_or_url, title = nil)
  result = api_call lambda { |api|
    api.put_video(video_file_or_url, {:title => title, :description => msg}, target)
  }

  result['id']
end

.raw_request(req) ⇒ Object



39
40
41
42
43
# File 'lib/fbcli/facebook.rb', line 39

def self.raw_request(req)
  api_call lambda { |api|
    api.graph_call req
  }
end

.request_object(id, options = {}) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/fbcli/facebook.rb', line 59

def self.request_object(id, options = {})
  api_call lambda { |api|
    api.get_object(id, options) do |data|
      yield data
    end
  }
end

.request_personal_connections(cmd) ⇒ Object



67
68
69
70
71
# File 'lib/fbcli/facebook.rb', line 67

def self.request_personal_connections(cmd)
  api_call lambda { |api|
    api.get_connections("me", cmd)
  }
end

.request_token_info(access_token = $config['access_token']) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/fbcli/facebook.rb', line 51

def self.request_token_info(access_token = $config['access_token'])
  api_call lambda { |api|
    api.debug_token access_token do |res|
      yield res['data']
    end
  }
end