如何通过 ActiveStorage S3 上传在 Rails 中用 twitter gem 发布 jpeg/mp4?

How to tweet a jpeg/mp4 with the twitter gem in Rails through ActiveStorage S3 uploads?

我正在尝试从我的 Rails 应用程序 (7.0.1)、Ruby (3.0.2) 发推文。我正在使用“twitter”gem 和其他人连接 Twitter 帐户并发布到 Twitter。只要我只发推文,一切正常。文本来自“Model.content”。

还有另一个“Model.media”,它是带有“has_one_attached”的附件,我想将其用于将媒体上传到 Twitter。它存储在 AWS S3 中。

这是如何使用 gem 发推文(只是“内容”而不是“Model.content”,因为我是从 Model.rb 本身发推文):

client.update(content) 它可以正常工作并发布到 Twitter。

要通过媒体发布推文,我可以根据 gem:

这样做

client.update_with_media(content, media)

我从 Rails 日志中得到的错误是:

/Users/~/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/activesupport-7.0.1/lib/active_support/core_ext/module/delegation.rb:307:in `method_missing': undefined method `merge' for #<ActiveStorage::Attached::One:0x00007fca71579048 @name="media", @record=#<...">> (NoMethodError)

如果我试试这个:

client.update_with_media(content, Rails.application.routes.url_helpers.rails_blob_path(media, only_path: true))

我从 Rails 日志中得到的错误是(同样发生在 .jpeg 上): /Users/~/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/twitter-7.0.0/lib/twitter/rest/upload_utils.rb:40:in `append_media': undefined method `eof?' for "/rails/active_storage/blobs/redirect/....mp4":String (NoMethodError)

我尝试并寻找了很多解决方案,如果我理解正确的话,它们并不是专门针对这个问题的。我觉得我错过了一件非常小的事情。

解决此问题的最佳方法是什么?如何?

链接: Gem link: https://rubygems.org/gems/twitter

Gem 快速指南:https://github.com/sferik/twitter/blob/master/examples/Update.md#update

根据文档,media 必须是 FileFile 的数组。此方法不支持直接上传,所以你必须先从S3下载文件,然后再上传到twitter。

rails_blob_path returns 一个字符串,这就是它不起作用的原因。此外,此路径是相对于您的应用程序域的,因此您不能直接使用它来引用文件系统上的文件。

ActiveStorage 有一个 open 方法可以生成 Tempfile。幸运的是,它们的行为与常规 File 一样,因此您应该能够将其传递给 update_with_media。你可以像这样使用它:

media.open do |file|
  client.update_with_media(content, file)
end

它将在文件系统上创建一个临时文件。

或者,如果您的文件相对较小(视频可能不是这种情况),您可以使用 download 方法。它将下载文件并将其存储在内存中:

client.update_with_media(content, media.download)

旁注:POST update_with_media is deprecated 不应再使用。