Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
131
research/chatwoot/app/models/campaign.rb
Normal file
131
research/chatwoot/app/models/campaign.rb
Normal file
@@ -0,0 +1,131 @@
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: campaigns
|
||||
#
|
||||
# id :bigint not null, primary key
|
||||
# audience :jsonb
|
||||
# campaign_status :integer default("active"), not null
|
||||
# campaign_type :integer default("ongoing"), not null
|
||||
# description :text
|
||||
# enabled :boolean default(TRUE)
|
||||
# message :text not null
|
||||
# scheduled_at :datetime
|
||||
# template_params :jsonb
|
||||
# title :string not null
|
||||
# trigger_only_during_business_hours :boolean default(FALSE)
|
||||
# trigger_rules :jsonb
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :bigint not null
|
||||
# display_id :integer not null
|
||||
# inbox_id :bigint not null
|
||||
# sender_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_campaigns_on_account_id (account_id)
|
||||
# index_campaigns_on_campaign_status (campaign_status)
|
||||
# index_campaigns_on_campaign_type (campaign_type)
|
||||
# index_campaigns_on_inbox_id (inbox_id)
|
||||
# index_campaigns_on_scheduled_at (scheduled_at)
|
||||
#
|
||||
class Campaign < ApplicationRecord
|
||||
include UrlHelper
|
||||
validates :account_id, presence: true
|
||||
validates :inbox_id, presence: true
|
||||
validates :title, presence: true
|
||||
validates :message, presence: true
|
||||
validate :validate_campaign_inbox
|
||||
validate :validate_url
|
||||
validate :prevent_completed_campaign_from_update, on: :update
|
||||
validate :sender_must_belong_to_account
|
||||
validate :inbox_must_belong_to_account
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :inbox
|
||||
belongs_to :sender, class_name: 'User', optional: true
|
||||
|
||||
enum campaign_type: { ongoing: 0, one_off: 1 }
|
||||
# TODO : enabled attribute is unneccessary . lets move that to the campaign status with additional statuses like draft, disabled etc.
|
||||
enum campaign_status: { active: 0, completed: 1 }
|
||||
|
||||
has_many :conversations, dependent: :nullify, autosave: true
|
||||
|
||||
before_validation :ensure_correct_campaign_attributes
|
||||
after_commit :set_display_id, unless: :display_id?
|
||||
|
||||
def trigger!
|
||||
return unless one_off?
|
||||
return if completed?
|
||||
|
||||
execute_campaign
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def execute_campaign
|
||||
case inbox.inbox_type
|
||||
when 'Twilio SMS'
|
||||
Twilio::OneoffSmsCampaignService.new(campaign: self).perform
|
||||
when 'Sms'
|
||||
Sms::OneoffSmsCampaignService.new(campaign: self).perform
|
||||
when 'Whatsapp'
|
||||
Whatsapp::OneoffCampaignService.new(campaign: self).perform if account.feature_enabled?(:whatsapp_campaign)
|
||||
end
|
||||
end
|
||||
|
||||
def set_display_id
|
||||
reload
|
||||
end
|
||||
|
||||
def validate_campaign_inbox
|
||||
return unless inbox
|
||||
|
||||
errors.add :inbox, 'Unsupported Inbox type' unless ['Website', 'Twilio SMS', 'Sms', 'Whatsapp'].include? inbox.inbox_type
|
||||
end
|
||||
|
||||
# TO-DO we clean up with better validations when campaigns evolve into more inboxes
|
||||
def ensure_correct_campaign_attributes
|
||||
return if inbox.blank?
|
||||
|
||||
if ['Twilio SMS', 'Sms', 'Whatsapp'].include?(inbox.inbox_type)
|
||||
self.campaign_type = 'one_off'
|
||||
self.scheduled_at ||= Time.now.utc
|
||||
else
|
||||
self.campaign_type = 'ongoing'
|
||||
self.scheduled_at = nil
|
||||
end
|
||||
end
|
||||
|
||||
def validate_url
|
||||
return unless trigger_rules['url']
|
||||
|
||||
use_http_protocol = trigger_rules['url'].starts_with?('http://') || trigger_rules['url'].starts_with?('https://')
|
||||
errors.add(:url, 'invalid') if inbox.inbox_type == 'Website' && !use_http_protocol
|
||||
end
|
||||
|
||||
def inbox_must_belong_to_account
|
||||
return unless inbox
|
||||
|
||||
return if inbox.account_id == account_id
|
||||
|
||||
errors.add(:inbox_id, 'must belong to the same account as the campaign')
|
||||
end
|
||||
|
||||
def sender_must_belong_to_account
|
||||
return unless sender
|
||||
|
||||
return if account.users.exists?(id: sender.id)
|
||||
|
||||
errors.add(:sender_id, 'must belong to the same account as the campaign')
|
||||
end
|
||||
|
||||
def prevent_completed_campaign_from_update
|
||||
errors.add :status, 'The campaign is already completed' if !campaign_status_changed? && completed?
|
||||
end
|
||||
|
||||
# creating db triggers
|
||||
trigger.before(:insert).for_each(:row) do
|
||||
"NEW.display_id := nextval('camp_dpid_seq_' || NEW.account_id);"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user