FaradayでSlackにファイルアップロードする

リハビリ記事

目的

SlackにCSVファイルを投げつけたかった

はじめに

以下を参考にSlack Appを作成し、Tokenを取得 qiita.com

files.uploadを読んでみる api.slack.com とりあえずCSVファイルが投げれれば良かったのでsystemで書いてみる

  system("curl -F file=@#{file_path} -F channels=#{channel_id} -F token=#{token} -F initial_comment=#{comment}  https://slack.com/api/files.upload")

書いてみたものの他でも使うかもしれないのでもうちょっとちゃんと書くことにする

Faraday使った実装

lostisland.github.io 不真面目なのでとりあえず楽そうに書いてみる

require "faraday"

class SlackFileUploadService
  def self.file_upload(file_path:, channel_id:, comment:)
    faraday = Faraday.new(url: "https://slack.com")

    token = Token # 取得したtoken
    
    faraday.post("api/files.upload", file: file_parh, channels: channel_id, token: token, initial_comment: comment)
  end
end

SlackFileUploadService.file_upload(file: file_path, channel_id: channel_id, comment: comment)

エラーが返ってきた

{"ok":false,"error":"no_file_data"}

どうやらFilePath投げるだけじゃダメらしい

ファイルの送信方法でググってみる

こちらを見るとFaraday::UploadIO使わないといけないらしい crieit.net

再度チャレンジ

今度はfileで一度Faraday::UploadIOで受けてから実行

require "faraday"

class SlackFileUploadService
  def self.file_upload(file_path:, channel_id:, comment:)
    faraday = Faraday.new(url: "https://slack.com")

    token = Token
    file = Faraday::UploadIO.new(file_path, "text/plain")
    
    faraday.post("api/files.upload", file: file, channels: channel_id, token: token, initial_comment: comment)
  end
end

SlackFileUploadService.file_upload(file: file_path, channel_id: channel_id, comment: comment)

変わらずエラー

{"ok":false,"error":"no_file_data"}

そもそもcurl-Fってなんだと思い調べてみる www.y-hakopro.com

-Fオプション使用時のContent-Typeはデフォルトで「multipart/form-data」が指定される。

ここでmultipart/form-dataというワードを入手した

multipartというワードを入手した状態で改めてfile uploadをググっていると stackoverflow.com どうやらFaraday.newの際に色々指定しなければいけないらしい

指定している内容はググると詳しそうなページが当たった

(たくさんタメになりそうな事書かれていそうなので後で全部読んでおきたい) nekorails.hatenablog.com

再再チャレンジ

require "faraday"

class SlackFileUploadService
  def self.file_upload(file_path:, channel_id:, comment:)
    faraday = Faraday.new(url: "https://slack.com") do |f|
      f.request :multipart
      f.request :url_encoded
      f.adapter Faraday.default_adapter
    end

    token = Token
    file = Faraday::UploadIO.new(file_path, "text/plain")
    
    faraday.post("api/files.upload", file: file, channels: channel_id, token: token, initial_comment: comment)
  end
end

SlackFileUploadService.file_upload(file: file_path, channel_id: channel_id, comment: comment)

成功!

{"ok":true,"file":以下略}

無事SlackにもCSVが投下されました

めでたし