chatwoot-develop/app/services/jasmine/vision_service.rb

68 lines
1.6 KiB
Ruby

# frozen_string_literal: true
require 'openai'
require 'base64'
class Jasmine::VisionService
attr_reader :attachment
def initialize(attachment:)
@attachment = attachment
end
def perform
return nil unless attachment.image?
api_key = ENV.fetch('OPENAI_API_KEY', nil)
return nil if api_key.blank?
client = OpenAI::Client.new(access_token: api_key)
image_data = get_image_data
return nil if image_data.blank?
response = client.chat(
parameters: {
model: 'gpt-4o-mini',
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Descreva de forma curta e objetiva o que você vê nesta imagem para um sistema de atendimento.' },
image_data
]
}
],
max_tokens: 300
}
)
response.dig('choices', 0, 'message', 'content')
rescue StandardError => e
Rails.logger.error "[Jasmine::VisionService] Failed to analyze image: #{e.message}"
nil
end
private
def get_image_data
# Always return base64 for better compatibility (OpenAI can reach it even if local)
# and it avoids issues with signed URL expiration or private buckets.
{
type: 'image_url',
image_url: {
url: "data:#{attachment.file.content_type};base64,#{encode_image}"
}
}
rescue StandardError => e
Rails.logger.error "[Jasmine::VisionService] Data encoding failed: #{e.message}"
nil
end
def encode_image
attachment.file.blob.open do |file|
Base64.strict_encode64(file.read)
end
end
end