mailer.rb 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. class NotificationFactory::Mailer
  2. =begin
  3. get notification settings for user and notification type
  4. result = NotificationFactory::Mailer.notification_settings(user, ticket, type)
  5. type: create | update | reminder_reached | escalation (escalation_warning)
  6. returns
  7. {
  8. user: user,
  9. channels: {
  10. online: true,
  11. email: true,
  12. },
  13. }
  14. =end
  15. def self.notification_settings(user, ticket, type)
  16. # map types if needed
  17. map = {
  18. 'escalation_warning' => 'escalation'
  19. }
  20. if map[type]
  21. type = map[type]
  22. end
  23. return if !user.preferences
  24. return if !user.preferences['notification_config']
  25. matrix = user.preferences['notification_config']['matrix']
  26. return if !matrix
  27. owned_by_nobody = false
  28. owned_by_me = false
  29. if ticket.owner_id == 1
  30. owned_by_nobody = true
  31. elsif ticket.owner_id == user.id
  32. owned_by_me = true
  33. else
  34. # check the replacement chain of max 10
  35. # if the current user is in it
  36. check_for = ticket.owner
  37. 10.times do
  38. replacement = check_for.out_of_office_agent
  39. break if !replacement
  40. check_for = replacement
  41. next if replacement.id != user.id
  42. owned_by_me = true
  43. break
  44. end
  45. end
  46. # check if group is in selected groups
  47. if !owned_by_me
  48. selected_group_ids = user.preferences['notification_config']['group_ids']
  49. if selected_group_ids.is_a?(Array)
  50. hit = nil
  51. if selected_group_ids.blank?
  52. hit = true
  53. elsif selected_group_ids[0] == '-' && selected_group_ids.count == 1
  54. hit = true
  55. else
  56. hit = false
  57. selected_group_ids.each do |selected_group_id|
  58. if selected_group_id.to_s == ticket.group_id.to_s
  59. hit = true
  60. break
  61. end
  62. end
  63. end
  64. return if !hit # no group access
  65. end
  66. end
  67. return if !matrix[type]
  68. data = matrix[type]
  69. return if !data
  70. return if !data['criteria']
  71. channels = data['channel']
  72. return if !channels
  73. if data['criteria']['owned_by_me'] && owned_by_me
  74. return {
  75. user: user,
  76. channels: channels
  77. }
  78. end
  79. if data['criteria']['owned_by_nobody'] && owned_by_nobody
  80. return {
  81. user: user,
  82. channels: channels
  83. }
  84. end
  85. return if !data['criteria']['no']
  86. {
  87. user: user,
  88. channels: channels
  89. }
  90. end
  91. =begin
  92. success = NotificationFactory::Mailer.send(
  93. recipient: User.find(123),
  94. subject: 'some subject',
  95. body: 'some body',
  96. content_type: '', # optional, e. g. 'text/html'
  97. message_id: '<some_message_id@fqdn>', # optional
  98. references: ['message-id123', 'message-id456'], # optional
  99. attachments: [attachments...], # optional
  100. )
  101. =end
  102. def self.send(data)
  103. sender = Setting.get('notification_sender')
  104. Rails.logger.info "Send notification to: #{data[:recipient][:email]} (from:#{sender}/subject:#{data[:subject]})"
  105. content_type = 'text/plain'
  106. if data[:content_type]
  107. content_type = data[:content_type]
  108. end
  109. # get active Email::Outbound Channel and send
  110. channel = Channel.find_by(area: 'Email::Notification', active: true)
  111. if channel.blank?
  112. Rails.logger.info "Can't find an active 'Email::Notification' channel. Canceling notification sending."
  113. return
  114. end
  115. channel.deliver(
  116. {
  117. # in_reply_to: in_reply_to,
  118. from: sender,
  119. to: data[:recipient][:email],
  120. subject: data[:subject],
  121. message_id: data[:message_id],
  122. references: data[:references],
  123. body: data[:body],
  124. content_type: content_type,
  125. attachments: data[:attachments],
  126. },
  127. true
  128. )
  129. end
  130. =begin
  131. NotificationFactory::Mailer.notification(
  132. template: 'password_reset',
  133. user: User.find(2),
  134. objects: {
  135. recipient: User.find(2),
  136. },
  137. main_object: ticket.find(123), # optional
  138. message_id: '<some_message_id@fqdn>', # optional
  139. references: ['message-id123', 'message-id456'], # optional
  140. standalone: true, # default: false - will send header & footer
  141. attachments: [attachments...], # optional
  142. )
  143. =end
  144. def self.notification(data)
  145. # get subject
  146. result = NotificationFactory::Mailer.template(
  147. template: data[:template],
  148. locale: data[:user][:preferences][:locale],
  149. objects: data[:objects],
  150. standalone: data[:standalone],
  151. )
  152. # rebuild subject
  153. if data[:main_object].respond_to?(:subject_build)
  154. result[:subject] = data[:main_object].subject_build(result[:subject])
  155. end
  156. # prepare scaling of images
  157. if result[:body]
  158. result[:body] = HtmlSanitizer.dynamic_image_size(result[:body])
  159. end
  160. NotificationFactory::Mailer.send(
  161. recipient: data[:user],
  162. subject: result[:subject],
  163. body: result[:body],
  164. content_type: 'text/html',
  165. message_id: data[:message_id],
  166. references: data[:references],
  167. attachments: data[:attachments],
  168. )
  169. end
  170. =begin
  171. get count of already sent notifications
  172. count = NotificationFactory::Mailer.already_sent?(ticket, recipient_user, type)
  173. retunes
  174. 8
  175. =end
  176. def self.already_sent?(ticket, recipient, type)
  177. result = ticket.history_get
  178. count = 0
  179. result.each do |item|
  180. next if item['type'] != 'notification'
  181. next if item['object'] != 'Ticket'
  182. next if item['value_to'] !~ /#{recipient.email}/i
  183. next if item['value_to'] !~ /#{type}/i
  184. count += 1
  185. end
  186. count
  187. end
  188. =begin
  189. result = NotificationFactory::Mailer.template(
  190. template: 'password_reset',
  191. locale: 'en-us',
  192. timezone: 'America/Santiago',
  193. objects: {
  194. recipient: User.find(2),
  195. },
  196. )
  197. result = NotificationFactory::Mailer.template(
  198. templateInline: "Invitation to \#{config.product_name} at \#{config.fqdn}",
  199. locale: 'en-us',
  200. timezone: 'America/Santiago',
  201. objects: {
  202. recipient: User.find(2),
  203. },
  204. quote: true, # html quoting
  205. )
  206. only raw subject/body
  207. result = NotificationFactory::Mailer.template(
  208. template: 'password_reset',
  209. locale: 'en-us',
  210. timezone: 'America/Santiago',
  211. objects: {
  212. recipient: User.find(2),
  213. },
  214. raw: true, # will not add application template
  215. standalone: true, # default: false - will send header & footer
  216. )
  217. returns
  218. {
  219. subject: 'some subject',
  220. body: 'some body',
  221. }
  222. =end
  223. def self.template(data)
  224. if data[:templateInline]
  225. return NotificationFactory::Renderer.new(
  226. objects: data[:objects],
  227. locale: data[:locale],
  228. timezone: data[:timezone],
  229. template: data[:templateInline],
  230. escape: data[:quote]
  231. ).render
  232. end
  233. template = NotificationFactory.template_read(
  234. locale: data[:locale] || Setting.get('locale_default') || 'en-us',
  235. template: data[:template],
  236. format: data[:format] || 'html',
  237. type: 'mailer',
  238. )
  239. message_subject = NotificationFactory::Renderer.new(
  240. objects: data[:objects],
  241. locale: data[:locale],
  242. timezone: data[:timezone],
  243. template: template[:subject],
  244. escape: false
  245. ).render
  246. # strip off the extra newline at the end for the subjects of plaintext templates
  247. message_subject.chomp! if data[:format] == 'txt'
  248. message_body = NotificationFactory::Renderer.new(
  249. objects: data[:objects],
  250. locale: data[:locale],
  251. timezone: data[:timezone],
  252. template: template[:body]
  253. ).render
  254. if !data[:raw]
  255. application_template = NotificationFactory.application_template_read(
  256. format: 'html',
  257. type: 'mailer',
  258. )
  259. data[:objects][:message] = message_body
  260. data[:objects][:standalone] = data[:standalone]
  261. message_body = NotificationFactory::Renderer.new(
  262. objects: data[:objects],
  263. locale: data[:locale],
  264. timezone: data[:timezone],
  265. template: application_template
  266. ).render
  267. end
  268. {
  269. subject: message_subject,
  270. body: message_body,
  271. }
  272. end
  273. end