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

Ruby 为命令行(桌面)应用程序获取Facebook身份验证令牌,ruby,facebook,perl,facebook-graph-api,Ruby,Facebook,Perl,Facebook Graph Api,我为一家推广手语的慈善机构工作,他们想每天在他们的FB页面上发布一段视频。视频的数量很大(而且还在增长),因此他们希望通过编程方式安排上传。我真的不介意我最终用什么编程语言来完成这项工作,但我尝试了以下几点,并没有走多远: 使用Perl(旧的RESTAPI) 身份验证正常,这会正确地将facebook.video.upload方法发布到https://api-video.facebook.com/restserver.php。不幸的是,这将返回“方法未知”。我认为这与RESTAPI被弃用有关

我为一家推广手语的慈善机构工作,他们想每天在他们的FB页面上发布一段视频。视频的数量很大(而且还在增长),因此他们希望通过编程方式安排上传。我真的不介意我最终用什么编程语言来完成这项工作,但我尝试了以下几点,并没有走多远:

  • 使用Perl(旧的RESTAPI)

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

  • 在Perl中或Ruby中的fb_图形中。(OAuth API)

    我甚至不能认证。这两个应用程序都面向web而不是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中,使用

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

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

    {
      "error": {
        "message": "Missing client_id parameter.",
        "type":    "OAuthException",
        "code":    101
      }
    }
    
    更新:当我更改
    access\u令牌时调用
    访问\u令牌!(“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上的桌面/命令行应用程序进行身份验证?

据我所知,如果没有某种端点可以接收来自Facebook的回调,您想要的东西实际上是不可能的

如果您可以从中欺骗oauth令牌,那么使用gem之类的工具上传视频就变得非常简单了

以下是突出的一点:

@graph = Koala::Facebook::API.new(access_token)
@graph.put_video(path_to_my_video)
我在这里为您制作了一个示例项目:

来自facebook:

图形API中的单个视频

要读取视频,请向/Video\u ID发出HTTP GET请求,并使用 用户没有视频权限。这将返回用户拥有的视频 已上载或已添加标签

视频帖子请求应使用graph-Video.facebook.com

所以,如果你想上传视频,你应该上传到graph-video.facebook.com

您还需要将要上载到的用户或个人资料的扩展权限,在这种情况下,当请求当前登录的用户对应用程序授予此类权限时,您需要
video\u upload
仅请求一次

您的端点应该是:

如果您总是想发布到特定用户,则必须将端点部分从
/me
更改为用户ID或页面ID

以下是一个示例(PHP):

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

Settings > Advanced
然后寻找第一个选择:

并启用该开关,以便facebook允许您从桌面或本机应用程序而不是web服务器发布帖子


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

问题是,对于OAuth,您需要一些端点URL,这些URL可以在互联网上为Facebook服务器公开访问,这对于普通客户端PC来说是不可能的,或者是一个支持WebView的桌面应用程序(我认为命令行不是)

Facebook表示,您可以构建桌面客户端登录流,但只能通过所谓的网络视图。因此,您需要像这样调用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会将用户重定向到 上面提到的重定向uri并将访问令牌与 URI片段中的一些其他元数据(如令牌到期时间):

https://www.facebook.com/connect/login_success.html#access_token=ACCESS_TOKEN... 
您的应用程序需要检测此重定向,然后使用您正在使用的操作系统和开发框架提供的机制从URI中读取访问令牌

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

  • 当您想要发布到页面时,获取页面访问令牌并将其存储在本地。这可以通过在

终点。请记住授予“管理页面”和“发布操作”权限

  • 使用cURL()将视频与在步骤1中获得的访问令牌和适当的页面ID一起发布到Graph API,如下所示:
curl-v-0--formtitle={YOUR_title}--form description={YOUR\u description}--form source=@{YOUR\u FULL\u FILE\u PATH} {您的页面\ ID}/视频?访问\令牌={您的访问\令牌}

参考资料:


所以,我终于让它工作了,没有设置web服务器和回调。与直觉相反,诀窍是关闭“桌面应用程序”设置,而不是请求
脱机访问

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
)

错误是{“error”:{“message”:“验证码格式无效”,“type”:“OAutheException”,“code”:100}}您的应用程序是否处于开发模式?似乎该应用程序必须公开才能上传视频。在应用程序详细信息部分(链接下,
是你的应用程序ID),新创建的应用程序的视频部分表示你的应用程序当前处于开发模式。上传视频时必须公开应用程序。如果你重新阅读这个问题,你会注意到这主要是关于使用Perl或Ruby为非web应用程序获取身份验证令牌:“我应该如何使用OAuth向Facebook验证桌面/命令行应用程序?”–这意味着您的PHP代码不仅与语言选择无关,还因为它错误地假设了web界面。你的答案中还有一些好的部分
Settings > Advanced
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}
https://www.facebook.com/connect/login_success.html#access_token=ACCESS_TOKEN... 
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
)