article_customer.rb 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
  2. module Import
  3. module OTRS
  4. class ArticleCustomer
  5. include Import::Helper
  6. def initialize(article)
  7. import(article)
  8. rescue Exceptions::UnprocessableEntity
  9. log "ERROR: Can't extract customer from Article #{article[:id]}"
  10. end
  11. class << self
  12. def find(article)
  13. email = local_email(article['From'])
  14. return if !email
  15. user = ::User.find_by(email: email)
  16. user ||= ::User.find_by(login: email)
  17. user
  18. end
  19. def local_email(from)
  20. # TODO: should get unified with User#check_email
  21. email = extract_email(from)
  22. return if !email
  23. email.downcase
  24. end
  25. private
  26. def extract_email(from)
  27. Mail::Address.new(from).address
  28. rescue
  29. return from if from !~ %r{<\s*([^>]+)}
  30. $1.strip
  31. end
  32. end
  33. private
  34. def import(article)
  35. find_or_create(article)
  36. end
  37. def find_or_create(article)
  38. return if self.class.find(article)
  39. create(article)
  40. end
  41. def create(article)
  42. email = self.class.local_email(article['From'])
  43. ::User.create(
  44. login: email,
  45. firstname: extract_display_name(article['From']),
  46. lastname: '',
  47. email: email,
  48. password: '',
  49. active: true,
  50. role_ids: roles,
  51. updated_by_id: 1,
  52. created_by_id: 1,
  53. )
  54. rescue ActiveRecord::RecordNotUnique
  55. log "User #{email} was handled by another thread, taking this."
  56. return if self.class.find(article)
  57. log "User #{email} wasn't created sleep and retry."
  58. sleep rand 3
  59. retry
  60. end
  61. def roles
  62. [
  63. Role.find_by(name: 'Customer').id
  64. ]
  65. end
  66. def extract_display_name(from)
  67. # do extra decoding because we needed to use field.value
  68. Mail::Field.new('X-From', parsed_display_name(from)).to_s
  69. end
  70. def parsed_display_name(from)
  71. parsed_address = Mail::Address.new(from)
  72. return parsed_address.display_name if parsed_address.display_name
  73. return from if parsed_address.comments.blank?
  74. parsed_address.comments[0]
  75. rescue
  76. from
  77. end
  78. end
  79. end
  80. end