trabajo-afectivo/app/models/cti/caller_id.rb

288 lines
6.6 KiB
Ruby
Raw Normal View History

2016-04-28 13:15:50 +00:00
module Cti
class CallerId < ApplicationModel
self.table_name = 'cti_caller_ids'
DEFAULT_COUNTRY_ID = '49'.freeze
# adopt/orphan matching Cti::Log records
# (see https://github.com/zammad/zammad/issues/2057)
after_commit :update_cti_logs, on: :destroy
after_commit :update_cti_logs_with_fg_optimization, on: :create
2016-04-28 13:15:50 +00:00
=begin
Cti::CallerId.maybe_add(
caller_id: '49123456789',
comment: 'Hairdresser Bob Smith, San Francisco', #optional
level: 'maybe', # known|maybe
user_id: 1, # optional
object: 'Ticket',
o_id: 123,
)
=end
def self.maybe_add(data)
record = find_or_initialize_by(
2016-04-28 13:15:50 +00:00
caller_id: data[:caller_id],
level: data[:level],
object: data[:object],
o_id: data[:o_id],
user_id: data[:user_id],
2016-04-28 13:15:50 +00:00
)
return record if !record.new_record?
2016-12-05 09:19:18 +00:00
record.comment = data[:comment]
record.save!
2016-04-28 13:15:50 +00:00
end
=begin
caller_id_records = Cti::CallerId.lookup('49123456789')
returns
[record1, record2, ...]
=end
def self.lookup(caller_id)
lookup_ids =
['known', 'maybe', nil].lazy.map do |level|
Cti::CallerId.select('MAX(id) as caller_id')
.where({ caller_id: caller_id, level: level }.compact)
.group(:user_id)
.order('caller_id DESC')
.limit(20)
.map(&:caller_id)
end.find(&:present?)
Cti::CallerId.where(id: lookup_ids).order(id: :desc).to_a
2016-04-28 13:15:50 +00:00
end
=begin
Cti::CallerId.build(ticket)
=end
def self.build(record)
map = config
level = nil
model = nil
map.each do |item|
2016-04-28 13:15:50 +00:00
next if item[:model] != record.class
level = item[:level]
model = item[:model]
end
2016-04-28 13:15:50 +00:00
return if !level || !model
build_item(record, model, level)
end
=begin
Cti::CallerId.build_item(record, model, level)
=end
def self.build_item(record, model, level)
# use first customer article
if model == Ticket
article = record.articles.first
return if !article
return if article.sender.name != 'Customer'
record = article
end
# set user id
user_id = record[:created_by_id]
if model == User
user_id = record.id
end
return if !user_id
# get caller ids
caller_ids = []
attributes = record.attributes
2017-11-23 08:09:44 +00:00
attributes.each_value do |value|
2016-04-28 13:15:50 +00:00
next if value.class != String
2017-11-23 08:09:44 +00:00
next if value.blank?
local_caller_ids = Cti::CallerId.extract_numbers(value)
2017-11-23 08:09:44 +00:00
next if local_caller_ids.blank?
2016-04-28 13:15:50 +00:00
caller_ids = caller_ids.concat(local_caller_ids)
end
2016-04-28 13:15:50 +00:00
# search for caller ids to keep
caller_ids_to_add = []
existing_record_ids = Cti::CallerId.where(object: model.to_s, o_id: record.id).pluck(:id)
caller_ids.uniq.each do |caller_id|
existing_record_id = Cti::CallerId.where(
object: model.to_s,
o_id: record.id,
caller_id: caller_id,
level: level,
user_id: user_id,
).pluck(:id)
if existing_record_id[0]
existing_record_ids.delete(existing_record_id[0])
next
end
caller_ids_to_add.push caller_id
end
# delete not longer existing caller ids
existing_record_ids.each do |record_id|
Cti::CallerId.destroy(record_id)
end
# create new caller ids
caller_ids_to_add.each do |caller_id|
2016-04-28 13:15:50 +00:00
Cti::CallerId.maybe_add(
caller_id: caller_id,
level: level,
object: model.to_s,
o_id: record.id,
user_id: user_id,
)
end
2016-04-28 13:15:50 +00:00
true
end
=begin
Cti::CallerId.rebuild
=end
def self.rebuild
transaction do
delete_all
config.each do |item|
level = item[:level]
model = item[:model]
item[:model].find_each(batch_size: 500) do |record|
build_item(record, model, level)
end
end
end
2016-04-28 13:15:50 +00:00
end
=begin
Cti::CallerId.config
returns
[
{
model: User,
level: 'known',
},
{
model: Ticket,
level: 'maybe',
},
]
=end
def self.config
[
{
model: User,
level: 'known',
},
{
model: Ticket,
level: 'maybe',
},
]
end
=begin
caller_ids = Cti::CallerId.extract_numbers('...')
2016-04-28 13:15:50 +00:00
returns
['49123456789', '49987654321']
=end
def self.extract_numbers(text)
# see specs for example
return [] if !text.is_a?(String)
text.scan(/([\d|\s|\-|\(|\)]{6,26})/).map do |match|
normalize_number(match[0])
end
end
2016-04-28 13:15:50 +00:00
def self.normalize_number(number)
number = number.gsub(/[\s-]/, '')
number.gsub!(/^(00)?(\+?\d\d)\(0?(\d*)\)/, '\\1\\2\\3')
number.gsub!(/\D/, '')
case number
when /^00/
number[2..-1]
when /^0/
DEFAULT_COUNTRY_ID + number[1..-1]
else
number
end
2016-04-28 13:15:50 +00:00
end
def self.get_comment_preferences(caller_id, direction)
from_comment_known = ''
from_comment_maybe = ''
preferences_known = {}
preferences_known[direction] = []
preferences_maybe = {}
preferences_maybe[direction] = []
lookup(extract_numbers(caller_id)).each do |record|
if record.level == 'known'
2017-09-08 08:28:34 +00:00
preferences_known[direction].push record.attributes
else
2017-09-08 08:28:34 +00:00
preferences_maybe[direction].push record.attributes
end
comment = ''
if record.user_id
user = User.lookup(id: record.user_id)
if user
comment += user.fullname
end
2017-11-23 08:09:44 +00:00
elsif record.comment.present?
comment += record.comment
end
if record.level == 'known'
2017-11-23 08:09:44 +00:00
if from_comment_known.present?
from_comment_known += ','
end
from_comment_known += comment
else
2017-11-23 08:09:44 +00:00
if from_comment_maybe.present?
from_comment_maybe += ','
end
from_comment_maybe += comment
end
end
2017-11-23 08:09:44 +00:00
return [from_comment_known, preferences_known] if from_comment_known.present?
return ["maybe #{from_comment_maybe}", preferences_maybe] if from_comment_maybe.present?
nil
end
def update_cti_logs
return if object != 'User'
UpdateCtiLogsByCallerJob.perform_later(caller_id)
end
def update_cti_logs_with_fg_optimization
return if object != 'User'
return if level != 'known'
UpdateCtiLogsByCallerJob.perform_now(caller_id, limit: 20)
UpdateCtiLogsByCallerJob.perform_later(caller_id, limit: 40, offset: 20)
end
2016-04-28 13:15:50 +00:00
end
end