182 lines
5.3 KiB
Ruby
182 lines
5.3 KiB
Ruby
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
|