caller_id.rb 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. module Cti
  2. class CallerId < ApplicationModel
  3. self.table_name = 'cti_caller_ids'
  4. DEFAULT_COUNTRY_ID = '49'.freeze
  5. =begin
  6. Cti::CallerId.maybe_add(
  7. caller_id: '49123456789',
  8. comment: 'Hairdresser Bob Smith, San Francisco', #optional
  9. level: 'maybe', # known|maybe
  10. user_id: 1, # optional
  11. object: 'Ticket',
  12. o_id: 123,
  13. )
  14. =end
  15. def self.maybe_add(data)
  16. record = find_or_initialize_by(
  17. caller_id: data[:caller_id],
  18. level: data[:level],
  19. object: data[:object],
  20. o_id: data[:o_id],
  21. user_id: data[:user_id],
  22. )
  23. return record if !record.new_record?
  24. record.comment = data[:comment]
  25. record.save!
  26. end
  27. =begin
  28. caller_id_records = Cti::CallerId.lookup('49123456789')
  29. returns
  30. [record1, record2, ...]
  31. =end
  32. def self.lookup(caller_id)
  33. result = []
  34. ['known', 'maybe', nil].each { |level|
  35. search_params = {
  36. caller_id: caller_id,
  37. }
  38. if level
  39. search_params[:level] = level
  40. end
  41. result = Cti::CallerId.where(search_params).group(:user_id, :id).order(id: 'DESC').limit(20)
  42. break if result.present?
  43. }
  44. result
  45. end
  46. =begin
  47. Cti::CallerId.build(ticket)
  48. =end
  49. def self.build(record)
  50. map = config
  51. level = nil
  52. model = nil
  53. map.each { |item|
  54. next if item[:model] != record.class
  55. level = item[:level]
  56. model = item[:model]
  57. }
  58. return if !level || !model
  59. build_item(record, model, level)
  60. end
  61. =begin
  62. Cti::CallerId.build_item(record, model, level)
  63. =end
  64. def self.build_item(record, model, level)
  65. # use first customer article
  66. if model == Ticket
  67. article = record.articles.first
  68. return if !article
  69. return if article.sender.name != 'Customer'
  70. record = article
  71. end
  72. # set user id
  73. user_id = record[:created_by_id]
  74. if model == User
  75. user_id = record.id
  76. end
  77. return if !user_id
  78. # get caller ids
  79. caller_ids = []
  80. attributes = record.attributes
  81. attributes.each { |_attribute, value|
  82. next if value.class != String
  83. next if value.empty?
  84. local_caller_ids = Cti::CallerId.extract_numbers(value)
  85. next if local_caller_ids.empty?
  86. caller_ids = caller_ids.concat(local_caller_ids)
  87. }
  88. # store caller ids
  89. Cti::CallerId.where(object: model.to_s, o_id: record.id).destroy_all
  90. caller_ids.each { |caller_id|
  91. Cti::CallerId.maybe_add(
  92. caller_id: caller_id,
  93. level: level,
  94. object: model.to_s,
  95. o_id: record.id,
  96. user_id: user_id,
  97. )
  98. }
  99. true
  100. end
  101. =begin
  102. Cti::CallerId.rebuild
  103. =end
  104. def self.rebuild
  105. transaction do
  106. delete_all
  107. config.each { |item|
  108. level = item[:level]
  109. model = item[:model]
  110. item[:model].find_each(batch_size: 500) do |record|
  111. build_item(record, model, level)
  112. end
  113. }
  114. end
  115. end
  116. =begin
  117. Cti::CallerId.config
  118. returns
  119. [
  120. {
  121. model: User,
  122. level: 'known',
  123. },
  124. {
  125. model: Ticket,
  126. level: 'maybe',
  127. },
  128. ]
  129. =end
  130. def self.config
  131. [
  132. {
  133. model: User,
  134. level: 'known',
  135. },
  136. {
  137. model: Ticket,
  138. level: 'maybe',
  139. },
  140. ]
  141. end
  142. =begin
  143. caller_ids = Cti::CallerId.extract_numbers('...')
  144. returns
  145. ['49123456789', '49987654321']
  146. =end
  147. def self.extract_numbers(text)
  148. # see specs for example
  149. return [] if !text.is_a?(String)
  150. text.scan(/([\d|\s|\-|\(|\)]{6,26})/).map do |match|
  151. normalize_number(match[0])
  152. end
  153. end
  154. def self.normalize_number(number)
  155. number = number.gsub(/[\s-]/, '')
  156. number.gsub!(/^(00)?(\+?\d\d)\(0?(\d*)\)/, '\\1\\2\\3')
  157. number.gsub!(/\D/, '')
  158. case number
  159. when /^00/
  160. number[2..-1]
  161. when /^0/
  162. DEFAULT_COUNTRY_ID + number[1..-1]
  163. else
  164. number
  165. end
  166. end
  167. def self.get_comment_preferences(caller_id, direction)
  168. from_comment_known = ''
  169. from_comment_maybe = ''
  170. preferences_known = {}
  171. preferences_known[direction] = []
  172. preferences_maybe = {}
  173. preferences_maybe[direction] = []
  174. lookup(extract_numbers(caller_id)).each { |record|
  175. if record.level == 'known'
  176. preferences_known[direction].push record
  177. else
  178. preferences_maybe[direction].push record
  179. end
  180. comment = ''
  181. if record.user_id
  182. user = User.lookup(id: record.user_id)
  183. if user
  184. comment += user.fullname
  185. end
  186. elsif !record.comment.empty?
  187. comment += record.comment
  188. end
  189. if record.level == 'known'
  190. if !from_comment_known.empty?
  191. from_comment_known += ','
  192. end
  193. from_comment_known += comment
  194. else
  195. if !from_comment_maybe.empty?
  196. from_comment_maybe += ','
  197. end
  198. from_comment_maybe += comment
  199. end
  200. }
  201. return [from_comment_known, preferences_known] if !from_comment_known.empty?
  202. return ["maybe #{from_comment_maybe}", preferences_maybe] if !from_comment_maybe.empty?
  203. nil
  204. end
  205. end
  206. end