Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
553 views
in Technique[技术] by (71.8m points)

ruby - Obtaining a Facebook auth token for a command-line (desktop) application

I am working for a charity which is promoting sign language, and they want to post a video to their FB page every day. There's a large (and growing) number of videos, so they want to schedule the uploads programmatically. I don't really mind what programming language I end up doing this in, but I've tried the following and not got very far:

  • Perl using WWW::Facebook::API (old REST API)

    my $res = $client->video->upload(
     title => $name,
     description => $description,
     data => scalar(read_file("videos/split/$name.mp4"))
    );
    

    Authentication is OK, and this correctly posts a facebook.video.upload method to https://api-video.facebook.com/restserver.php. Unfortunately, this returns "Method unknown". I presume this is to do with the REST API being deprecated.

  • Facebook::Graph in Perl or fb_graph gem in Ruby. (OAuth API)

    I can't even authenticate. Both of these are geared towards web rather than desktop applications of OAuth, but I think I ought to be able to do:

    my $fb = Facebook::Graph->new(
     app_id => "xxx",
     secret => "yyy",
     postback => "https://www.facebook.com/connect/login_success.html"
    );
    print $fb->authorize->extend_permissions(qw(publish_stream read_stream))->uri_as_string;
    

    Go to that URL in my browser, capture the code parameter returned, and then

    my $r = $fb->request_access_token($code);
    

    Unfortunately:

    Could not fetch access token: Bad Request at /Library/Perl/5.16/Facebook/Graph/AccessToken/Response.pm line 26
    
  • Similarly in Ruby, using fb_graph,

    fb_auth = FbGraph::Auth.new(APP_ID, APP_SECRET)
    
    client = fb_auth.client
    client.redirect_uri = "https://www.facebook.com/connect/login_success.html"
    puts client.authorization_uri(
      :scope => [:publish_stream, :read_stream]
    )
    

    Gives me a URL which returns a code, but running

    client.authorization_code = <code>
    FbGraph.debug!
    access_token = client.access_token!
    

    returns

    {
      "error": {
        "message": "Missing client_id parameter.",
        "type":    "OAuthException",
        "code":    101
      }
    }
    

    Update: When I change the access_token! call to access_token!("foobar") to force Rack::OAuth2::Client to put the identifier and secret into the request body, I get the following error instead:

    {
      "error": {
        "message": "The request is invalid because the app is configured as a desktop app",
         "type":   "OAuthException",
         "code":   1
      }
    }
    

How am I supposed to authenticate a desktop/command line app to Facebook using OAuth?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So, I finally got it working, without setting up a web server and doing a callback. The trick, counter-intuitively, was to turn off the "Desktop application" setting and not to request offline_access.

FaceBook::Graph's support for posting videos doesn't seem to work at the moment, so I ended up doing it in Ruby.

fb_auth = FbGraph::Auth.new(APP_ID, APP_SECRET)

client = fb_auth.client
client.redirect_uri = "https://www.facebook.com/connect/login_success.html"

if ARGV.length == 0
  puts "Go to this URL"
  puts client.authorization_uri(:scope => [:publish_stream, :read_stream] )
  puts "Then run me again with the code"
  exit
end

if ARGV.length == 1
  client.authorization_code = ARGV[0]
  access_token = client.access_token! :client_auth_body
  File.open("authtoken.txt", "w") { |io| io.write(access_token)  }
  exit
end

file, title, description = ARGV

access_token = File.read("authtoken.txt")
fb_auth.exchange_token! access_token
File.open("authtoken.txt", "w") { |io| io.write(fb_auth.access_token)  }

me = FbGraph::Page.new(PAGE_ID, :access_token => access_token)
me.video!(
    :source => File.new(file),
    :title => title,
    :description => description
)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...