# == Schema Information # # Table name: attachments # # id :integer not null, primary key # coordinates_lat :float default(0.0) # coordinates_long :float default(0.0) # extension :string # external_url :string # fallback_title :string # file_type :integer default("image") # meta :jsonb # created_at :datetime not null # updated_at :datetime not null # account_id :integer not null # message_id :integer not null # # Indexes # # index_attachments_on_account_id (account_id) # index_attachments_on_message_id (message_id) # class Attachment < ApplicationRecord include Rails.application.routes.url_helpers ACCEPTABLE_FILE_TYPES = %w[ text/csv text/plain text/rtf application/json application/pdf application/zip application/x-7z-compressed application/vnd.rar application/x-tar application/msword application/vnd.ms-excel application/vnd.ms-powerpoint application/rtf application/vnd.oasis.opendocument.text application/vnd.openxmlformats-officedocument.presentationml.presentation application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.openxmlformats-officedocument.wordprocessingml.document ].freeze belongs_to :account belongs_to :message has_one_attached :file before_save :set_extension validate :acceptable_file validates :external_url, length: { maximum: Limits::URL_LENGTH_LIMIT } enum file_type: { :image => 0, :audio => 1, :video => 2, :file => 3, :location => 4, :fallback => 5, :share => 6, :story_mention => 7, :contact => 8, :ig_reel => 9, :ig_post => 10, :ig_story => 11, :embed => 12 } def push_event_data return unless file_type base_data.merge(metadata_for_file_type) end # NOTE: the URl returned does a 301 redirect to the actual file def file_url file.attached? ? url_for(file) : '' end # NOTE: for External services use this methods since redirect doesn't work effectively in a lot of cases def download_url ActiveStorage::Current.url_options = Rails.application.routes.default_url_options if ActiveStorage::Current.url_options.blank? file.attached? ? file.blob.url : '' end def thumb_url return '' unless file.attached? && image? begin url_for(file.representation(resize_to_fill: [250, nil])) rescue ActiveStorage::UnrepresentableError => e Rails.logger.warn "Unrepresentable image attachment: #{id} (#{file.filename}) - #{e.message}" '' end end def with_attached_file? [:image, :audio, :video, :file].include?(file_type.to_sym) end private def metadata_for_file_type case file_type.to_sym when :location location_metadata when :fallback fallback_data when :contact contact_metadata when :audio audio_metadata when :embed embed_data else file.attached? ? file_metadata : { data_url: external_url, thumb_url: '' } end end def embed_data { data_url: external_url } end def audio_metadata audio_file_data = base_data.merge(file_metadata) audio_file_data.merge( { # ActiveStorage's redirect endpoint defaults to Content-Disposition: attachment, # which makes