class Integrations::Dialogflow::ProcessorService pattr_initialize [:event_name!, :hook!, :event_data!] def perform message = event_data[:message] return if message.private? return unless processable_message?(message) return unless message.conversation.pending? content = message_content(message) response = get_dialogflow_response(message.conversation.contact_inbox.source_id, content) if content.present? process_response(message, response) if response.present? end private def message_content(message) # TODO: might needs to change this to a way that we fetch the updated value from event data instead # cause the message.updated event could be that that the message was deleted return message.content_attributes['submitted_values']&.first&.dig('value') if event_name == 'message.updated' message.content end def processable_message?(message) # TODO: change from reportable and create a dedicated method for this? return unless message.reportable? return if message.outgoing? && !processable_outgoing_message?(message) true end def processable_outgoing_message?(message) event_name == 'message.updated' && ['input_select'].include?(message.content_type) end def get_dialogflow_response(session_id, message) Google::Cloud::Dialogflow.configure { |config| config.credentials = hook.settings['credentials'] } session_client = Google::Cloud::Dialogflow.sessions session = session_client.session_path project: hook.settings['project_id'], session: session_id query_input = { text: { text: message, language_code: 'en-US' } } session_client.detect_intent session: session, query_input: query_input end def process_response(message, response) fulfillment_messages = response.query_result['fulfillment_messages'] fulfillment_messages.each do |fulfillment_message| content_params = generate_content_params(fulfillment_message) if content_params['action'].present? process_action(message, content_params['action']) else create_conversation(message, content_params) end end end def generate_content_params(fulfillment_message) text_response = fulfillment_message['text'].to_h content_params = { content: text_response[:text].first } if text_response[:text].present? content_params ||= fulfillment_message['payload'].to_h content_params end def create_conversation(message, content_params) return if content_params.blank? conversation = message.conversation conversation.messages.create(content_params.merge({ message_type: :outgoing, account_id: conversation.account_id, inbox_id: conversation.inbox_id })) end def process_action(message, action) case action when 'handoff' message.conversation.open! when 'resolve' message.conversation.resolved! end end end