Class: PolylingoChat::TranslateJob

Inherits:
ApplicationJob
  • Object
show all
Defined in:
lib/generators/polylingo_chat/install/templates/jobs/translate_job.rb

Instance Method Summary collapse

Instance Method Details

#perform(message_id) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/generators/polylingo_chat/install/templates/jobs/translate_job.rb', line 5

def perform(message_id)
  # Find message using namespaced model
  message = PolylingoChat::Message.find_by(id: message_id)
  return unless message

  conversation = message.conversation
  return unless conversation

  # Get all participants except the sender (works with polymorphic associations)
  recipient_participants = conversation.participants.where.not(
    participantable_type: message.sender_type,
    participantable_id: message.sender_id
  )
  recipients = recipient_participants.map(&:participantable)

  # Check if translation is enabled (API key present)
  translation_enabled = PolylingoChat.config.api_key.present?

  # Detect and store the source language
  if translation_enabled
    source_lang = PolylingoChat::Translator.detect_language(message.body)
    message.update_column(:language, source_lang)
  end

  # Store default translation (to default_language) for API consumers
  if translation_enabled
    default_lang = PolylingoChat.config.default_language
    unless source_lang == default_lang
      context = conversation.messages.order(created_at: :asc).last(20).pluck(:body).join("") rescue nil
      default_translation = PolylingoChat::Translator.translate(
        text: message.body,
        from: source_lang,
        to: default_lang,
        context: context
      )
      default_translation = default_translation.value if default_translation.respond_to?(:value)
      message.update_column(:translated_body, default_translation)
    end
  end

  recipients.each do |recipient|
    if translation_enabled
      # Translation enabled - translate message for this specific recipient
      target_lang = recipient.preferred_language || PolylingoChat.config.default_language
      context = conversation.messages.order(created_at: :asc).last(20).pluck(:body).join("") rescue nil

      translated = PolylingoChat::Translator.translate(text: message.body, from: source_lang, to: target_lang, context: context)
      # If translator returns a Future-like, wait
      translated = translated.value if translated.respond_to?(:value)
    else
      # No API key - just use original message (chat-only mode)
      translated = message.body
    end

    # Broadcast to recipient using ActionCable (skip if API-only)
    begin
      if defined?(ActionCable)
        # Broadcast to user-specific channel
        ActionCable.server.broadcast("polylingo_chat_recipient_#{recipient.id}", {
          message: translated,
          original: message.body,
          message_id: message.id,
          sender_id: message.sender_id,
          sender_name: message.sender_name,
          translated: translation_enabled
        })

        # Also broadcast to conversation channel for demo/group chat
        ActionCable.server.broadcast("conversation_#{conversation.id}", {
          message: translated,
          original: message.body,
          message_id: message.id,
          sender_id: message.sender_id,
          sender_name: message.sender_name,
          translated: translation_enabled,
          recipient_id: recipient.id
        })
      end
    rescue StandardError => e
      Rails.logger.error("PolylingoChat: Broadcast failed - #{e.message}")
    end
  end

  message.update_column(:translated, translation_enabled)
rescue StandardError => e
  Rails.logger.error("PolylingoChat: Failed to process translation - #{e.message}")
end