notification.rb 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
  2. class Transaction::Notification
  3. =begin
  4. {
  5. object: 'Ticket',
  6. type: 'update',
  7. ticket_id: 123,
  8. via_web: true,
  9. changes: {
  10. 'attribute1' => [before, now],
  11. 'attribute2' => [before, now],
  12. }
  13. },
  14. =end
  15. def initialize(item, params = {})
  16. @item = item
  17. @params = params
  18. end
  19. def perform
  20. return if @params[:disable_notification]
  21. ticket = Ticket.find(@item[:ticket_id])
  22. if @item[:article_id]
  23. article = Ticket::Article.find(@item[:article_id])
  24. end
  25. # find recipients
  26. recipients_and_channels = []
  27. =begin
  28. # group of agents to work on
  29. if data[:recipient] == 'group'
  30. recipients = ticket.agent_of_group()
  31. # owner
  32. elsif data[:recipient] == 'owner'
  33. if ticket.owner_id != 1
  34. recipients.push ticket.owner
  35. end
  36. # customer
  37. elsif data[:recipient] == 'customer'
  38. if ticket.customer_id != 1
  39. # temporarily disabled
  40. # recipients.push ticket.customer
  41. end
  42. # owner or group of agents to work on
  43. elsif data[:recipient] == 'to_work_on'
  44. if ticket.owner_id != 1
  45. recipients.push ticket.owner
  46. else
  47. recipients = ticket.agent_of_group()
  48. end
  49. end
  50. =end
  51. # loop through all users
  52. possible_recipients = ticket.agent_of_group
  53. if ticket.owner_id == 1
  54. possible_recipients.push ticket.owner
  55. end
  56. already_checked_recipient_ids = {}
  57. possible_recipients.each {|user|
  58. result = NotificationFactory::Mailer.notification_settings(user, ticket, @item[:type])
  59. next if !result
  60. next if already_checked_recipient_ids[result[:user].id]
  61. already_checked_recipient_ids[result[:user].id] = true
  62. recipients_and_channels.push result
  63. }
  64. # send notifications
  65. recipient_list = ''
  66. recipients_and_channels.each do |item|
  67. user = item[:user]
  68. channels = item[:channels]
  69. # ignore user who changed it by him self via web
  70. if @params[:via_web]
  71. next if article && article.updated_by_id == user.id
  72. next if !article && ticket.updated_by_id == user.id
  73. end
  74. # ignore inactive users
  75. next if !user.active
  76. # ignore if no changes has been done
  77. changes = human_changes(user, ticket)
  78. next if @item[:type] == 'update' && !article && (!changes || changes.empty?)
  79. # check if today already notified
  80. if @item[:type] == 'reminder_reached' || @item[:type] == 'escalation' || @item[:type] == 'escalation_warning'
  81. identifier = user.email
  82. if !identifier || identifier == ''
  83. identifier = user.login
  84. end
  85. already_notified = false
  86. History.list('Ticket', ticket.id).each {|history|
  87. next if history['type'] != 'notification'
  88. next if history['value_to'] !~ /\(#{Regexp.escape(@item[:type])}:/
  89. next if history['value_to'] !~ /#{Regexp.escape(identifier)}\(/
  90. next if !history['created_at'].today?
  91. already_notified = true
  92. }
  93. next if already_notified
  94. end
  95. # create online notification
  96. used_channels = []
  97. if channels['online']
  98. used_channels.push 'online'
  99. created_by_id = ticket.updated_by_id || 1
  100. # delete old notifications
  101. if @item[:type] == 'reminder_reached'
  102. seen = false
  103. created_by_id = 1
  104. OnlineNotification.remove_by_type('Ticket', ticket.id, @item[:type], user)
  105. elsif @item[:type] == 'escalation' || @item[:type] == 'escalation_warning'
  106. seen = false
  107. created_by_id = 1
  108. OnlineNotification.remove_by_type('Ticket', ticket.id, 'escalation', user)
  109. OnlineNotification.remove_by_type('Ticket', ticket.id, 'escalation_warning', user)
  110. # on updates without state changes create unseen messages
  111. elsif @item[:type] != 'create' && (!@item[:changes] || @item[:changes].empty? || !@item[:changes]['state_id'])
  112. seen = false
  113. else
  114. seen = ticket.online_notification_seen_state(user.id)
  115. end
  116. OnlineNotification.add(
  117. type: @item[:type],
  118. object: 'Ticket',
  119. o_id: ticket.id,
  120. seen: seen,
  121. created_by_id: created_by_id,
  122. user_id: user.id,
  123. )
  124. Rails.logger.debug "sent ticket online notifiaction to agent (#{@item[:type]}/#{ticket.id}/#{user.email})"
  125. end
  126. # ignore email channel notificaiton and empty emails
  127. if !channels['email'] || !user.email || user.email == ''
  128. add_recipient_list(ticket, user, used_channels, @item[:type])
  129. next
  130. end
  131. used_channels.push 'email'
  132. add_recipient_list(ticket, user, used_channels, @item[:type])
  133. # get user based notification template
  134. # if create, send create message / block update messages
  135. template = nil
  136. if @item[:type] == 'create'
  137. template = 'ticket_create'
  138. elsif @item[:type] == 'update'
  139. template = 'ticket_update'
  140. elsif @item[:type] == 'reminder_reached'
  141. template = 'ticket_reminder_reached'
  142. elsif @item[:type] == 'escalation'
  143. template = 'ticket_escalation'
  144. elsif @item[:type] == 'escalation_warning'
  145. template = 'ticket_escalation_warning'
  146. else
  147. raise "unknown type for notification #{@item[:type]}"
  148. end
  149. NotificationFactory::Mailer.notification(
  150. template: template,
  151. user: user,
  152. objects: {
  153. ticket: ticket,
  154. article: article,
  155. recipient: user,
  156. changes: changes,
  157. },
  158. references: ticket.get_references,
  159. main_object: ticket,
  160. )
  161. Rails.logger.debug "sent ticket email notifiaction to agent (#{@item[:type]}/#{ticket.id}/#{user.email})"
  162. end
  163. end
  164. def add_recipient_list(ticket, user, channels, type)
  165. return if channels.empty?
  166. identifier = user.email
  167. if !identifier || identifier == ''
  168. identifier = user.login
  169. end
  170. recipient_list = "#{identifier}(#{type}:#{channels.join(',')})"
  171. History.add(
  172. o_id: ticket.id,
  173. history_type: 'notification',
  174. history_object: 'Ticket',
  175. value_to: recipient_list,
  176. created_by_id: ticket.updated_by_id || 1
  177. )
  178. end
  179. def human_changes(user, record)
  180. return {} if !@item[:changes]
  181. locale = user.preferences[:locale] || 'en-us'
  182. # only show allowed attributes
  183. attribute_list = ObjectManager::Attribute.by_object_as_hash('Ticket', user)
  184. #puts "AL #{attribute_list.inspect}"
  185. user_related_changes = {}
  186. @item[:changes].each {|key, value|
  187. # if no config exists, use all attributes
  188. if !attribute_list || attribute_list.empty?
  189. user_related_changes[key] = value
  190. # if config exists, just use existing attributes for user
  191. elsif attribute_list[key.to_s]
  192. user_related_changes[key] = value
  193. end
  194. }
  195. changes = {}
  196. user_related_changes.each {|key, value|
  197. # get attribute name
  198. attribute_name = key.to_s
  199. object_manager_attribute = attribute_list[attribute_name]
  200. if attribute_name[-3, 3] == '_id'
  201. attribute_name = attribute_name[ 0, attribute_name.length - 3 ].to_s
  202. end
  203. # add item to changes hash
  204. if key.to_s == attribute_name
  205. changes[attribute_name] = value
  206. end
  207. # if changed item is an _id field/reference, do an lookup for the realy values
  208. value_id = []
  209. value_str = [ value[0], value[1] ]
  210. if key.to_s[-3, 3] == '_id'
  211. value_id[0] = value[0]
  212. value_id[1] = value[1]
  213. if record.respond_to?(attribute_name) && record.send(attribute_name)
  214. relation_class = record.send(attribute_name).class
  215. if relation_class && value_id[0]
  216. relation_model = relation_class.lookup(id: value_id[0])
  217. if relation_model
  218. if relation_model['name']
  219. value_str[0] = relation_model['name']
  220. elsif relation_model.respond_to?('fullname')
  221. value_str[0] = relation_model.send('fullname')
  222. end
  223. end
  224. end
  225. if relation_class && value_id[1]
  226. relation_model = relation_class.lookup(id: value_id[1])
  227. if relation_model
  228. if relation_model['name']
  229. value_str[1] = relation_model['name']
  230. elsif relation_model.respond_to?('fullname')
  231. value_str[1] = relation_model.send('fullname')
  232. end
  233. end
  234. end
  235. end
  236. end
  237. # check if we have an dedcated display name for it
  238. display = attribute_name
  239. if object_manager_attribute && object_manager_attribute[:display]
  240. # delete old key
  241. changes.delete(display)
  242. # set new key
  243. display = object_manager_attribute[:display].to_s
  244. end
  245. changes[display] = if object_manager_attribute && object_manager_attribute[:translate]
  246. from = Translation.translate(locale, value_str[0])
  247. to = Translation.translate(locale, value_str[1])
  248. [from, to]
  249. else
  250. [value_str[0].to_s, value_str[1].to_s]
  251. end
  252. }
  253. changes
  254. end
  255. end