# frozen_string_literal: true require "faraday" require "faraday/multipart" require_relative "request" require_relative '../resource/media_types' module WhatsappSdk module Api class Medias < Request class FileNotFoundError < StandardError attr_reader :file_path def initialize(file_path:) @file_path = file_path message = "Couldn't find file_path: #{file_path}" super(message) end end class InvalidMediaTypeError < StandardError attr_reader :media_type def initialize(media_type:) @media_type = media_type message = "Invalid Media Type #{media_type}. See the supported types in the official documentation " \ "https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types." super(message) end end # Get Media by ID. # # @param media_id [String] Media Id. # @return [Resource::Media] Media object. def get(media_id:) response = send_request( http_method: "get", endpoint: "/#{media_id}" ) Resource::Media.from_hash(response) end def media(media_id:) warn "[DEPRECATION] `media` is deprecated. Please use `get` instead." get(media_id: media_id) end # Download Media by URL. # # @param url URL. # @param file_path [String] The file_path to download the media e.g. "tmp/downloaded_image.png". # @param media_type [String] The media type e.g. "audio/mp4". See possible types in the official # documentation https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types, # but note that the API may allow more depending on the client. # @return [Boolean] Whether the media was downloaded successfully. def download(url:, file_path:, media_type:) # Allow download of unsupported media types, since Cloud API may decide to let it through. # https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk/discussions/127 # raise InvalidMediaTypeError.new(media_type: media_type) unless valid_media_type?(media_type) content_type_header = map_media_type_to_content_type_header(media_type) response = download_file(url: url, file_path: file_path, content_type_header: content_type_header) return true if response.code.to_i == 200 begin body = JSON.parse(response.body) rescue JSON::ParserError body = { "message" => response.body } end raise Api::Responses::HttpResponseError.new(http_status: response.code, body: body) end # Upload a media. # @param sender_id [Integer] Sender' phone number. # @param file_path [String] Path to the file stored in your local directory. For example: "tmp/whatsapp.png". # @param type [String] Media type e.g. text/plain, video/3gp, image/jpeg, image/png. For more information, # see the official documentation https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#supported-media-types. # # @return [Api::Responses::IdResponse] IdResponse object. def upload(sender_id:, file_path:, type:, headers: {}) raise FileNotFoundError.new(file_path: file_path) unless File.file?(file_path) params = { messaging_product: "whatsapp", file: Faraday::FilePart.new(file_path, type), type: type } response = send_request( http_method: "post", endpoint: "#{sender_id}/media", params: params, headers: headers, multipart: true ) Api::Responses::IdResponse.new(response["id"]) end # Delete a Media by ID. # # @param media_id [String] Media Id. # @return [Boolean] Whether the media was deleted successfully. def delete(media_id:) response = send_request( http_method: "delete", endpoint: "/#{media_id}" ) Api::Responses::SuccessResponse.success_response?(response: response) end private def map_media_type_to_content_type_header(media_type) # Media type maps 1:1 to the content-type header. # The list of supported types are in MediaTypes::SUPPORTED_TYPES. # It uses the media type defined by IANA https://www.iana.org/assignments/media-types media_type end def valid_media_type?(media_type) Resource::MediaTypes::SUPPORTED_MEDIA_TYPES.include?(media_type) end end end end