base_email_inbound.rb 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Channel::Driver::BaseEmailInbound < Channel::EmailParser
  3. def fetch(_options, _channel)
  4. raise 'not implemented'
  5. end
  6. def check(_options)
  7. raise 'not implemented'
  8. end
  9. def verify(_options, _verify_string)
  10. raise 'not implemented'
  11. end
  12. def fetchable?(_channel)
  13. true
  14. end
  15. def self.streamable?
  16. false
  17. end
  18. # Checks if the given channel was modified since it it was loaded
  19. # This check is used in email fetching loop
  20. def channel_has_changed?(channel)
  21. current_channel = Channel.find_by(id: channel.id)
  22. if !current_channel
  23. Rails.logger.info "Channel with id #{channel.id} is deleted in the meantime. Stop fetching."
  24. return true
  25. end
  26. return false if channel.updated_at == current_channel.updated_at
  27. Rails.logger.info "Channel with id #{channel.id} has changed. Stop fetching."
  28. true
  29. end
  30. # Checks if email is not too big for processing
  31. #
  32. # @param [Integer] size in bytes
  33. #
  34. # This method is used by IMAP and MicrosoftGraphInbound only
  35. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  36. def too_large?(message_meta_size)
  37. max_message_size = Setting.get('postmaster_max_size').to_f
  38. real_message_size = message_meta_size.to_f / 1024 / 1024
  39. if real_message_size > max_message_size
  40. return [real_message_size, max_message_size]
  41. end
  42. false
  43. end
  44. # Checks if a message with the given headers is a Zammad verify message
  45. #
  46. # This method is used by IMAP and MicrosoftGraphInbound only
  47. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  48. def messages_is_verify_message?(headers)
  49. return true if headers['X-Zammad-Verify'] == 'true'
  50. false
  51. end
  52. # Checks if a message with the given headers marked to be ignored by Zammad
  53. #
  54. # This method is used by IMAP and MicrosoftGraphInbound only
  55. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  56. def messages_is_ignore_message?(headers)
  57. return true if headers['X-Zammad-Ignore'] == 'true'
  58. false
  59. end
  60. # Checks if a message is an old Zammad verify message
  61. #
  62. # Returns false only if a verify message is less than 30 minutes old
  63. #
  64. # This method is used by IMAP and MicrosoftGraphInbound only
  65. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  66. def messages_is_too_old_verify?(headers, count, count_all)
  67. return true if !messages_is_verify_message?(headers)
  68. return true if headers['X-Zammad-Verify-Time'].blank?
  69. begin
  70. verify_time = Time.zone.parse(headers['X-Zammad-Verify-Time'])
  71. rescue => e
  72. Rails.logger.error e
  73. return true
  74. end
  75. return true if verify_time < 30.minutes.ago
  76. Rails.logger.info " - ignore message #{count}/#{count_all} - because message has a verify message"
  77. false
  78. end
  79. # Checks if a message is already imported in a given channel
  80. # This check is skipped for channels which do not keep messages on the server
  81. #
  82. # This method is used by IMAP and MicrosoftGraphInbound only
  83. # It may be possible to reuse them with POP3 too, but it needs further refactoring
  84. def already_imported?(headers, keep_on_server, channel)
  85. return false if !keep_on_server
  86. return false if !headers
  87. local_message_id = headers['Message-ID']
  88. return false if local_message_id.blank?
  89. local_message_id_md5 = Digest::MD5.hexdigest(local_message_id)
  90. article = Ticket::Article.where(message_id_md5: local_message_id_md5).reorder('created_at DESC, id DESC').limit(1).first
  91. return false if !article
  92. # verify if message is already imported via same channel, if not, import it again
  93. ticket = article.ticket
  94. return false if ticket&.preferences && ticket.preferences[:channel_id].present? && channel.present? && ticket.preferences[:channel_id] != channel[:id]
  95. true
  96. end
  97. end