Files
chatwoot/lib/integrations/dyte/processor_service.rb
T

136 lines
4.6 KiB
Ruby

class Integrations::Dyte::ProcessorService
pattr_initialize [:account!, :conversation!]
def create_a_meeting(agent)
raise CustomExceptions::ConversationMessageCreationLocked, conversation if conversation.message_creation_locked?
return missing_realtimekit_credentials_response if realtimekit_credentials_missing?
title = I18n.t('integration_apps.dyte.meeting_name', agent_name: agent.available_name)
response = dyte_client.create_a_meeting(title)
return response if response[:error].present?
meeting = response
message = create_a_dyte_integration_message(meeting, title, agent)
message.push_event_data
end
def add_participant_to_meeting(meeting_id, user, message = nil)
return missing_realtimekit_credentials_response if realtimekit_credentials_missing?
client_id = realtimekit_client_id(user)
participant_id = realtimekit_participant_id(message, client_id)
response = participant_token_response(meeting_id, participant_id)
return response if response[:error].blank?
response = dyte_client.add_participant_to_meeting(meeting_id, client_id, user.name, avatar_url(user))
return store_participant_id_and_return(message, client_id, response) if response[:error].blank?
existing_participant_token_response(meeting_id, client_id, message) || response
end
private
def realtimekit_client_id(user)
"#{user.class.name}:#{user.id}"
end
def store_participant_id_and_return(message, client_id, response)
update_realtimekit_participant_id(message, client_id, response['id']) if response['id'].present?
response
end
def create_a_dyte_integration_message(meeting, title, agent)
@conversation.messages.create!(
{
account_id: conversation.account_id,
inbox_id: conversation.inbox_id,
message_type: :outgoing,
content_type: :integrations,
content: title,
content_attributes: {
type: 'dyte',
data: {
meeting_id: meeting['id']
}
},
sender: agent
}
)
end
def avatar_url(user)
return user.avatar_url if user.avatar_url.present?
"#{ENV.fetch('FRONTEND_URL', nil)}/integrations/slack/user.png"
end
def dyte_hook
@dyte_hook ||= account.hooks.find_by!(app_id: 'dyte')
end
def dyte_client
@dyte_client ||= Dyte.new(*realtimekit_credentials)
end
def participant_token_response(meeting_id, participant_id)
return { error: :participant_id_missing } if participant_id.blank?
dyte_client.refresh_participant_token(meeting_id, participant_id)
end
def existing_participant_token_response(meeting_id, client_id, message)
participant_id = existing_realtimekit_participant_id(meeting_id, client_id)
return if participant_id.blank?
response = dyte_client.refresh_participant_token(meeting_id, participant_id)
update_realtimekit_participant_id(message, client_id, participant_id) if response[:error].blank?
response
end
def existing_realtimekit_participant_id(meeting_id, client_id)
participants = dyte_client.fetch_participants(meeting_id)
return if participants.blank? || participants.is_a?(Hash)
participants.find { |participant| participant['custom_participant_id'].to_s == client_id.to_s }&.dig('id')
end
def realtimekit_participant_id(message, client_id)
integration_message_data(message).dig(:participants, client_id.to_s)
end
def update_realtimekit_participant_id(message, client_id, participant_id)
return if message.blank?
attributes = message.content_attributes.with_indifferent_access
data = (attributes[:data] || {}).with_indifferent_access
participants = (data[:participants] || {}).with_indifferent_access
participants[client_id.to_s] = participant_id
data[:participants] = participants
attributes[:data] = data
message.update_columns(content_attributes: attributes.deep_stringify_keys, updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
rescue StandardError => e
Rails.logger.warn("[dyte] Failed to store RealtimeKit participant ID for message #{message.id}: #{e.class}: #{e.message}")
end
def integration_message_data(message)
return {} if message.blank?
(message.content_attributes.with_indifferent_access[:data] || {}).with_indifferent_access
end
def realtimekit_credentials
credentials = dyte_hook.settings.with_indifferent_access
[credentials[:account_id], credentials[:app_id], credentials[:api_token]]
end
def realtimekit_credentials_missing?
realtimekit_credentials.any?(&:blank?)
end
def missing_realtimekit_credentials_response
{ error: I18n.t('errors.dyte.realtimekit_credentials_required') }
end
end