notification.rb 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class TriggerWebhookJob::CustomPayload::Track::Notification < TriggerWebhookJob::CustomPayload::Track
  3. class << self
  4. def root?
  5. true
  6. end
  7. def klass
  8. 'Struct::Notification'
  9. end
  10. def functions
  11. %w[
  12. subject
  13. link
  14. message
  15. body
  16. changes
  17. ].freeze
  18. end
  19. def replacements(pre_defined_webhook_type:)
  20. {
  21. notification: functions,
  22. }
  23. end
  24. Struct.new('Notification', :subject, :message, :link, :changes, :body) if !defined?(Struct::Notification)
  25. def generate(tracks, data)
  26. return if data[:event].blank?
  27. event = data[:event]
  28. raise ArgumentError, __("The required event field 'execution' is missing.") if event.exclude?(:execution)
  29. type = type!(event)
  30. template = fetch(tracks, event, type)
  31. tracks[:notification] = assemble(template, has_body: tracks[:article].present? && tracks[:article].body_as_text.strip.present?, type:)
  32. end
  33. private
  34. def fetch(tracks, event, type)
  35. NotificationFactory::Messaging.template(
  36. template: "ticket_#{type}",
  37. locale: Setting.get('locale_default') || 'en-us',
  38. timezone: Setting.get('timezone_default'),
  39. objects: {
  40. ticket: tracks.fetch(:ticket, nil),
  41. article: tracks.fetch(:article, nil),
  42. current_user: event[:user_id].present? ? ::User.lookup(id: event[:user_id]) : nil,
  43. changes: event[:changes],
  44. },
  45. )
  46. end
  47. def type!(event)
  48. return 'info' if event[:execution].eql?('job')
  49. return event[:type] if event[:execution].eql?('trigger')
  50. raise ArgumentError, __("The required event field 'execution' is unknown or missing.")
  51. end
  52. def assemble(template, has_body: false, type: nil)
  53. match = regex(has_body).match(template[:body])
  54. raise ArgumentError, "Extracting information for the notification failed due to a non-matching template (template: #{"ticket_#{type}"}, locale: #{Setting.get('locale_default')})." if match.nil?
  55. notification = {
  56. subject: template[:subject][2..],
  57. message: match[:message].presence || '',
  58. link: match[:link].presence || '',
  59. changes: match[:changes].presence || '',
  60. body: has_body ? match[:body].presence || '' : '',
  61. }
  62. sanitize(notification)
  63. Struct::Notification.new(*notification.values)
  64. end
  65. def regex(extended)
  66. source = '_<(?<link>.+)\|.+>[ ]?:(?<message>.+)_(\n(?<changes>.+))?'
  67. source += '\n{3,4}(?<body>.+)?' if extended
  68. Regexp.new(source, Regexp::MULTILINE)
  69. end
  70. def sanitize(hash)
  71. hash.each do |key, value|
  72. if key.eql?(:changes)
  73. value = value
  74. .split(%r{\n})
  75. .map(&:strip)
  76. .compact_blank
  77. .join('\n')
  78. end
  79. hash[key] = value.strip
  80. end
  81. end
  82. end
  83. end