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

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

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

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

    身份validation没问题,这正确地将facebook.video.upload方法发布到https://api-video.facebook.com/restserver.php 。 不幸的是,这会返回“方法未知”。 我认为这与弃用的REST API有关。

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

    我甚至无法进行身份validation。 这两个都面向网络而不是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] ) 

    给我一个返回代码但正在运行的URL

     client.authorization_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 } } 

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

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

FaceBook::Graph对发布video的支持目前似乎不起作用,所以我最终用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 ) 

问题是在你的情况下,对于OAuth,你需要一些端点URL,可以通过互联网公开到达Facebook服务器,对于普通的客户端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中读取访问令牌。

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

  • 当您想要发布到页面时,获取页面访问令牌并将其存储在本地。 这可以通过使用图形资源管理器来完成

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

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

curl -v -0 –form title = {YOUR_TITLE} – 表格描述= {YOUR_DESCRIPTION} – 表格来源= @ {YOUR_FULL_FILE_PATH} https://graph-video.facebook.com/ {YOUR_PAGE_ID} / videos?access_token = {} YOUR_ACCESS_TOKEN

参考文献:

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

来自facebook videoAPI参考 :

图谱API中的单个video。

要读取video,请使用user_videos权限向/ VIDEO_ID发出HTTP GET请求。 这将返回用户已上传或已被标记的video。

videoPOST请求应使用graph-video.facebook.com。

因此,如果要上传video,您应该发布到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(""); } $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 '
'; echo 'Please choose a file:'; echo ''; echo ''; echo '
';

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

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

 http://yourdomain.com/testfb.php 

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

 Settings > Advanced 

并寻找第一个选项:

在此处输入图像描述

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

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

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

如果您可以使用图谱API资源管理器来获取oauth令牌,那么使用像考拉这样的gem来上传您的video就变得非常简单了。

这是重要的一点:

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

我在这里为你做了一个示例项目: fb-upload-example