4

我正在开发一个 Rails 应用程序,它使用 OmniAuth 为我的用户收集 Oauth/OAuth2 凭据,然后代表他们发布到这些服务。

创建简单的帖子来更新状态提要效果很好。现在我需要上传文件了。Facebook 说“要发布照片,请发出带有照片文件附件作为 multipart/form-data 的 POST 请求。” http://developers.facebook.com/docs/reference/api/photo/

所以这就是我想要做的:

我在这里实现了这个模块:Ruby: How to post a file via HTTP as multipart/form-data? 获取标题和数据...

if appearance.post.post_attachment_content_type.to_s.include?('image')

  fbpost = "https://graph.facebook.com/me/photos"

  data, headers = Multipart::Post.prepare_query("title" => appearance.post.post_attachment_file_name  , "document" => File.read(appearance.post.post_attachment.path))

  paramsarray = {:source=>data, :message=> appearance.post.content}
  response = access_token.request(:post, fbpost, paramsarray, headers)
  appearance.result = response
  appearance.save
end

我但我得到一个 OAuth2::HTTPError - HTTP 400 错误

任何帮助都是难以置信的......正如我所见,将文件上传到 SoundCloud 也需要此信息。

谢谢,

标记

4

2 回答 2

3

我自己也在为此苦苦挣扎。Faraday 支持 oauth2 库的 HTTP 交互。通过一些配置,它支持开箱即用的上传文件。第一步是在建立连接时添加适当的法拉第中间件。我的代码中的一个例子:

OAuth2::Client.new client_id, secret, site: site do |stack|
  stack.request :multipart
  stack.request :url_encoded
  stack.adapter  Faraday.default_adapter
end

这为法拉第连接添加了多部分编码支持。接下来,在对访问令牌对象发出请求时,您要使用 Faraday::UploadIO 对象。所以:

upload = Faraday::UploadIO.new io, mime_type, filename
access_token.post('some/url', params: {url: 'params'}, body: {file: upload})

在上面的代码中:

io - 要上传的文件的 IO 对象。可以是 File 对象甚至是 StringIO。

mime_type - 您正在上传的文件的 mime 类型。您可以尝试检测此服务器端,或者如果用户将文件上传给您,您应该能够从他们的请求中提取 mime 类型。

文件名- 什么正在调用您正在上传的文件。这也可以由您自己的选择来确定,或者您可以使用上传文件的用户调用它的任何内容。

some/url - 将其替换为您要发布到的 URL

{url: 'params'} - 将其替换为您要提供的任何 URL 参数

{file: upload} - 将其替换为您的多部分表单数据。显然,一个(或多个)键/值对应该有一个文件上传实例。

于 2014-04-28T20:57:30.427 回答
0

我实际上正在成功地使用此代码在 fb 页面上上传照片:

dir = Dir.pwd.concat("/public/system/posts/images")
fb_url = URI.parse("https://graph.facebook.com/#{@page_id}/photos")
img = File.open("myfile.jpg")
req = Net::HTTP::Post::Multipart.new(
  "#{fb_url.path}?access_token=#{@token}", 
  "source" => UploadIO.new(img, "application/jpg", img.path),
  "message" => "some messsage"
) 
n = Net::HTTP.new(fb_url.host, fb_url.port)
n.use_ssl = true
n.verify_mode = OpenSSL::SSL::VERIFY_NONE
n.start do |http|
  @result = http.request(req)
end
于 2013-04-29T06:28:09.143 回答