Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
181
research/chatwoot/app/services/csat_survey_service.rb
Normal file
181
research/chatwoot/app/services/csat_survey_service.rb
Normal file
@@ -0,0 +1,181 @@
|
||||
class CsatSurveyService
|
||||
pattr_initialize [:conversation!]
|
||||
|
||||
def perform
|
||||
return unless should_send_csat_survey?
|
||||
|
||||
if whatsapp_channel? && template_available_and_approved?
|
||||
send_whatsapp_template_survey
|
||||
elsif inbox.twilio_whatsapp? && twilio_template_available_and_approved?
|
||||
send_twilio_whatsapp_template_survey
|
||||
elsif within_messaging_window?
|
||||
::MessageTemplates::Template::CsatSurvey.new(conversation: conversation).perform
|
||||
else
|
||||
create_csat_not_sent_activity_message
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
delegate :inbox, :contact, to: :conversation
|
||||
|
||||
def should_send_csat_survey?
|
||||
conversation_allows_csat? && csat_enabled? && !csat_already_sent? && csat_allowed_by_survey_rules?
|
||||
end
|
||||
|
||||
def conversation_allows_csat?
|
||||
conversation.resolved? && !conversation.tweet?
|
||||
end
|
||||
|
||||
def csat_enabled?
|
||||
inbox.csat_survey_enabled?
|
||||
end
|
||||
|
||||
def csat_already_sent?
|
||||
conversation.messages.where(content_type: :input_csat).present?
|
||||
end
|
||||
|
||||
def within_messaging_window?
|
||||
conversation.can_reply?
|
||||
end
|
||||
|
||||
def csat_allowed_by_survey_rules?
|
||||
return true unless survey_rules_configured?
|
||||
|
||||
labels = conversation.label_list
|
||||
return true if rule_values.empty?
|
||||
|
||||
case rule_operator
|
||||
when 'contains'
|
||||
rule_values.any? { |label| labels.include?(label) }
|
||||
when 'does_not_contain'
|
||||
rule_values.none? { |label| labels.include?(label) }
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def survey_rules_configured?
|
||||
return false if csat_config.blank?
|
||||
return false if csat_config['survey_rules'].blank?
|
||||
|
||||
rule_values.any?
|
||||
end
|
||||
|
||||
def rule_operator
|
||||
csat_config.dig('survey_rules', 'operator') || 'contains'
|
||||
end
|
||||
|
||||
def rule_values
|
||||
csat_config.dig('survey_rules', 'values') || []
|
||||
end
|
||||
|
||||
def whatsapp_channel?
|
||||
inbox.channel_type == 'Channel::Whatsapp'
|
||||
end
|
||||
|
||||
def template_available_and_approved?
|
||||
template_config = inbox.csat_config&.dig('template')
|
||||
return false unless template_config
|
||||
|
||||
template_name = template_config['name'] || CsatTemplateNameService.csat_template_name(inbox.id)
|
||||
|
||||
status_result = inbox.channel.provider_service.get_template_status(template_name)
|
||||
|
||||
status_result[:success] && status_result[:template][:status] == 'APPROVED'
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "Error checking CSAT template status: #{e.message}"
|
||||
false
|
||||
end
|
||||
|
||||
def twilio_template_available_and_approved?
|
||||
template_config = inbox.csat_config&.dig('template')
|
||||
return false unless template_config
|
||||
|
||||
content_sid = template_config['content_sid']
|
||||
return false unless content_sid
|
||||
|
||||
template_service = Twilio::CsatTemplateService.new(inbox.channel)
|
||||
status_result = template_service.get_template_status(content_sid)
|
||||
|
||||
status_result[:success] && status_result[:template][:status] == 'approved'
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "Error checking Twilio CSAT template status: #{e.message}"
|
||||
false
|
||||
end
|
||||
|
||||
def send_whatsapp_template_survey
|
||||
template_config = inbox.csat_config&.dig('template')
|
||||
template_name = template_config['name'] || CsatTemplateNameService.csat_template_name(inbox.id)
|
||||
|
||||
phone_number = conversation.contact_inbox.source_id
|
||||
template_info = build_template_info(template_name, template_config)
|
||||
message = build_csat_message
|
||||
|
||||
message_id = inbox.channel.provider_service.send_template(phone_number, template_info, message)
|
||||
|
||||
message.update!(source_id: message_id) if message_id.present?
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "Error sending WhatsApp CSAT template for conversation #{conversation.id}: #{e.message}"
|
||||
end
|
||||
|
||||
def build_template_info(template_name, template_config)
|
||||
{
|
||||
name: template_name,
|
||||
lang_code: template_config['language'] || 'en',
|
||||
parameters: [
|
||||
{
|
||||
type: 'button',
|
||||
sub_type: 'url',
|
||||
index: '0',
|
||||
parameters: [{ type: 'text', text: conversation.uuid }]
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
def build_csat_message
|
||||
conversation.messages.build(
|
||||
account: conversation.account,
|
||||
inbox: inbox,
|
||||
message_type: :outgoing,
|
||||
content: inbox.csat_config&.dig('message') || 'Please rate this conversation',
|
||||
content_type: :input_csat
|
||||
)
|
||||
end
|
||||
|
||||
def csat_config
|
||||
inbox.csat_config || {}
|
||||
end
|
||||
|
||||
def send_twilio_whatsapp_template_survey
|
||||
template_config = inbox.csat_config&.dig('template')
|
||||
content_sid = template_config['content_sid']
|
||||
|
||||
phone_number = conversation.contact_inbox.source_id
|
||||
content_variables = { '1' => conversation.uuid }
|
||||
message = build_csat_message
|
||||
|
||||
send_service = Twilio::SendOnTwilioService.new(message: message)
|
||||
result = send_service.send_csat_template_message(
|
||||
phone_number: phone_number,
|
||||
content_sid: content_sid,
|
||||
content_variables: content_variables
|
||||
)
|
||||
|
||||
message.update!(source_id: result[:message_id]) if result[:success] && result[:message_id].present?
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "Error sending Twilio WhatsApp CSAT template for conversation #{conversation.id}: #{e.message}"
|
||||
end
|
||||
|
||||
def create_csat_not_sent_activity_message
|
||||
content = I18n.t('conversations.activity.csat.not_sent_due_to_messaging_window')
|
||||
activity_message_params = {
|
||||
account_id: conversation.account_id,
|
||||
inbox_id: conversation.inbox_id,
|
||||
message_type: :activity,
|
||||
content: content
|
||||
}
|
||||
::Conversations::ActivityMessageJob.perform_later(conversation, activity_message_params) if content
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user