123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- module Enrichment
- module Clearbit
- class User
- def initialize(user)
- @local_user = user
- @source = 'clearbit'
- @config = Setting.get('clearbit_config')
- end
- def synced?
- return false if !@config
- return false if @local_user.email.blank?
- UserInfo.current_user_id = 1
- return false if !mapping?
- payload = fetch
- return false if !payload
- attributes_changed = attributes_changed?(payload)
- organization_synced = false
- if payload['company'] && @config['organization_autocreate']
- organization = Enrichment::Clearbit::Organization.new(
- user: @local_user,
- payload: payload
- )
- organization_synced = organization.synced?
- end
- return false if !attributes_changed && !organization_synced
- @local_user.save if attributes_changed || organization_synced
- true
- end
- private
- def mapping?
- @mapping = @config['user_sync'].dup
- return false if @mapping.blank?
- # TODO: Refactoring:
- # Currently all target keys are prefixed with
- # user.
- # which is not necessary since the target object
- # is always a user
- @mapping.transform_values! { |value| value.sub('user.', '') }
- true
- end
- def load_remote(data)
- return if !remote_id?(data)
- return if !external_found?
- load_previous_changes
- end
- def remote_id?(data)
- return if !data
- return if !data['person']
- @remote_id = data['person']['id']
- end
- def external_found?
- return true if @external_user
- @external_user = ExternalSync.find_by(
- source: @source,
- source_id: @remote_id,
- object: @local_user.class.name,
- o_id: @local_user.id,
- )
- @external_user.present?
- end
- def load_previous_changes
- last_payload = @external_user.last_payload
- return if !last_payload
- @previous_changes = ExternalSync.map(
- mapping: @mapping,
- source: last_payload
- )
- end
- def attributes_changed?(payload)
- current_changes = ExternalSync.map(
- mapping: @mapping,
- source: payload
- )
- return false if !current_changes
- previous_changes = load_remote(payload)
- return false if !ExternalSync.changed?(
- object: @local_user,
- previous_changes: previous_changes,
- current_changes: current_changes,
- )
- @local_user.updated_by_id = 1
- return true if !@remote_id
- store_current(payload)
- true
- end
- def store_current(payload)
- if !external_found?
- @external_user = ExternalSync.new(
- source: @source,
- source_id: @remote_id,
- object: @local_user.class.name,
- o_id: @local_user.id,
- )
- end
- @external_user.last_payload = payload
- @external_user.save
- end
- def fetch
- if !Rails.env.production?
- filename = Rails.root.join('test', 'data', 'clearbit', "#{@local_user.email}.json")
- if File.exist?(filename)
- data = File.binread(filename)
- return JSON.parse(data) if data
- end
- end
- return if @config['api_key'].blank?
- record = {
- direction: 'out',
- facility: 'clearbit',
- url: "clearbit -> #{@local_user.email}",
- status: 200,
- ip: nil,
- request: { content: @local_user.email },
- response: {},
- method: 'GET',
- }
- begin
- require 'clearbit' # Only load this gem when it is really used.
- ::Clearbit.key = @config['api_key']
- result = ::Clearbit::Enrichment.find(email: @local_user.email, stream: true)
- record[:response] = { code: 200, content: result.to_s }
- rescue => e
- record[:status] = 500
- record[:response] = { code: 500, content: e.inspect }
- end
- HttpLog.create(record)
- result
- end
- class << self
- def all
- users = User.of_role(Role.signup_roles)
- users.each do |user|
- new(user).synced?
- end
- end
- end
- end
- end
- end
|