base.rb 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Cti::Driver::Base
  3. def initialize(params = {})
  4. @config = params[:config] || config
  5. @params = mapping(params[:params])
  6. end
  7. def mapping(params)
  8. params
  9. end
  10. def config
  11. {}
  12. end
  13. def process
  14. # validate directions
  15. result = direction_check
  16. return result if result.present?
  17. # reject inbound call
  18. result = reject_check
  19. if result.present? && result[:action] == 'reject'
  20. @params['comment'] = 'reject, busy'
  21. if @params['user'].present?
  22. @params['comment'] = "#{@params['user']} -> reject, busy"
  23. end
  24. Cti::Log.process(@params)
  25. return result
  26. end
  27. # set caller ID of outbound call
  28. result = caller_id_rewrite(@params)
  29. if result.present? && result[:action] == 'set_caller_id'
  30. @params['from'] = result[:params][:from_caller_id]
  31. Cti::Log.process(@params)
  32. return result
  33. end
  34. log = Cti::Log.process(@params)
  35. if log.present?
  36. # push new call notification
  37. push_incoming_call(log)
  38. # open screen if call got answered
  39. push_open_ticket_screen(log)
  40. end
  41. result || {}
  42. end
  43. def direction_check
  44. # check possible directions
  45. if @params['direction'] != 'in' && @params['direction'] != 'out'
  46. return {
  47. action: 'invalid_direction',
  48. params: @params
  49. }
  50. end
  51. nil
  52. end
  53. def reject_check
  54. return nil if @params['direction'] != 'in'
  55. return nil if @params['event'] != 'newCall'
  56. config_inbound = @config[:inbound] || {}
  57. block_caller_ids = config_inbound[:block_caller_ids] || []
  58. # check if call needs to be blocked
  59. block_caller_ids.each do |item|
  60. next if item[:caller_id] != @params['from']
  61. return {
  62. action: 'reject'
  63. }
  64. end
  65. nil
  66. end
  67. def caller_id_rewrite(params)
  68. return nil if params['direction'] != 'out'
  69. return nil if params['event'] != 'newCall'
  70. config_outbound = @config[:outbound]
  71. routing_table = nil
  72. default_caller_id = nil
  73. if config_outbound.present?
  74. routing_table = config_outbound[:routing_table]
  75. default_caller_id = config_outbound[:default_caller_id]
  76. end
  77. to = params[:to]
  78. return nil if to.blank?
  79. if routing_table.present?
  80. routing_table.each do |row|
  81. dest = row[:dest].gsub(%r{\*}, '.+?')
  82. next if !to.match?(%r{^#{dest}$})
  83. return {
  84. action: 'set_caller_id',
  85. params: {
  86. from_caller_id: row[:caller_id],
  87. to_caller_id: params[:to],
  88. }
  89. }
  90. end
  91. end
  92. if default_caller_id.present?
  93. return {
  94. action: 'set_caller_id',
  95. params: {
  96. from_caller_id: default_caller_id,
  97. to_caller_id: params[:to],
  98. }
  99. }
  100. end
  101. nil
  102. end
  103. def push_open_ticket_screen(log)
  104. return if log.destroyed?
  105. return if @params[:event] != 'answer'
  106. return if @params[:direction] != 'in'
  107. user = push_open_ticket_screen_recipient
  108. return if !user
  109. return if !user.permissions?('cti.agent')
  110. customer_id = log.best_customer_id_of_log_entry
  111. # open user profile if user has a ticket in the last 30 days
  112. if customer_id
  113. last_activity = Setting.get('cti_customer_last_activity')
  114. if Ticket.where(customer_id: customer_id).exists?(['updated_at > ?', last_activity.seconds.ago])
  115. PushMessages.send_to(user.id, {
  116. event: 'remote_task',
  117. data: {
  118. key: "User-#{customer_id}",
  119. controller: 'UserProfile',
  120. params: { user_id: customer_id.to_s },
  121. show: true,
  122. url: "user/profile/#{customer_id}"
  123. },
  124. })
  125. return
  126. end
  127. end
  128. id = SecureRandom.uuid
  129. title = Translation.translate(user.locale, __('Call from %s'), @params[:from])
  130. PushMessages.send_to(user.id, {
  131. event: 'remote_task',
  132. data: {
  133. key: "TicketCreateScreen-#{id}",
  134. controller: 'TicketCreate',
  135. params: { customer_id: customer_id.to_s, title: title, id: id },
  136. show: true,
  137. url: "ticket/create/id/#{id}"
  138. },
  139. })
  140. end
  141. def push_open_ticket_screen_recipient
  142. # try to find answering which answered call
  143. user = nil
  144. # based on answeringNumber
  145. if @params[:answeringNumber].present?
  146. user = Cti::CallerId.known_agents_by_number(@params[:answeringNumber]).first
  147. if !user
  148. user = User.find_by(phone: @params[:answeringNumber], active: true)
  149. end
  150. end
  151. # based on user param
  152. if !user && @params[:user].present?
  153. user = User.find_by(login: @params[:user].downcase)
  154. end
  155. # based on user_id param
  156. if !user && @params[:user_id].present?
  157. user = User.find_by(id: @params[:user_id])
  158. end
  159. user
  160. end
  161. def push_incoming_call(log)
  162. return if log.destroyed?
  163. return if @params[:event] != 'newCall'
  164. return if @params[:direction] != 'in'
  165. # check if only a certain user should get the notification
  166. if @config[:notify_map].present?
  167. user_ids = []
  168. @config[:notify_map].each do |row|
  169. next if row[:user_ids].blank? || row[:queue] != @params[:to]
  170. row[:user_ids].each do |user_id|
  171. user = User.find_by(id: user_id)
  172. next if !user
  173. next if !user.permissions?('cti.agent')
  174. user_ids.push user.id
  175. end
  176. end
  177. # add agents which have this number directly assigned
  178. Cti::CallerId.known_agents_by_number(@params[:to]).each do |user|
  179. next if !user
  180. next if !user.permissions?('cti.agent')
  181. user_ids.push user.id
  182. end
  183. user_ids.uniq.each do |user_id|
  184. PushMessages.send_to(
  185. user_id,
  186. {
  187. event: 'cti_event',
  188. data: log,
  189. },
  190. )
  191. end
  192. return true
  193. end
  194. # send notify about event
  195. users = User.with_permissions('cti.agent')
  196. users.each do |user|
  197. PushMessages.send_to(
  198. user.id,
  199. {
  200. event: 'cti_event',
  201. data: log,
  202. },
  203. )
  204. end
  205. true
  206. end
  207. end