iachat/enterprise/app/services/captain/hermes/reply_context_builder.rb

96 lines
2.7 KiB
Ruby

class Captain::Hermes::ReplyContextBuilder
def initialize(message:, conversation:)
@message = message
@conversation = conversation
end
def perform
return nil if reply_to_external_id.blank?
{
external_id: reply_to_external_id,
found: quoted_message.present?,
quoted_message: quoted_message_snapshot
}.compact
end
def wrap_message(current_text)
return current_text if reply_context.blank?
"#{formatted_reply_context}\n\n[RESPOSTA ATUAL DO CLIENTE]\n#{current_text}"
end
private
attr_reader :message, :conversation
def reply_context
@reply_context ||= perform
end
def formatted_reply_context
return missing_reply_context unless reply_context[:found]
quoted = reply_context[:quoted_message]
quoted_content = quoted[:content].presence || quoted[:attachment_summary].presence || '[mensagem sem texto]'
<<~TEXT.strip
[CONTEXTO DE RESPOSTA DO WHATSAPP]
O cliente respondeu citando uma mensagem anterior.
Interprete a resposta atual como referência direta a essa mensagem citada.
Mensagem citada (#{quoted[:sender_label]}, #{quoted[:created_at]}): #{quoted_content}
TEXT
end
def missing_reply_context
<<~TEXT.strip
[CONTEXTO DE RESPOSTA DO WHATSAPP]
O cliente respondeu citando uma mensagem anterior, mas o Chatwoot não encontrou o conteúdo da mensagem citada.
ID externo citado: #{reply_context[:external_id]}
TEXT
end
def reply_to_external_id
@reply_to_external_id ||= message.in_reply_to_external_id.presence ||
message.content_attributes.to_h['in_reply_to_external_id'].presence ||
message.content_attributes.to_h[:in_reply_to_external_id].presence
end
def quoted_message
@quoted_message ||= conversation.messages.find_by(source_id: reply_to_external_id)
end
def quoted_message_snapshot
return nil if quoted_message.blank?
{
id: quoted_message.id,
external_id: quoted_message.source_id,
message_type: quoted_message.message_type,
sender_label: sender_label,
sender_name: quoted_message.sender&.available_name,
content: quoted_message_content,
attachment_summary: attachment_summary,
created_at: quoted_message.created_at&.iso8601
}.compact
end
def sender_label
return 'cliente' if quoted_message.incoming?
return 'atendente/Hermes' if quoted_message.outgoing?
'sistema'
end
def quoted_message_content
quoted_message.content.to_s.truncate(1200)
end
def attachment_summary
return nil if quoted_message.attachments.blank?
types = quoted_message.attachments.filter_map(&:file_type)
"anexos: #{types.join(', ')}"
end
end