136 lines
4.6 KiB
Ruby
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
|