获取命令行(桌面)应用程序的Facebook身份验证令牌

时间:2014-02-24 04:11:04

标签: ruby facebook perl facebook-graph-api

我正在为一家推广手语的慈善机构工作,他们希望每天都将视频发布到他们的FB页面。视频数量很大(且不断增长),因此他们希望以编程方式安排上传。我真的不介意我最终在做什么编程语言,但是我尝试了以下内容并没有走得太远:

  • Perl使用WWW::Facebook::API(旧的REST API)

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

    身份验证即可,这样就可以将facebook.video.upload方法正确发布到https://api-video.facebook.com/restserver.php。不幸的是,这会返回“方法未知”。我认为这与弃用的REST API有关。

  • Perl中的
  • Facebook::Graph或Ruby中的fb_graph gem。 (OAuth API)

    我甚至无法进行身份验证。这两个都面向网络而不是OAuth的桌面应用程序,但我认为我应该能够做到:

    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;
    

    在浏览器中转到该URL,捕获返回的code参数,然后

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

    不幸的是:

    Could not fetch access token: Bad Request at /Library/Perl/5.16/Facebook/Graph/AccessToken/Response.pm line 26
    
  • 同样在Ruby中,使用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]
    )
    

    给我一​​个返回代码但运行

    的网址
    client.authorization_code = <code>
    FbGraph.debug!
    access_token = client.access_token!
    

    返回

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

    更新:当我将access_token!调用更改为access_token!("foobar")以强制Rack :: OAuth2 :: Client将标识符和机密放入请求正文时,我得到了而是出现以下错误:

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

我应该如何使用OAuth验证桌面/命令行应用程序到Facebook?

4 个答案:

答案 0 :(得分:8)

所以,我终于让它工作了,没有设置Web服务器并进行回调。反直觉的诀窍是将关闭&#34;桌面应用程序&#34;设置而不是请求offline_access

FaceBook::Graph对发布视频的支持目前似乎无法正常工作,所以我最终在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
)

答案 1 :(得分:7)

在您的情况下,对于OAuth,您需要一些可通过Internet公开到达Facebook服务器的端点URL,这对于普通客户端PC或具有WebViews功能的桌面应用程序来说可能是不行的(我假设,命令行不是。)

Facebook在https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#login声明您可以构建桌面客户端登录流程,但只能通过所谓的WebViews。因此,您需要像这样调用OAuth端点:

https://www.facebook.com/dialog/oauth?client_id={YOUR_APP_ID}&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&scope={YOUR_PERMISSION_LIST}

然后,您必须检查生成的重定向WebView URL为引用:

  

使用桌面应用程序并登录时,Facebook会将人重定向到   上面提到的redirect_uri并放置一个访问令牌   URI片段中的一些其他元数据(例如令牌到期时间):

https://www.facebook.com/connect/login_success.html#access_token=ACCESS_TOKEN... 
     

您的应用需要检测此重定向,然后使用您正在使用的操作系统和开发框架提供的机制从URI中读取访问令牌。

如果您想在“黑客模式”中执行此操作,我建议您执行以下操作:

  • 当您想要发布到页面时,获取页面访问令牌并将其存储在本地。这可以通过使用
  • 中的Graph Explorer来完成

https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts

端点。请记住提供“manage_pages”和“publish_actions”权限。

  

卷曲-v -0 - 形成title = {YOUR_TITLE} - 形成   description = {YOUR_DESCRIPTION} - 表格source = @ {YOUR_FULL_FILE_PATH}   https://graph-video.facebook.com/ {YOUR_PAGE_ID} /视频?ACCESS_TOKEN = {YOUR_ACCESS_TOKEN}

参考文献:

https://developers.facebook.com/docs/graph-api/reference/page/videos/#publish https://developers.facebook.com/docs/reference/api/video/

答案 2 :(得分:1)

来自facebook video API reference

  

图谱API中的单个视频。

     

要阅读视频,请向/ VIDEO_ID发出HTTP GET请求   user_videos权限。这将返回用户拥有的视频   已上传或已被标记。

     

视频POST请求应使用graph-video.facebook.com。

如果您要上传视频,那么您应该发布到graph-video.facebook.com。

您还需要来自将要上传到的用户或个人资料的扩展权限,在这种情况下,您需要video_upload这将仅被请求一次,当前用户被要求获得此类权限时对于应用程序。

您的终端应该是:

https://graph-video.facebook.com/me/videos

如果您始终要发布给特定用户,则必须将端点部分从/me更改为用户ID或页面ID。

这是一个示例(在PHP中):

$app_id = "YOUR_APP_ID";
$app_secret = "YOUR_APP_SECRET"; 
$my_url = "YOUR_POST_LOGIN_URL"; 
$video_title = "YOUR_VIDEO_TITLE";
$video_desc = "YOUR_VIDEO_DESCRIPTION";

$code = $_REQUEST["code"];

if(empty($code)) {
   $dialog_url = "http://www.facebook.com/dialog/oauth?client_id=" 
     . $app_id . "&redirect_uri=" . urlencode($my_url) 
     . "&scope=publish_stream";
    echo("<script>top.location.href='" . $dialog_url . "'</script>");
}

$token_url = "https://graph.facebook.com/oauth/access_token?client_id="
    . $app_id . "&redirect_uri=" . urlencode($my_url) 
    . "&client_secret=" . $app_secret 
    . "&code=" . $code;
$access_token = file_get_contents($token_url);

$post_url = "https://graph-video.facebook.com/me/videos?"
    . "title=" . $video_title. "&description=" . $video_desc 
    . "&". $access_token;

echo '<form enctype="multipart/form-data" action=" '.$post_url.' "  
     method="POST">';
echo 'Please choose a file:';
echo '<input name="file" type="file">';
echo '<input type="submit" value="Upload" />';
echo '</form>';

虽然如果视频太大我担心上传速度,但我猜你的客户已经对其进行了整理(压缩/优化/短视频等)。

我已经让你成为demo here。转到我的网站(我拥有该域名)并尝试上传视频。我尝试使用this one这是一个相对较小的4Mb文件。确保此脚本只会尝试上传视频,仅此而已(对于您当前登录的FB配置文件),但是,如果您仍然担心,请复制我的代码段,将其上传到您自己的服务器(使用PHP)支持当然)并创建一个测试应用程序,其中网站网址是该域名,并确保在$my_url变量中指定您的端点,这基本上是接收来自Facebook的响应的脚本的完整路径:

http://yourdomain.com/testfb.php 

如果您仍想在桌面应用上执行此操作,则必须在应用设置上访问developer.facebook.com:

Settings > Advanced

寻找第一个选项:

enter image description here

启用该开关,以便facebook允许您从桌面或本机应用程序而不是Web服务器进行POST。

注意:我不是Ruby的专家,但上面运行的PHP代码应该非常明显,并且很容易移植到它。

答案 3 :(得分:0)

据我所知,如果没有某种可以从facebook接收回调的端点,你想要的是不可能的。

如果您可以使用Graph API Explorer来表达oauth令牌,那么使用像koala这样的宝石来上传您的视频就变得非常简单了。

这是重要的一点:

@graph = Koala::Facebook::API.new(access_token)
@graph.put_video(path_to_my_video)

我在这里为您制作了一个示例项目:fb-upload-example