user.rb 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. module Enrichment
  2. module Clearbit
  3. class User
  4. def initialize(user)
  5. @local_user = user
  6. @source = 'clearbit'
  7. @config = Setting.get('clearbit_config')
  8. end
  9. def synced?
  10. return false if !@config
  11. return false if @local_user.email.blank?
  12. UserInfo.current_user_id = 1
  13. return false if !mapping?
  14. payload = fetch
  15. return false if !payload
  16. attributes_changed = attributes_changed?(payload)
  17. organization_synced = false
  18. if payload['company'] && @config['organization_autocreate']
  19. organization = Enrichment::Clearbit::Organization.new(
  20. user: @local_user,
  21. payload: payload
  22. )
  23. organization_synced = organization.synced?
  24. end
  25. return false if !attributes_changed && !organization_synced
  26. @local_user.save if attributes_changed || organization_synced
  27. true
  28. end
  29. private
  30. def mapping?
  31. @mapping = @config['user_sync'].dup
  32. return false if @mapping.blank?
  33. # TODO: Refactoring:
  34. # Currently all target keys are prefixed with
  35. # user.
  36. # which is not necessary since the target object
  37. # is always a user
  38. @mapping.transform_values! { |value| value.sub('user.', '') }
  39. true
  40. end
  41. def load_remote(data)
  42. return if !remote_id?(data)
  43. return if !external_found?
  44. load_previous_changes
  45. end
  46. def remote_id?(data)
  47. return if !data
  48. return if !data['person']
  49. @remote_id = data['person']['id']
  50. end
  51. def external_found?
  52. return true if @external_user
  53. @external_user = ExternalSync.find_by(
  54. source: @source,
  55. source_id: @remote_id,
  56. object: @local_user.class.name,
  57. o_id: @local_user.id,
  58. )
  59. @external_user.present?
  60. end
  61. def load_previous_changes
  62. last_payload = @external_user.last_payload
  63. return if !last_payload
  64. @previous_changes = ExternalSync.map(
  65. mapping: @mapping,
  66. source: last_payload
  67. )
  68. end
  69. def attributes_changed?(payload)
  70. current_changes = ExternalSync.map(
  71. mapping: @mapping,
  72. source: payload
  73. )
  74. return false if !current_changes
  75. previous_changes = load_remote(payload)
  76. return false if !ExternalSync.changed?(
  77. object: @local_user,
  78. previous_changes: previous_changes,
  79. current_changes: current_changes,
  80. )
  81. @local_user.updated_by_id = 1
  82. return true if !@remote_id
  83. store_current(payload)
  84. true
  85. end
  86. def store_current(payload)
  87. if !external_found?
  88. @external_user = ExternalSync.new(
  89. source: @source,
  90. source_id: @remote_id,
  91. object: @local_user.class.name,
  92. o_id: @local_user.id,
  93. )
  94. end
  95. @external_user.last_payload = payload
  96. @external_user.save
  97. end
  98. def fetch
  99. if !Rails.env.production?
  100. filename = Rails.root.join('test', 'data', 'clearbit', "#{@local_user.email}.json")
  101. if File.exist?(filename)
  102. data = File.binread(filename)
  103. return JSON.parse(data) if data
  104. end
  105. end
  106. return if @config['api_key'].blank?
  107. record = {
  108. direction: 'out',
  109. facility: 'clearbit',
  110. url: "clearbit -> #{@local_user.email}",
  111. status: 200,
  112. ip: nil,
  113. request: { content: @local_user.email },
  114. response: {},
  115. method: 'GET',
  116. }
  117. begin
  118. ::Clearbit.key = @config['api_key']
  119. result = ::Clearbit::Enrichment.find(email: @local_user.email, stream: true)
  120. record[:response] = { code: 200, content: result.to_s }
  121. rescue => e
  122. record[:status] = 500
  123. record[:response] = { code: 500, content: e.inspect }
  124. end
  125. HttpLog.create(record)
  126. result
  127. end
  128. class << self
  129. def all
  130. users = User.of_role(Role.signup_roles)
  131. users.each do |user|
  132. new(user).synced?
  133. end
  134. end
  135. end
  136. end
  137. end
  138. end