Added init version of clearbit integration.
This commit is contained in:
parent
62d35d2a0e
commit
e06f4ee7fe
22 changed files with 1865 additions and 99 deletions
|
@ -156,6 +156,17 @@ job_integration_slack:
|
|||
- ruby -I test test/integration/slack_test.rb
|
||||
- rake db:drop
|
||||
|
||||
job_integration_clearbit:
|
||||
stage: test
|
||||
tags:
|
||||
- core
|
||||
script:
|
||||
- export RAILS_ENV=test
|
||||
- rake db:create
|
||||
- rake db:migrate
|
||||
- ruby -I test test/integration/clearbit_test.rb
|
||||
- rake db:drop
|
||||
|
||||
job_integration_es_mysql:
|
||||
stage: test
|
||||
tags:
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -32,8 +32,6 @@ gem 'omniauth-facebook'
|
|||
gem 'omniauth-linkedin'
|
||||
gem 'omniauth-google-oauth2'
|
||||
|
||||
gem 'zendesk_api'
|
||||
|
||||
gem 'twitter'
|
||||
gem 'koala'
|
||||
gem 'mail'
|
||||
|
@ -90,6 +88,8 @@ gem 'browser'
|
|||
|
||||
# integrations
|
||||
gem 'slack-notifier'
|
||||
gem 'clearbit'
|
||||
gem 'zendesk_api'
|
||||
|
||||
# event machine
|
||||
gem 'eventmachine'
|
||||
|
|
|
@ -54,6 +54,8 @@ GEM
|
|||
childprocess (0.5.9)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
clavius (1.0.2)
|
||||
clearbit (0.2.3)
|
||||
nestful (~> 1.1.0)
|
||||
coderay (1.1.1)
|
||||
coffee-rails (4.1.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
|
@ -134,7 +136,7 @@ GEM
|
|||
faraday
|
||||
multi_json
|
||||
libv8 (3.16.14.13)
|
||||
listen (3.0.6)
|
||||
listen (3.1.1)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9.7)
|
||||
loofah (2.0.3)
|
||||
|
@ -154,6 +156,7 @@ GEM
|
|||
mysql2 (0.3.20)
|
||||
naught (1.1.0)
|
||||
nenv (0.3.0)
|
||||
nestful (1.1.1)
|
||||
net-ldap (0.14.0)
|
||||
nokogiri (1.6.7.2)
|
||||
mini_portile2 (~> 2.0.0.rc2)
|
||||
|
@ -323,6 +326,7 @@ DEPENDENCIES
|
|||
autoprefixer-rails (>= 5.2)
|
||||
biz
|
||||
browser
|
||||
clearbit
|
||||
coffee-rails
|
||||
coffee-script-source
|
||||
coffeelint
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
class Index extends App.ControllerIntegrationBase
|
||||
featureIntegration: 'clearbit_integration'
|
||||
featureName: 'Clearbit'
|
||||
featureConfig: 'clearbit_config'
|
||||
description: [
|
||||
['Automatically enrich your customers and organizations with fresh, up-to-date intel. Map data directly to object fields.
|
||||
']
|
||||
]
|
||||
|
||||
render: =>
|
||||
super
|
||||
new Form(
|
||||
el: @$('.js-form')
|
||||
)
|
||||
|
||||
new App.HttpLog(
|
||||
el: @$('.js-log')
|
||||
facility: 'clearbit'
|
||||
)
|
||||
|
||||
class Form extends App.Controller
|
||||
events:
|
||||
'submit form': 'update'
|
||||
'click .js-userSync .js-add': 'addUserSync'
|
||||
'click .js-organizationSync .js-add': 'addOrganizationSync'
|
||||
'click .js-userSync .js-remove': 'removeRow'
|
||||
'click .js-organizationSync .js-remove': 'removeRow'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
@subscribeId = App.Setting.subscribe(@render, initFetch: true, clear: false)
|
||||
|
||||
currentConfig: ->
|
||||
config = App.Setting.get('clearbit_config')
|
||||
if !config
|
||||
config = {}
|
||||
if config.organization_autocreate is undefined
|
||||
config.organization_autocreate = true
|
||||
if config.organization_shared is undefined
|
||||
config.organization_shared = false
|
||||
if !config.user_sync
|
||||
config.user_sync =
|
||||
'person.name.givenName': 'user.firstname'
|
||||
'person.name.familyName': 'user.lastname'
|
||||
'person.email': 'user.email'
|
||||
'person.bio': 'user.note'
|
||||
'company.url': 'user.web'
|
||||
'person.site': 'user.web'
|
||||
'company.location': 'user.address'
|
||||
'person.location': 'user.address'
|
||||
if !config.organization_sync
|
||||
config.organization_sync =
|
||||
'company.legalName': 'organization.name'
|
||||
'company.name': 'organization.name'
|
||||
'company.description': 'organization.note'
|
||||
config
|
||||
|
||||
setConfig: (value) ->
|
||||
App.Setting.set('clearbit_config', value)
|
||||
|
||||
render: =>
|
||||
@config = @currentConfig()
|
||||
|
||||
settings = [
|
||||
{ name: 'api_key', display: 'API Key', tag: 'input', type: 'text', limit: 100, null: false, placeholder: '...', note: 'Your api key.' },
|
||||
{ name: 'organization_autocreate', display: 'Auto create', tag: 'boolean', type: 'boolean', null: false, note: 'Create organizations automatically if record has one.' },
|
||||
{ name: 'organization_shared', display: 'Shared', tag: 'boolean', type: 'boolean', null: false, note: 'New organizations are shared.' },
|
||||
]
|
||||
|
||||
@html App.view('integration/clearbit')(
|
||||
config: @config
|
||||
settings: settings
|
||||
)
|
||||
|
||||
for setting in settings
|
||||
setting.display = ''
|
||||
new App.ControllerForm(
|
||||
el: @$("[data-name=#{setting.name}]")
|
||||
model: { configure_attributes: [setting] }
|
||||
params: @config
|
||||
)
|
||||
|
||||
updateCurrentConfig: =>
|
||||
config = @config
|
||||
cleanupInput = @cleanupInput
|
||||
|
||||
params = @formParam(@$('form'))
|
||||
config.api_key = params['api_key']
|
||||
config.organization_autocreate = params['organization_autocreate']
|
||||
config.organization_shared = params['organization_shared']
|
||||
|
||||
# user sync
|
||||
config.user_sync = {}
|
||||
@$('.js-userSync .js-row').each(->
|
||||
element = $(@)
|
||||
source = cleanupInput(element.find('input[name="source"]').val())
|
||||
destination = cleanupInput(element.find('input[name="destination"]').val())
|
||||
config.user_sync[source] = destination
|
||||
)
|
||||
|
||||
# organization sync
|
||||
config.organization_sync = {}
|
||||
@$('.js-organizationSync .js-row').each(->
|
||||
element = $(@)
|
||||
source = cleanupInput(element.find('input[name="source"]').val())
|
||||
destination = cleanupInput(element.find('input[name="destination"]').val())
|
||||
config.organization_sync[source] = destination
|
||||
)
|
||||
|
||||
@config = config
|
||||
|
||||
update: (e) =>
|
||||
e.preventDefault()
|
||||
@updateCurrentConfig()
|
||||
@setConfig(@config)
|
||||
|
||||
cleanupInput: (value) ->
|
||||
return value if !value
|
||||
value.replace(/\s/g, '').trim()
|
||||
|
||||
addUserSync: (e) =>
|
||||
e.preventDefault()
|
||||
@updateCurrentConfig()
|
||||
element = $(e.currentTarget).closest('tr')
|
||||
source = @cleanupInput(element.find('input[name="source"]').val())
|
||||
destination = @cleanupInput(element.find('input[name="destination"]').val())
|
||||
@config.user_sync[source] = destination
|
||||
@setConfig(@config)
|
||||
@render()
|
||||
|
||||
addOrganizationSync: (e) =>
|
||||
e.preventDefault()
|
||||
@updateCurrentConfig()
|
||||
element = $(e.currentTarget).closest('tr')
|
||||
source = @cleanupInput(element.find('input[name="source"]').val())
|
||||
destination = @cleanupInput(element.find('input[name="destination"]').val())
|
||||
@config.organization_sync[source] = destination
|
||||
@setConfig(@config)
|
||||
@render()
|
||||
|
||||
removeRow: (e) =>
|
||||
e.preventDefault()
|
||||
@updateCurrentConfig()
|
||||
element = $(e.currentTarget).closest('tr')
|
||||
element.remove()
|
||||
|
||||
class State
|
||||
@current: ->
|
||||
App.Setting.get('clearbit_integration')
|
||||
|
||||
App.Config.set(
|
||||
'IntegrationClearbit'
|
||||
{
|
||||
name: 'Clearbit'
|
||||
target: '#system/integration/clearbit'
|
||||
description: 'A powerfull service to get more information about your customers.'
|
||||
controller: Index
|
||||
state: State
|
||||
}
|
||||
'NavBarIntegrations'
|
||||
)
|
|
@ -148,7 +148,7 @@ App.Config.set(
|
|||
{
|
||||
name: 'sipgate.io'
|
||||
target: '#system/integration/sipgate'
|
||||
description: 'VoIP services provide.'
|
||||
description: 'VoIP service provider with realtime push.'
|
||||
controller: Index
|
||||
state: State
|
||||
}
|
||||
|
|
|
@ -1,93 +1,3 @@
|
|||
class App.SettingsForm extends App.Controller
|
||||
events:
|
||||
'submit form': 'update'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
@subscribeId = App.Setting.subscribe(@render, initFetch: true, clear: false)
|
||||
|
||||
render: =>
|
||||
|
||||
# serach area settings
|
||||
settings = App.Setting.search(
|
||||
filter:
|
||||
area: @area
|
||||
)
|
||||
|
||||
# filter online service settings
|
||||
if App.Config.get('system_online_service')
|
||||
settings = _.filter(settings, (setting) ->
|
||||
return if setting.online_service
|
||||
return if setting.preferences && setting.preferences.online_service_disable
|
||||
setting
|
||||
)
|
||||
return if _.isEmpty(settings)
|
||||
|
||||
# sort by prio
|
||||
settings = _.sortBy( settings, (setting) ->
|
||||
return if !setting.preferences
|
||||
setting.preferences.prio
|
||||
)
|
||||
|
||||
localEl = $( App.view('settings/form')(
|
||||
settings: settings
|
||||
))
|
||||
|
||||
for setting in settings
|
||||
configure_attributes = setting.options['form']
|
||||
value = App.Setting.get(setting.name)
|
||||
params = {}
|
||||
params[setting.name] = value
|
||||
new App.ControllerForm(
|
||||
el: localEl.find("[data-name=#{setting.name}]")
|
||||
model: { configure_attributes: configure_attributes, className: '' }
|
||||
params: params
|
||||
)
|
||||
@html localEl
|
||||
|
||||
update: (e) =>
|
||||
e.preventDefault()
|
||||
@formDisable(e)
|
||||
params = @formParam(e.target)
|
||||
|
||||
ui = @
|
||||
count = 0
|
||||
for name, value of params
|
||||
if App.Setting.findByAttribute('name', name)
|
||||
count += 1
|
||||
App.Setting.set(
|
||||
name,
|
||||
value,
|
||||
done: ->
|
||||
ui.formEnable(e)
|
||||
count -= 1
|
||||
if count == 0
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Update successful!')
|
||||
timeout: 2000
|
||||
}
|
||||
|
||||
# rerender ui || get new collections and session data
|
||||
if @preferences
|
||||
if @preferences.render
|
||||
App.Event.trigger( 'ui:rerender' )
|
||||
|
||||
if @preferences.session_check
|
||||
App.Auth.loginCheck()
|
||||
|
||||
fail: (settings, details) ->
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!')
|
||||
timeout: 2000
|
||||
}
|
||||
)
|
||||
|
||||
class App.SettingsArea extends App.Controller
|
||||
constructor: ->
|
||||
super
|
||||
|
@ -123,9 +33,9 @@ class App.SettingsArea extends App.Controller
|
|||
elements = []
|
||||
for setting in settings
|
||||
if setting.name is 'product_logo'
|
||||
item = new App.SettingsAreaLogo( setting: setting )
|
||||
item = new App.SettingsAreaLogo(setting: setting)
|
||||
else
|
||||
item = new App.SettingsAreaItem( setting: setting )
|
||||
item = new App.SettingsAreaItem(setting: setting)
|
||||
elements.push item.el
|
||||
|
||||
@html elements
|
||||
|
|
89
app/assets/javascripts/app/controllers/_settings/form.coffee
Normal file
89
app/assets/javascripts/app/controllers/_settings/form.coffee
Normal file
|
@ -0,0 +1,89 @@
|
|||
class App.SettingsForm extends App.Controller
|
||||
events:
|
||||
'submit form': 'update'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
@subscribeId = App.Setting.subscribe(@render, initFetch: true, clear: false)
|
||||
|
||||
render: =>
|
||||
|
||||
# serach area settings
|
||||
settings = App.Setting.search(
|
||||
filter:
|
||||
area: @area
|
||||
)
|
||||
|
||||
# filter online service settings
|
||||
if App.Config.get('system_online_service')
|
||||
settings = _.filter(settings, (setting) ->
|
||||
return if setting.online_service
|
||||
return if setting.preferences && setting.preferences.online_service_disable
|
||||
setting
|
||||
)
|
||||
return if _.isEmpty(settings)
|
||||
|
||||
# sort by prio
|
||||
settings = _.sortBy( settings, (setting) ->
|
||||
return if !setting.preferences
|
||||
setting.preferences.prio
|
||||
)
|
||||
|
||||
localEl = $( App.view('settings/form')(
|
||||
settings: settings
|
||||
))
|
||||
|
||||
for setting in settings
|
||||
configure_attributes = setting.options['form']
|
||||
value = App.Setting.get(setting.name)
|
||||
params = {}
|
||||
params[setting.name] = value
|
||||
new App.ControllerForm(
|
||||
el: localEl.find("[data-name=#{setting.name}]")
|
||||
model: { configure_attributes: configure_attributes }
|
||||
params: params
|
||||
)
|
||||
@html localEl
|
||||
|
||||
update: (e) =>
|
||||
e.preventDefault()
|
||||
@formDisable(e)
|
||||
params = @formParam(e.target)
|
||||
|
||||
ui = @
|
||||
count = 0
|
||||
for name, value of params
|
||||
if App.Setting.findByAttribute('name', name)
|
||||
count += 1
|
||||
App.Setting.set(
|
||||
name,
|
||||
value,
|
||||
done: ->
|
||||
ui.formEnable(e)
|
||||
count -= 1
|
||||
if count == 0
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'success'
|
||||
msg: App.i18n.translateContent('Update successful!')
|
||||
timeout: 2000
|
||||
}
|
||||
|
||||
# rerender ui || get new collections and session data
|
||||
if @preferences
|
||||
if @preferences.render
|
||||
App.Event.trigger( 'ui:rerender' )
|
||||
|
||||
if @preferences.session_check
|
||||
App.Auth.loginCheck()
|
||||
|
||||
fail: (settings, details) ->
|
||||
App.Event.trigger 'notify', {
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!')
|
||||
timeout: 2000
|
||||
}
|
||||
)
|
|
@ -220,6 +220,7 @@ class App extends Spine.Controller
|
|||
|
||||
# define richtext helper
|
||||
params.RichText = (string) ->
|
||||
return string if !string
|
||||
if string.match(/@T\('/)
|
||||
string = string.replace(/@T\('(.+?)'\)/g, (match, capture) ->
|
||||
App.i18n.translateContent(capture)
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<form>
|
||||
|
||||
<div class="settings-entry">
|
||||
<table class="settings-list" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"><%- @T('Title') %>
|
||||
<th width="50%"><%- @T('Value') %>
|
||||
<th width="35%"><%- @T('Description') %>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for setting in @settings: %>
|
||||
<tr>
|
||||
<td><%- @T(setting.display) %>
|
||||
<td data-name="<%- setting.name %>">
|
||||
<td><p class="help-text"><%- @RichText(setting.note) %></p>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2><%- @T('Mapping') %></h2>
|
||||
|
||||
<p><%- @T('What values of %s should be synced to users.', 'Clearbit') %></p>
|
||||
|
||||
<div class="settings-entry">
|
||||
<table class="settings-list js-userSync" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="45%"><%- @T('Clearbit') %>
|
||||
<th width="45%"><%- @T('Zammad') %>
|
||||
<th width="10%"><%- @T('Action') %>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for source, destination of @config.user_sync: %>
|
||||
<tr class="js-row">
|
||||
<td class="settings-list-control-cell"><input name="source" value="<%= source %>" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-control-cell"><input name="destination" value="<%= destination %>" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-row-control"><div class="btn btn--text js-remove"><%- @Icon('trash') %> <%- @T('Remove') %></div>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td class="settings-list-control-cell"><input name="source" value="" placeholder="person.attribute" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-control-cell"><input name="destination" value="" placeholder="user.attribute" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-row-control"><div class="btn btn--text btn--create js-add"><%- @Icon('plus-small') %> <%- @T('Add') %></div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p><%- @T('What values of %s should be synced to organization.', 'Clearbit') %></p>
|
||||
|
||||
<div class="settings-entry">
|
||||
<table class="settings-list js-organizationSync" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="45%"><%- @T('Clearbit') %>
|
||||
<th width="45%"><%- @T('Zammad') %>
|
||||
<th width="10%"><%- @T('Action') %>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for source, destination of @config.organization_sync: %>
|
||||
<tr class="js-row">
|
||||
<td class="settings-list-control-cell"><input name="source" value="<%= source %>" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-control-cell"><input name="destination" value="<%= destination %>" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-row-control"><div class="btn btn--text js-remove"><%- @Icon('trash') %> <%- @T('Remove') %></div>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td class="settings-list-control-cell"><input name="source" value="" placeholder="company.attribute" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-control-cell"><input name="destination" value="" placeholder="organization.attribute" class="form-control form-control--small js-summary">
|
||||
<td class="settings-list-row-control"><div class="btn btn--text btn--create js-add"><%- @Icon('plus-small') %> <%- @T('Add') %></div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn--primary"><%- @T('Save') %></button>
|
||||
</form>
|
|
@ -6,7 +6,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th style="width: 30px;"></th>
|
||||
<th style="width: 40%;"><%- @T('Service') %></th>
|
||||
<th style="width: 30%;"><%- @T('Service') %></th>
|
||||
<th><%- @T('Description') %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
5
app/models/external_sync.rb
Normal file
5
app/models/external_sync.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class ExternalSync < ApplicationModel
|
||||
store :last_payload
|
||||
end
|
|
@ -23,8 +23,13 @@ class Transaction::BackgroundJob
|
|||
def perform
|
||||
Setting.where(area: 'Transaction::Backend').order(:name).each {|setting|
|
||||
backend = Setting.get(setting.name)
|
||||
integration = Kernel.const_get(backend).new(@item, @params)
|
||||
integration.perform
|
||||
begin
|
||||
integration = Kernel.const_get(backend).new(@item, @params)
|
||||
integration.perform
|
||||
rescue => e
|
||||
logger.error 'ERROR: ' + setting.inspect
|
||||
logger.error 'ERROR: ' + e.inspect
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
|
321
app/models/transaction/clearbit_enrichment.rb
Normal file
321
app/models/transaction/clearbit_enrichment.rb
Normal file
|
@ -0,0 +1,321 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Transaction::ClearbitEnrichment
|
||||
|
||||
=begin
|
||||
{
|
||||
object: 'User',
|
||||
type: 'create',
|
||||
object_id: 123,
|
||||
changes: {
|
||||
'attribute1' => [before, now],
|
||||
'attribute2' => [before, now],
|
||||
}
|
||||
},
|
||||
=end
|
||||
|
||||
def initialize(item, params = {})
|
||||
@item = item
|
||||
@params = params
|
||||
end
|
||||
|
||||
def perform
|
||||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
return if @item[:object] != 'User'
|
||||
return if @item[:type] != 'create'
|
||||
|
||||
return if !Setting.get('clearbit_integration')
|
||||
|
||||
config = Setting.get('clearbit_config')
|
||||
return if !config
|
||||
return if config['api_key'].empty?
|
||||
|
||||
user = User.lookup(id: @item[:object_id])
|
||||
return if !user
|
||||
|
||||
Transaction::ClearbitEnrichment.sync_user(user)
|
||||
end
|
||||
|
||||
def self.sync
|
||||
users = User.of_role('Customer')
|
||||
users.each {|user|
|
||||
sync_user(user)
|
||||
}
|
||||
end
|
||||
|
||||
def self.sync_user(user)
|
||||
|
||||
return if !user.email
|
||||
data = fetch(user.email)
|
||||
#p 'OO: ' + data.inspect
|
||||
|
||||
config = Setting.get('clearbit_config')
|
||||
return if !config
|
||||
|
||||
# get new user sync attributes
|
||||
user_sync = config['user_sync']
|
||||
user_sync_values = {}
|
||||
if user_sync
|
||||
user_sync.each {|callback, destination|
|
||||
next if !user_sync_values[destination].empty?
|
||||
value = _replace(callback, data)
|
||||
next if !value
|
||||
user_sync_values[destination] = value
|
||||
}
|
||||
end
|
||||
|
||||
# get new organization sync attributes
|
||||
organization_sync = config['organization_sync']
|
||||
organization_sync_values = {}
|
||||
if organization_sync
|
||||
organization_sync.each {|callback, destination|
|
||||
next if !organization_sync_values[destination].empty?
|
||||
value = _replace(callback, data)
|
||||
next if !value
|
||||
organization_sync_values[destination] = value
|
||||
}
|
||||
end
|
||||
|
||||
# get latest user synced attributes
|
||||
external_syn_user = nil
|
||||
user_sync_values_last_time = {}
|
||||
if data && data['person'] && data['person']['id']
|
||||
external_syn_user = ExternalSync.find_by(
|
||||
source: 'clearbit',
|
||||
source_id: data['person']['id'],
|
||||
object: 'User',
|
||||
o_id: user.id,
|
||||
)
|
||||
if external_syn_user && external_syn_user.last_payload
|
||||
user_sync.each {|callback, destination|
|
||||
next if !user_sync_values_last_time[destination].empty?
|
||||
value = _replace(callback, external_syn_user.last_payload)
|
||||
next if !value
|
||||
user_sync_values_last_time[destination] = value
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# if person record exists
|
||||
user_has_changed = false
|
||||
user_sync_values.each {|destination, value|
|
||||
attribute = destination.sub(/^user\./, '')
|
||||
next if user[attribute] == value
|
||||
next if !user[attribute].empty? && user_sync_values_last_time[destination] != user[attribute]
|
||||
begin
|
||||
user[attribute] = value
|
||||
rescue => e
|
||||
Rails.logger.error "ERROR: Unable to assign user.#{attribute}: #{e.inspect}"
|
||||
end
|
||||
user_has_changed = true
|
||||
}
|
||||
if user_has_changed
|
||||
user.updated_by_id = 1
|
||||
if data['person'] && data['person']['id']
|
||||
if external_syn_user
|
||||
external_syn_user.last_payload = data
|
||||
external_syn_user.save
|
||||
else
|
||||
external_syn_user = ExternalSync.create(
|
||||
source: 'clearbit',
|
||||
source_id: data['person']['id'],
|
||||
object: 'User',
|
||||
o_id: user.id,
|
||||
last_payload: data,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# if no company record exists
|
||||
if !data['company']
|
||||
if user_has_changed
|
||||
user.save
|
||||
end
|
||||
Observer::Transaction.commit
|
||||
return
|
||||
end
|
||||
|
||||
# if company record exists
|
||||
external_syn_organization = ExternalSync.find_by(
|
||||
source: 'clearbit',
|
||||
source_id: data['company']['id'],
|
||||
)
|
||||
|
||||
# create new organization
|
||||
if !external_syn_organization
|
||||
|
||||
# can't create organization without name
|
||||
if organization_sync_values['organization.name'].empty?
|
||||
Observer::Transaction.commit
|
||||
return
|
||||
end
|
||||
|
||||
# find by name
|
||||
organization = Organization.find_by(name: organization_sync_values['organization.name'])
|
||||
|
||||
# create new organization
|
||||
if !organization
|
||||
organization = Organization.new(
|
||||
shared: config['organization_shared'],
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
organization_sync_values.each {|destination, value|
|
||||
attribute = destination.sub(/^organization\./, '')
|
||||
next if !organization[attribute].empty?
|
||||
begin
|
||||
organization[attribute] = value
|
||||
rescue => e
|
||||
Rails.logger.error "ERROR: Unable to assign organization.#{attribute}: #{e.inspect}"
|
||||
end
|
||||
}
|
||||
organization.save
|
||||
end
|
||||
ExternalSync.create(
|
||||
source: 'clearbit',
|
||||
source_id: data['company']['id'],
|
||||
object: 'Organization',
|
||||
o_id: organization.id,
|
||||
last_payload: data,
|
||||
)
|
||||
|
||||
# assign new organization to user
|
||||
if !user.organization_id
|
||||
user.organization_id = organization.id
|
||||
user.save
|
||||
end
|
||||
Observer::Transaction.commit
|
||||
return
|
||||
end
|
||||
|
||||
# get latest organization synced attributes
|
||||
organization_sync_values_last_time = {}
|
||||
if external_syn_organization && external_syn_organization.last_payload
|
||||
organization_sync.each {|callback, destination|
|
||||
next if !organization_sync_values_last_time[destination].empty?
|
||||
value = _replace(callback, external_syn_organization.last_payload)
|
||||
next if !value
|
||||
organization_sync_values_last_time[destination] = value
|
||||
}
|
||||
end
|
||||
|
||||
# update existing organization
|
||||
organization = Organization.find(external_syn_organization[:o_id])
|
||||
organization_has_changed = false
|
||||
organization_sync_values.each {|destination, value|
|
||||
attribute = destination.sub(/^organization\./, '')
|
||||
next if organization[attribute] == value
|
||||
next if !organization[attribute].empty? && organization_sync_values_last_time[destination] != organization[attribute]
|
||||
begin
|
||||
organization[attribute] = value
|
||||
rescue => e
|
||||
Rails.logger.error "ERROR: Unable to assign organization.#{attribute}: #{e.inspect}"
|
||||
end
|
||||
organization_has_changed = true
|
||||
}
|
||||
if organization_has_changed
|
||||
organization.updated_by_id = 1
|
||||
organization.save
|
||||
external_syn_organization.last_payload = data
|
||||
external_syn_organization.save
|
||||
end
|
||||
|
||||
# assign new organization to user
|
||||
if !user.organization_id
|
||||
user_has_changed = true
|
||||
user.organization_id = organization.id
|
||||
end
|
||||
|
||||
if user_has_changed
|
||||
user.save
|
||||
end
|
||||
|
||||
Observer::Transaction.commit
|
||||
true
|
||||
end
|
||||
|
||||
def self._replace(callback, data)
|
||||
object_name = nil
|
||||
object_method = nil
|
||||
placeholder = nil
|
||||
|
||||
if callback =~ /\A ( [\w]+ )\.( [\w\.]+ ) \z/x
|
||||
object_name = $1
|
||||
object_method = $2
|
||||
end
|
||||
|
||||
return if !data
|
||||
return if !data[object_name]
|
||||
|
||||
# do validaton, ignore some methodes
|
||||
if callback =~ /(`|\.(|\s*)(save|destroy|delete|remove|drop|update\(|update_att|create\(|new|all|where|find))/i
|
||||
placeholder = "#{callback} (not allowed)"
|
||||
|
||||
# get value based on object_name and object_method
|
||||
elsif object_name && object_method
|
||||
object_refs = data[object_name]
|
||||
object_methods = object_method.split('.')
|
||||
object_methods_s = ''
|
||||
object_methods.each {|method|
|
||||
if object_methods_s != ''
|
||||
object_methods_s += '.'
|
||||
end
|
||||
object_methods_s += method
|
||||
|
||||
# if method exists
|
||||
break if !object_refs.respond_to?(method.to_sym) && !object_refs[method]
|
||||
|
||||
object_refs = if object_refs.respond_to?(method.to_sym)
|
||||
object_refs.send(method.to_sym)
|
||||
else
|
||||
object_refs[method]
|
||||
end
|
||||
}
|
||||
if object_refs.class == String
|
||||
placeholder = object_refs
|
||||
end
|
||||
end
|
||||
placeholder
|
||||
end
|
||||
|
||||
def self.fetch(email)
|
||||
if !Rails.env.production?
|
||||
filename = "#{Rails.root}/test/fixtures/clearbit/#{email}.json"
|
||||
if File.exist?(filename)
|
||||
data = IO.binread(filename)
|
||||
return JSON.parse(data) if data
|
||||
end
|
||||
end
|
||||
|
||||
config = Setting.get('clearbit_config')
|
||||
return if !config
|
||||
return if config['api_key'].empty?
|
||||
|
||||
record = {
|
||||
direction: 'out',
|
||||
facility: 'clearbit',
|
||||
url: "clearbit -> #{email}",
|
||||
status: 200,
|
||||
ip: nil,
|
||||
request: { content: email },
|
||||
response: {},
|
||||
method: 'GET',
|
||||
}
|
||||
|
||||
begin
|
||||
Clearbit.key = config['api_key']
|
||||
result = Clearbit::Enrichment.find(email: 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
|
||||
|
||||
end
|
15
db/migrate/20160424000002_create_external_sync.rb
Normal file
15
db/migrate/20160424000002_create_external_sync.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class CreateExternalSync < ActiveRecord::Migration
|
||||
def up
|
||||
create_table :external_syncs do |t|
|
||||
t.string :source, limit: 100, null: false
|
||||
t.string :source_id, limit: 200, null: false
|
||||
t.string :object, limit: 100, null: false
|
||||
t.integer :o_id, null: false
|
||||
t.text :last_payload, limit: 500.kilobytes + 1, null: true
|
||||
t.timestamps null: false
|
||||
end
|
||||
add_index :external_syncs, [:source, :source_id], unique: true
|
||||
add_index :external_syncs, [:source, :source_id, :object, :o_id]
|
||||
add_index :external_syncs, [:object, :o_id]
|
||||
end
|
||||
end
|
46
db/migrate/20160425000001_add_clearbit_integration.rb
Normal file
46
db/migrate/20160425000001_add_clearbit_integration.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
class AddClearbitIntegration < ActiveRecord::Migration
|
||||
def up
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Clearbit integration',
|
||||
name: 'clearbit_integration',
|
||||
area: 'Integration::Switch',
|
||||
description: 'Define if Clearbit (http://www.clearbit.com) is enabled or not.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'clearbit_integration',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: false,
|
||||
preferences: { prio: 1 },
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Clearbit config',
|
||||
name: 'clearbit_config',
|
||||
area: 'Integration::Clearbit',
|
||||
description: 'Define the Clearbit config.',
|
||||
options: {},
|
||||
state: {},
|
||||
frontend: false,
|
||||
preferences: { prio: 2 },
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define transaction backend.',
|
||||
name: '9000_clearbit_enrichment',
|
||||
area: 'Transaction::Backend',
|
||||
description: 'Define the transaction backend which will enrich customer and organization informations from (http://www.clearbit.com).',
|
||||
options: {},
|
||||
state: 'Transaction::ClearbitEnrichment',
|
||||
frontend: false
|
||||
)
|
||||
end
|
||||
end
|
42
db/seeds.rb
42
db/seeds.rb
|
@ -1864,6 +1864,48 @@ Setting.create_if_not_exists(
|
|||
frontend: false,
|
||||
preferences: { prio: 2 },
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Clearbit integration',
|
||||
name: 'clearbit_integration',
|
||||
area: 'Integration::Switch',
|
||||
description: 'Define if Clearbit (http://www.clearbit.com) is enabled or not.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'clearbit_integration',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: false,
|
||||
preferences: { prio: 1 },
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Clearbit config',
|
||||
name: 'clearbit_config',
|
||||
area: 'Integration::Clearbit',
|
||||
description: 'Define the Clearbit config.',
|
||||
options: {},
|
||||
state: {},
|
||||
frontend: false,
|
||||
preferences: { prio: 2 },
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define transaction backend.',
|
||||
name: '9000_clearbit_enrichment',
|
||||
area: 'Transaction::Backend',
|
||||
description: 'Define the transaction backend which will enrich customer and organization informations from (http://www.clearbit.com).',
|
||||
options: {},
|
||||
state: 'Transaction::ClearbitEnrichment',
|
||||
frontend: false
|
||||
)
|
||||
|
||||
signature = Signature.create_if_not_exists(
|
||||
id: 1,
|
||||
|
|
188
test/fixtures/clearbit/alex@alexmaccaw.com.json
vendored
Normal file
188
test/fixtures/clearbit/alex@alexmaccaw.com.json
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
{
|
||||
"person": {
|
||||
"id": "d54c54ad-40be-4305-8a34-0ab44710b90d",
|
||||
"name": {
|
||||
"fullName": "Alex MacCaw",
|
||||
"givenName": "Alex",
|
||||
"familyName": "MacCaw"
|
||||
},
|
||||
"email": "alex@alexmaccaw.com",
|
||||
"gender": "male",
|
||||
"location": "San Francisco, CA, US",
|
||||
"timeZone": "America/Los_Angeles",
|
||||
"utcOffset": -8,
|
||||
"geo": {
|
||||
"city": "San Francisco",
|
||||
"state": "California",
|
||||
"stateCode": "CA",
|
||||
"country": "United States",
|
||||
"countryCode": "US",
|
||||
"lat": 37.7749295,
|
||||
"lng": -122.4194155
|
||||
},
|
||||
"bio": "O'Reilly author, software engineer & traveller. Founder of https://clearbit.com",
|
||||
"site": "http://alexmaccaw.com",
|
||||
"avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/d54c54ad-40be-4305-8a34-0ab44710b90d",
|
||||
"employment": {
|
||||
"domain": "clearbit.com",
|
||||
"name": "Clearbit",
|
||||
"title": "Founder and CEO",
|
||||
"role": "ceo",
|
||||
"seniority": "executive"
|
||||
},
|
||||
"facebook": {
|
||||
"handle": "amaccaw"
|
||||
},
|
||||
"github": {
|
||||
"handle": "maccman",
|
||||
"avatar": "https://avatars.githubusercontent.com/u/2142?v=2",
|
||||
"company": "Clearbit",
|
||||
"blog": "http://alexmaccaw.com",
|
||||
"followers": 2932,
|
||||
"following": 94
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "maccaw",
|
||||
"id": "2006261",
|
||||
"bio": "O'Reilly author, software engineer & traveller. Founder of https://clearbit.com",
|
||||
"followers": 15248,
|
||||
"following": 1711,
|
||||
"location": "San Francisco",
|
||||
"site": "http://alexmaccaw.com",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/1826201101/297606_10150904890650705_570400704_21211347_1883468370_n.jpeg"
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "pub/alex-maccaw/78/929/ab5"
|
||||
},
|
||||
"googleplus": {
|
||||
"handle": null
|
||||
},
|
||||
"angellist": {
|
||||
"handle": "maccaw",
|
||||
"bio": "O'Reilly author, engineer & traveller. Mostly harmless.",
|
||||
"blog": "http://blog.alexmaccaw.com",
|
||||
"site": "http://alexmaccaw.com",
|
||||
"followers": 532,
|
||||
"avatar": "https://d1qb2nb5cznatu.cloudfront.net/users/403357-medium_jpg?1405661263"
|
||||
},
|
||||
"aboutme": {
|
||||
"handle": "maccaw",
|
||||
"bio": "Software engineer & traveller. Walker, skier, reader, tennis player, breather, ginger beer drinker, scooterer & generally enjoying things :)",
|
||||
"avatar": "http://o.aolcdn.com/dims-global/dims/ABOUTME/5/803/408/80/http://d3mod6n032mdiz.cloudfront.net/thumb2/m/a/c/maccaw/maccaw-840x560.jpg"
|
||||
},
|
||||
"gravatar": {
|
||||
"handle": "maccman",
|
||||
"urls": [
|
||||
{
|
||||
"value": "http://alexmaccaw.com",
|
||||
"title": "Personal Website"
|
||||
}
|
||||
],
|
||||
"avatar": "http://2.gravatar.com/avatar/994909da96d3afaf4daaf54973914b64",
|
||||
"avatars": [
|
||||
{
|
||||
"url": "http://2.gravatar.com/avatar/994909da96d3afaf4daaf54973914b64",
|
||||
"type": "thumbnail"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fuzzy": false
|
||||
},
|
||||
"company": {
|
||||
"id": "027b0d40-016c-40ea-8925-a076fa640992",
|
||||
"name": "Uber",
|
||||
"legalName": "Uber, Inc.",
|
||||
"domain": "uber.com",
|
||||
"domainAliases": [],
|
||||
"url": "http://uber.com",
|
||||
"site": {
|
||||
"url": "http://uber.com",
|
||||
"title": null,
|
||||
"h1": null,
|
||||
"metaDescription": null,
|
||||
"metaAuthor": null,
|
||||
"phoneNumbers": [
|
||||
"+1 877-223-8023"
|
||||
],
|
||||
"emailAddresses": [
|
||||
"team@uber.com"
|
||||
]
|
||||
},
|
||||
"tags": [
|
||||
"Transportation",
|
||||
"Design",
|
||||
"SEO",
|
||||
"Automotive",
|
||||
"Real Time",
|
||||
"Limousines",
|
||||
"Public Transportation",
|
||||
"Transport"
|
||||
],
|
||||
"description": "Uber is a mobile app connecting passengers with drivers for hire.",
|
||||
"foundedDate": "2009-03-01",
|
||||
"location": "1455 Market Street, San Francisco, CA 94103, USA",
|
||||
"timeZone": "America/Los_Angeles",
|
||||
"utcOffset": -8,
|
||||
"geo": {
|
||||
"streetNumber": "1455",
|
||||
"streetName": "Market Street",
|
||||
"subPremise": null,
|
||||
"city": "San Francisco",
|
||||
"state": "California",
|
||||
"stateCode": "CA",
|
||||
"postalCode": "94103",
|
||||
"country": "United States",
|
||||
"countryCode": "US",
|
||||
"lat": 37.7752315,
|
||||
"lng": -122.4175567
|
||||
},
|
||||
"metrics": {
|
||||
"raised": 5900000000,
|
||||
"employees": 3250,
|
||||
"googleRank": 7,
|
||||
"alexaUsRank": 649,
|
||||
"alexaGlobalRank": 1071,
|
||||
"marketCap": null,
|
||||
"annualRevenue": null
|
||||
},
|
||||
"logo": "https://dqus23xyrtg1i.cloudfront.net/v1/logos/027b0d40-016c-40ea-8925-a076fa640992",
|
||||
"facebook": {
|
||||
"handle": "uber.IND"
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "company/uber.com"
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "uber",
|
||||
"id": 19103481,
|
||||
"bio": "Everyone's Private Driver. Question, concern or praise? Tweet at your local community manager here: https://t.co/EUiTjLk0xj",
|
||||
"followers": 176582,
|
||||
"following": 330,
|
||||
"location": "Global",
|
||||
"site": "http://t.co/PtMbwFTeQA",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/378800000762572812/91ea09a6535666e18ca3c56f731f67ef_normal.jpeg"
|
||||
},
|
||||
"angellist": {
|
||||
"id": 19163,
|
||||
"handle": "uber",
|
||||
"description": "Request a car from any mobile phone via text message, iPhone and Android apps. Within minutes, a professional driver in a sleek black car will arrive curbside. Automatically charged to your credit card on file, tip included.",
|
||||
"followers": 2650,
|
||||
"blogUrl": "http://blog.uber.com/"
|
||||
},
|
||||
"crunchbase": {
|
||||
"handle": "uber"
|
||||
},
|
||||
"phone": "+1 877-223-8023",
|
||||
"emailProvider": false,
|
||||
"type": "private",
|
||||
"tech": [
|
||||
"google_analytics",
|
||||
"double_click",
|
||||
"mixpanel",
|
||||
"optimizely",
|
||||
"typekit_by_adobe",
|
||||
"nginx",
|
||||
"google_apps"
|
||||
]
|
||||
}
|
||||
}
|
196
test/fixtures/clearbit/me2@example.com.json
vendored
Normal file
196
test/fixtures/clearbit/me2@example.com.json
vendored
Normal file
|
@ -0,0 +1,196 @@
|
|||
{
|
||||
"person": {
|
||||
"id": "4db7cfeb-8017-4aac-b4b9-debb6d3142c0",
|
||||
"name": {
|
||||
"fullName": "Martini Edenhofer",
|
||||
"givenName": "Martini",
|
||||
"familyName": "Edenhofer"
|
||||
},
|
||||
"email": "me2@otrs.org",
|
||||
"gender": null,
|
||||
"location": "Berlin, Berlin, DE",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"city": "Berlin",
|
||||
"state": "Berlin",
|
||||
"stateCode": "Berlin",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 52.52000659999999,
|
||||
"lng": 13.404954
|
||||
},
|
||||
"bio": "Open Source professional and geek. Also known as OTRS inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
|
||||
"site": "http://edenhofer.de/",
|
||||
"avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/4db7cfeb-8017-4aac-b4b9-debb6d3142c0",
|
||||
"employment": {
|
||||
"domain": "otrs.org",
|
||||
"name": "OTRS",
|
||||
"title": "CEO",
|
||||
"role": null,
|
||||
"seniority": "executive"
|
||||
},
|
||||
"facebook": {
|
||||
"handle": null
|
||||
},
|
||||
"github": {
|
||||
"handle": null,
|
||||
"id": null,
|
||||
"avatar": null,
|
||||
"company": null,
|
||||
"blog": null,
|
||||
"followers": null,
|
||||
"following": null
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "medenhofer",
|
||||
"id": 219826253,
|
||||
"bio": "Open Source professional and geek. Also known as OTRS inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
|
||||
"followers": 215,
|
||||
"following": 260,
|
||||
"statuses": 114,
|
||||
"favorites": 8,
|
||||
"location": "",
|
||||
"site": "http://edenhofer.de/",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/1216362658/DSC_0084-p.jpg"
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "in/enjoyme"
|
||||
},
|
||||
"googleplus": {
|
||||
"handle": null
|
||||
},
|
||||
"aboutme": {
|
||||
"handle": null,
|
||||
"bio": null,
|
||||
"avatar": null
|
||||
},
|
||||
"gravatar": {
|
||||
"handle": "bazzi",
|
||||
"urls": [
|
||||
{
|
||||
"value": "http://edenhofer.de",
|
||||
"title": "Blog"
|
||||
},
|
||||
{
|
||||
"value": "http://znuny.com",
|
||||
"title": "Znuny - OTRS related services"
|
||||
}
|
||||
],
|
||||
"avatar": "http://2.gravatar.com/avatar/0e321a416c45d214d1040a7667cb0b54",
|
||||
"avatars": [
|
||||
{
|
||||
"url": "http://2.gravatar.com/avatar/0e321a416c45d214d1040a7667cb0b54",
|
||||
"type": "thumbnail"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fuzzy": false
|
||||
},
|
||||
"company": {
|
||||
"id": "2b30663f-f1a4-47a9-b2a9-0817b8d3ae7b",
|
||||
"name": "OTRS",
|
||||
"legalName": "OTRS AG",
|
||||
"domain": "otrs.com",
|
||||
"domainAliases": [
|
||||
"otrs.org"
|
||||
],
|
||||
"url": "http://otrs.com",
|
||||
"site": {
|
||||
"url": "http://otrs.com",
|
||||
"title": "OTRS Simple Service Management",
|
||||
"h1": "What is OTRS?",
|
||||
"metaDescription": "OTRS is an Open Source helpdesk software and an IT Service Management software free of licence costs. Improve your Customer Service Management with OTRS.",
|
||||
"metaAuthor": null,
|
||||
"phoneNumbers": [
|
||||
"+49 6172 681988",
|
||||
"+1 408-549-1717",
|
||||
"+49 5255 11689664",
|
||||
"+49 6032 0355578",
|
||||
"+49 9421 568181",
|
||||
"+1 408-512-1748",
|
||||
"+49 8523 6901503",
|
||||
"+49 6032 7258038",
|
||||
"+49 6032 0355568",
|
||||
"+49 551 141308205"
|
||||
],
|
||||
"emailAddresses": [
|
||||
"sales@otrs.com",
|
||||
"otrs-demo@otrs.org",
|
||||
"itsm-demo@otrs.org",
|
||||
"security@otrs.org",
|
||||
"investor-relations@otrs.com"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"sector": "Information Technology",
|
||||
"industryGroup": "Software & Services",
|
||||
"industry": "Internet Software & Services",
|
||||
"subIndustry": "Internet Software & Services"
|
||||
},
|
||||
"tags": [
|
||||
"Information Technology & Services",
|
||||
"Technology",
|
||||
"Software"
|
||||
],
|
||||
"description": "OTRS is an Open Source helpdesk software and an IT Service Management software free of licence costs. Improve your Customer Service Management with OTRS.",
|
||||
"foundedDate": null,
|
||||
"location": "Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"streetNumber": "1",
|
||||
"streetName": "Norsk-Data-Straße",
|
||||
"subPremise": null,
|
||||
"city": "Bad Homburg vor der Höhe",
|
||||
"postalCode": "61352",
|
||||
"state": "Hessen",
|
||||
"stateCode": "HE",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 50.21093,
|
||||
"lng": 8.652809999999999
|
||||
},
|
||||
"logo": "https://logo.clearbit.com/otrs.com",
|
||||
"facebook": {
|
||||
"handle": "otrsgroup"
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "company/otrs-ag"
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "OTRSGroup",
|
||||
"id": "126673991",
|
||||
"bio": "OTRS is the leading open source service management software including Help Desk and ITIL V3-certified IT service management (ITSM).",
|
||||
"followers": 2988,
|
||||
"following": 2484,
|
||||
"location": "Cupertino, CA, Bad Homburg",
|
||||
"site": "http://t.co/F09dcTEScJ",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/575314188848889856/F4KWmvVX_normal.png"
|
||||
},
|
||||
"crunchbase": {
|
||||
"handle": "organization/otrs"
|
||||
},
|
||||
"emailProvider": false,
|
||||
"type": "private",
|
||||
"ticker": null,
|
||||
"phone": null,
|
||||
"metrics": {
|
||||
"alexaUsRank": null,
|
||||
"alexaGlobalRank": 116381,
|
||||
"googleRank": 0,
|
||||
"employees": 15,
|
||||
"marketCap": null,
|
||||
"raised": null,
|
||||
"annualRevenue": null
|
||||
},
|
||||
"tech": [
|
||||
"google_analytics",
|
||||
"double_click",
|
||||
"google_adwords",
|
||||
"optimizely",
|
||||
"wordpress",
|
||||
"pardot"
|
||||
]
|
||||
}
|
||||
}
|
196
test/fixtures/clearbit/me@example.com.json
vendored
Normal file
196
test/fixtures/clearbit/me@example.com.json
vendored
Normal file
|
@ -0,0 +1,196 @@
|
|||
{
|
||||
"person": {
|
||||
"id": "4db7cfeb-8017-4aac-b4b9-debb6d3142c0",
|
||||
"name": {
|
||||
"fullName": "Martin Edenhofer",
|
||||
"givenName": "Martin",
|
||||
"familyName": "Edenhofer"
|
||||
},
|
||||
"email": "me@otrs.org",
|
||||
"gender": null,
|
||||
"location": "Berlin, Berlin, DE",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"city": "Berlin",
|
||||
"state": "Berlin",
|
||||
"stateCode": "Berlin",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 52.52000659999999,
|
||||
"lng": 13.404954
|
||||
},
|
||||
"bio": "Open Source professional and geek. Also known as OTRS inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
|
||||
"site": "http://edenhofer.de/",
|
||||
"avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/4db7cfeb-8017-4aac-b4b9-debb6d3142c0",
|
||||
"employment": {
|
||||
"domain": "otrs.org",
|
||||
"name": "OTRS",
|
||||
"title": "CEO",
|
||||
"role": null,
|
||||
"seniority": "executive"
|
||||
},
|
||||
"facebook": {
|
||||
"handle": null
|
||||
},
|
||||
"github": {
|
||||
"handle": null,
|
||||
"id": null,
|
||||
"avatar": null,
|
||||
"company": null,
|
||||
"blog": null,
|
||||
"followers": null,
|
||||
"following": null
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "medenhofer",
|
||||
"id": 219826253,
|
||||
"bio": "Open Source professional and geek. Also known as OTRS inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
|
||||
"followers": 215,
|
||||
"following": 260,
|
||||
"statuses": 114,
|
||||
"favorites": 8,
|
||||
"location": "",
|
||||
"site": "http://edenhofer.de/",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/1216362658/DSC_0084-p.jpg"
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "in/enjoyme"
|
||||
},
|
||||
"googleplus": {
|
||||
"handle": null
|
||||
},
|
||||
"aboutme": {
|
||||
"handle": null,
|
||||
"bio": null,
|
||||
"avatar": null
|
||||
},
|
||||
"gravatar": {
|
||||
"handle": "bazzi",
|
||||
"urls": [
|
||||
{
|
||||
"value": "http://edenhofer.de",
|
||||
"title": "Blog"
|
||||
},
|
||||
{
|
||||
"value": "http://znuny.com",
|
||||
"title": "Znuny - OTRS related services"
|
||||
}
|
||||
],
|
||||
"avatar": "http://2.gravatar.com/avatar/0e321a416c45d214d1040a7667cb0b54",
|
||||
"avatars": [
|
||||
{
|
||||
"url": "http://2.gravatar.com/avatar/0e321a416c45d214d1040a7667cb0b54",
|
||||
"type": "thumbnail"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fuzzy": false
|
||||
},
|
||||
"company": {
|
||||
"id": "2b30663f-f1a4-47a9-b2a9-0817b8d3ae7b",
|
||||
"name": "OTRS",
|
||||
"legalName": null,
|
||||
"domain": "otrs.com",
|
||||
"domainAliases": [
|
||||
"otrs.org"
|
||||
],
|
||||
"url": "http://otrs.com",
|
||||
"site": {
|
||||
"url": "http://otrs.com",
|
||||
"title": "OTRS Simple Service Management",
|
||||
"h1": "What is OTRS?",
|
||||
"metaDescription": "OTRS is an Open Source helpdesk software and an IT Service Management software free of licence costs. Improve your Customer Service Management with OTRS.",
|
||||
"metaAuthor": null,
|
||||
"phoneNumbers": [
|
||||
"+49 6172 681988",
|
||||
"+1 408-549-1717",
|
||||
"+49 5255 11689664",
|
||||
"+49 6032 0355578",
|
||||
"+49 9421 568181",
|
||||
"+1 408-512-1748",
|
||||
"+49 8523 6901503",
|
||||
"+49 6032 7258038",
|
||||
"+49 6032 0355568",
|
||||
"+49 551 141308205"
|
||||
],
|
||||
"emailAddresses": [
|
||||
"sales@otrs.com",
|
||||
"otrs-demo@otrs.org",
|
||||
"itsm-demo@otrs.org",
|
||||
"security@otrs.org",
|
||||
"investor-relations@otrs.com"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"sector": "Information Technology",
|
||||
"industryGroup": "Software & Services",
|
||||
"industry": "Internet Software & Services",
|
||||
"subIndustry": "Internet Software & Services"
|
||||
},
|
||||
"tags": [
|
||||
"Information Technology & Services",
|
||||
"Technology",
|
||||
"Software"
|
||||
],
|
||||
"description": "OTRS is an Open Source helpdesk software and an IT Service Management software free of licence costs. Improve your Customer Service Management with OTRS.",
|
||||
"foundedDate": null,
|
||||
"location": "Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"streetNumber": "1",
|
||||
"streetName": "Norsk-Data-Straße",
|
||||
"subPremise": null,
|
||||
"city": "Bad Homburg vor der Höhe",
|
||||
"postalCode": "61352",
|
||||
"state": "Hessen",
|
||||
"stateCode": "HE",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 50.21093,
|
||||
"lng": 8.652809999999999
|
||||
},
|
||||
"logo": "https://logo.clearbit.com/otrs.com",
|
||||
"facebook": {
|
||||
"handle": "otrsgroup"
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "company/otrs-ag"
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "OTRSGroup",
|
||||
"id": "126673991",
|
||||
"bio": "OTRS is the leading open source service management software including Help Desk and ITIL V3-certified IT service management (ITSM).",
|
||||
"followers": 2988,
|
||||
"following": 2484,
|
||||
"location": "Cupertino, CA, Bad Homburg",
|
||||
"site": "http://t.co/F09dcTEScJ",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/575314188848889856/F4KWmvVX_normal.png"
|
||||
},
|
||||
"crunchbase": {
|
||||
"handle": "organization/otrs"
|
||||
},
|
||||
"emailProvider": false,
|
||||
"type": "private",
|
||||
"ticker": null,
|
||||
"phone": null,
|
||||
"metrics": {
|
||||
"alexaUsRank": null,
|
||||
"alexaGlobalRank": 116381,
|
||||
"googleRank": 0,
|
||||
"employees": 15,
|
||||
"marketCap": null,
|
||||
"raised": null,
|
||||
"annualRevenue": null
|
||||
},
|
||||
"tech": [
|
||||
"google_analytics",
|
||||
"double_click",
|
||||
"google_adwords",
|
||||
"optimizely",
|
||||
"wordpress",
|
||||
"pardot"
|
||||
]
|
||||
}
|
||||
}
|
96
test/fixtures/clearbit/testing4@znuny.com.json
vendored
Normal file
96
test/fixtures/clearbit/testing4@znuny.com.json
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"person": null,
|
||||
"company": {
|
||||
"id": "273d8666-9d70-43dc-836b-a47a88293905",
|
||||
"name": "Znuny / ES for OTRS",
|
||||
"legalName": null,
|
||||
"domain": "znuny.com",
|
||||
"domainAliases": [
|
||||
"znuny.de"
|
||||
],
|
||||
"url": "http://znuny.com",
|
||||
"site": {
|
||||
"url": "http://znuny.com",
|
||||
"title": "Support, Consulting, Development and Training for OTRS - Znuny GmbH",
|
||||
"h1": "We make OTRS support easy!",
|
||||
"metaDescription": "OTRS Support, Consulting, Development, Training and Customizing - Znuny GmbH",
|
||||
"metaAuthor": null,
|
||||
"phoneNumbers": [
|
||||
"+49 30 6098541",
|
||||
"+49 4107 15880339",
|
||||
"+49 8601 81017925",
|
||||
"+49 4107 15880186",
|
||||
"+49 8602 16139061"
|
||||
],
|
||||
"emailAddresses": [
|
||||
"info@znuny.com"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"sector": "Industrials",
|
||||
"industryGroup": "Commercial & Professional Services",
|
||||
"industry": "Professional Services",
|
||||
"subIndustry": "Consulting"
|
||||
},
|
||||
"tags": [
|
||||
"Consulting & Professional Services",
|
||||
"Corporate & Business",
|
||||
"Information Technology & Services"
|
||||
],
|
||||
"description": "OTRS Support, Consulting, Development, Training and Customizing - Znuny GmbH",
|
||||
"foundedDate": null,
|
||||
"location": "Marienstraße 11, 10117 Berlin, Germany",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"streetNumber": "11",
|
||||
"streetName": "Marienstraße",
|
||||
"subPremise": null,
|
||||
"city": "Berlin",
|
||||
"postalCode": "10117",
|
||||
"state": "Berlin",
|
||||
"stateCode": "Berlin",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 52.52182,
|
||||
"lng": 13.38268
|
||||
},
|
||||
"logo": "https://logo.clearbit.com/znuny.com",
|
||||
"facebook": {
|
||||
"handle": null
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "company/znuny-gmbh"
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "znuny",
|
||||
"id": "293437546",
|
||||
"bio": "Enterprise Services for OTRS! We love to do what we can do!",
|
||||
"followers": 85,
|
||||
"following": 63,
|
||||
"location": "Berlin",
|
||||
"site": "http://t.co/miuzrhoHeG",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/2460325455/hix7so4b0h0miq9gwkw8_normal.png"
|
||||
},
|
||||
"crunchbase": {
|
||||
"handle": null
|
||||
},
|
||||
"emailProvider": false,
|
||||
"type": "private",
|
||||
"ticker": null,
|
||||
"phone": null,
|
||||
"metrics": {
|
||||
"alexaUsRank": null,
|
||||
"alexaGlobalRank": 10086408,
|
||||
"googleRank": 3,
|
||||
"employees": null,
|
||||
"marketCap": null,
|
||||
"raised": null,
|
||||
"annualRevenue": null
|
||||
},
|
||||
"tech": [
|
||||
"google_analytics",
|
||||
"ruby_on_rails"
|
||||
]
|
||||
}
|
||||
}
|
120
test/fixtures/clearbit/testing5@znuny.com.json
vendored
Normal file
120
test/fixtures/clearbit/testing5@znuny.com.json
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
{
|
||||
"person": {
|
||||
"id": "4db7cfeb-8017-4aac-b4b9-debb6d3142c0-1",
|
||||
"name": {
|
||||
"fullName": "Bob Smith",
|
||||
"givenName": "Bob",
|
||||
"familyName": "Smith"
|
||||
},
|
||||
"email": "testing5@znuny.com",
|
||||
"gender": null,
|
||||
"location": "Berlin, Berlin, DE",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"city": "Berlin",
|
||||
"state": "Berlin",
|
||||
"stateCode": "Berlin",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 52.52000659999999,
|
||||
"lng": 13.404954
|
||||
},
|
||||
"bio": "some_bio",
|
||||
"site": "http://example.com/",
|
||||
"avatar": "https://d1ts43dypk8bqh.cloudfront.net/v1/avatars/4db7cfeb-8017-4aac-b4b9-debb6d3142c0"
|
||||
},
|
||||
"company": {
|
||||
"id": "273d8666-9d70-43dc-836b-a47a88293905",
|
||||
"name": "Znuny2",
|
||||
"legalName": null,
|
||||
"domain": "znuny.com",
|
||||
"domainAliases": [
|
||||
"znuny.de"
|
||||
],
|
||||
"url": "http://znuny.com",
|
||||
"site": {
|
||||
"url": "http://znuny.com",
|
||||
"title": "Support, Consulting, Development and Training for OTRS - Znuny GmbH",
|
||||
"h1": "We make OTRS support easy!",
|
||||
"metaDescription": "OTRS Support, Consulting, Development, Training and Customizing - Znuny GmbH",
|
||||
"metaAuthor": null,
|
||||
"phoneNumbers": [
|
||||
"+49 30 6098541",
|
||||
"+49 4107 15880339",
|
||||
"+49 8601 81017925",
|
||||
"+49 4107 15880186",
|
||||
"+49 8602 16139061"
|
||||
],
|
||||
"emailAddresses": [
|
||||
"info@znuny.com"
|
||||
]
|
||||
},
|
||||
"category": {
|
||||
"sector": "Industrials",
|
||||
"industryGroup": "Commercial & Professional Services",
|
||||
"industry": "Professional Services",
|
||||
"subIndustry": "Consulting"
|
||||
},
|
||||
"tags": [
|
||||
"Consulting & Professional Services",
|
||||
"Corporate & Business",
|
||||
"Information Technology & Services"
|
||||
],
|
||||
"description": "Znuny2 GmbH",
|
||||
"foundedDate": null,
|
||||
"location": "Marienstraße 11, 10117 Berlin, Germany",
|
||||
"timeZone": "Europe/Berlin",
|
||||
"utcOffset": 2,
|
||||
"geo": {
|
||||
"streetNumber": "11",
|
||||
"streetName": "Marienstraße",
|
||||
"subPremise": null,
|
||||
"city": "Berlin",
|
||||
"postalCode": "10117",
|
||||
"state": "Berlin",
|
||||
"stateCode": "Berlin",
|
||||
"country": "Germany",
|
||||
"countryCode": "DE",
|
||||
"lat": 52.52182,
|
||||
"lng": 13.38268
|
||||
},
|
||||
"logo": "https://logo.clearbit.com/znuny.com",
|
||||
"facebook": {
|
||||
"handle": null
|
||||
},
|
||||
"linkedin": {
|
||||
"handle": "company/znuny-gmbh"
|
||||
},
|
||||
"twitter": {
|
||||
"handle": "znuny",
|
||||
"id": "293437546",
|
||||
"bio": "Enterprise Services for OTRS! We love to do what we can do!",
|
||||
"followers": 85,
|
||||
"following": 63,
|
||||
"location": "Berlin",
|
||||
"site": "http://t.co/miuzrhoHeG",
|
||||
"avatar": "https://pbs.twimg.com/profile_images/2460325455/hix7so4b0h0miq9gwkw8_normal.png"
|
||||
},
|
||||
"crunchbase": {
|
||||
"handle": null
|
||||
},
|
||||
"emailProvider": false,
|
||||
"type": "private",
|
||||
"ticker": null,
|
||||
"phone": null,
|
||||
"metrics": {
|
||||
"alexaUsRank": null,
|
||||
"alexaGlobalRank": 10086408,
|
||||
"googleRank": 3,
|
||||
"employees": null,
|
||||
"marketCap": null,
|
||||
"raised": null,
|
||||
"annualRevenue": null
|
||||
},
|
||||
"tech": [
|
||||
"google_analytics",
|
||||
"ruby_on_rails"
|
||||
]
|
||||
}
|
||||
}
|
281
test/integration/clearbit_test.rb
Normal file
281
test/integration/clearbit_test.rb
Normal file
|
@ -0,0 +1,281 @@
|
|||
# encoding: utf-8
|
||||
require 'integration_test_helper'
|
||||
|
||||
class ClearbitTest < ActiveSupport::TestCase
|
||||
|
||||
# check
|
||||
test 'base' do
|
||||
if !ENV['CLEARBIT_CI_API_KEY']
|
||||
raise "ERROR: Need CLEARBIT_CI_API_KEY - hint CLEARBIT_CI_API_KEY='abc...'"
|
||||
end
|
||||
|
||||
# set system mode to done / to activate
|
||||
Setting.set('system_init_done', true)
|
||||
|
||||
Setting.set('clearbit_integration', true)
|
||||
Setting.set('clearbit_config', {
|
||||
api_key: ENV['CLEARBIT_CI_API_KEY'],
|
||||
organization_autocreate: true,
|
||||
organization_shared: false,
|
||||
user_sync: {
|
||||
'person.name.givenName' => 'user.firstname',
|
||||
'person.name.familyName' => 'user.lastname',
|
||||
'person.email' => 'user.email',
|
||||
'person.bio' => 'user.note',
|
||||
'company.url' => 'user.web',
|
||||
'person.site' => 'user.web',
|
||||
'company.location' => 'user.address',
|
||||
'person.location' => 'user.address',
|
||||
#'person.timeZone' => 'user.preferences[:timezone]',
|
||||
#'person.gender' => 'user.preferences[:gender]',
|
||||
},
|
||||
organization_sync: {
|
||||
'company.legalName' => 'organization.name',
|
||||
'company.name' => 'organization.name',
|
||||
'company.description' => 'organization.note',
|
||||
},
|
||||
})
|
||||
|
||||
# case 1 - person + company (demo data set)
|
||||
customer1 = User.create(
|
||||
firstname: '',
|
||||
lastname: 'Should be still there',
|
||||
email: 'alex@alexmaccaw.com',
|
||||
note: '',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert(customer1)
|
||||
|
||||
Observer::Transaction.commit
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'User', o_id: customer1.id))
|
||||
|
||||
customer1_lookup = User.lookup(id: customer1.id)
|
||||
|
||||
assert_equal('Alex', customer1_lookup.firstname)
|
||||
assert_equal('Should be still there', customer1_lookup.lastname)
|
||||
assert_equal('O\'Reilly author, software engineer & traveller. Founder of https://clearbit.com', customer1_lookup.note)
|
||||
assert_equal('1455 Market Street, San Francisco, CA 94103, USA', customer1_lookup.address)
|
||||
|
||||
organization1_lookup = Organization.find_by(name: 'Uber, Inc.')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization1_lookup.id))
|
||||
assert_equal(false, organization1_lookup.shared)
|
||||
assert_equal('Uber is a mobile app connecting passengers with drivers for hire.', organization1_lookup.note)
|
||||
|
||||
# case 2 - person + company
|
||||
customer2 = User.create(
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
email: 'me@example.com',
|
||||
note: '',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert(customer2)
|
||||
|
||||
Observer::Transaction.commit
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'User', o_id: customer2.id))
|
||||
|
||||
customer2_lookup = User.lookup(id: customer2.id)
|
||||
|
||||
assert_equal('Martin', customer2_lookup.firstname)
|
||||
assert_equal('Edenhofer', customer2_lookup.lastname)
|
||||
assert_equal("Open Source professional and geek. Also known as OTRS inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.", customer2_lookup.note)
|
||||
assert_equal('Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany', customer2_lookup.address)
|
||||
|
||||
organization2_lookup = Organization.find_by(name: 'OTRS')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization2_lookup.id))
|
||||
assert_equal(false, organization2_lookup.shared)
|
||||
assert_equal('OTRS is an Open Source helpdesk software and an IT Service Management software free of licence costs. Improve your Customer Service Management with OTRS.', organization2_lookup.note)
|
||||
|
||||
# update with own values (do not overwrite)
|
||||
customer2.update_attributes(
|
||||
firstname: 'Martini',
|
||||
note: 'changed by my self',
|
||||
)
|
||||
|
||||
Observer::Transaction.commit
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'User', o_id: customer2.id))
|
||||
|
||||
customer2_lookup = User.lookup(id: customer2.id)
|
||||
|
||||
assert_equal('Martini', customer2_lookup.firstname)
|
||||
assert_equal('Edenhofer', customer2_lookup.lastname)
|
||||
assert_equal('changed by my self', customer2_lookup.note)
|
||||
assert_equal('Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany', customer2_lookup.address)
|
||||
|
||||
Transaction::ClearbitEnrichment.sync_user(customer2)
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
customer2_lookup = User.lookup(id: customer2.id)
|
||||
|
||||
assert_equal('Martini', customer2_lookup.firstname)
|
||||
assert_equal('Edenhofer', customer2_lookup.lastname)
|
||||
assert_equal('changed by my self', customer2_lookup.note)
|
||||
assert_equal('Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany', customer2_lookup.address)
|
||||
|
||||
# update with own values (do not overwrite)
|
||||
customer2.update_attributes(
|
||||
firstname: '',
|
||||
note: 'changed by my self',
|
||||
)
|
||||
|
||||
Transaction::ClearbitEnrichment.sync_user(customer2)
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
customer2_lookup = User.lookup(id: customer2.id)
|
||||
|
||||
assert_equal('Martin', customer2_lookup.firstname)
|
||||
assert_equal('Edenhofer', customer2_lookup.lastname)
|
||||
assert_equal('changed by my self', customer2_lookup.note)
|
||||
assert_equal('Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany', customer2_lookup.address)
|
||||
|
||||
# update with changed values at clearbit site (do overwrite)
|
||||
customer2.update_attributes(
|
||||
email: 'me2@example.com',
|
||||
)
|
||||
|
||||
Transaction::ClearbitEnrichment.sync_user(customer2)
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
customer2_lookup = User.lookup(id: customer2.id)
|
||||
|
||||
assert_equal('Martini', customer2_lookup.firstname)
|
||||
assert_equal('Edenhofer', customer2_lookup.lastname)
|
||||
assert_equal('changed by my self', customer2_lookup.note)
|
||||
assert_equal('Norsk-Data-Straße 1, 61352 Bad Homburg vor der Höhe, Germany', customer2_lookup.address)
|
||||
|
||||
organization2_lookup = Organization.find_by(name: 'OTRS AG')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization2_lookup.id))
|
||||
assert_equal(false, organization2_lookup.shared)
|
||||
assert_equal('OTRS is an Open Source helpdesk software and an IT Service Management software free of licence costs. Improve your Customer Service Management with OTRS.', organization2_lookup.note)
|
||||
|
||||
# case 3 - no person
|
||||
customer3 = User.create(
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
email: 'testing4@znuny.com',
|
||||
note: '',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert(customer3)
|
||||
|
||||
Observer::Transaction.commit
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
assert_not(ExternalSync.find_by(source: 'clearbit', object: 'User', o_id: customer3.id))
|
||||
|
||||
customer3_lookup = User.lookup(id: customer3.id)
|
||||
assert_not_equal(customer3.updated_at, customer3_lookup.updated_at)
|
||||
|
||||
assert_equal('', customer3_lookup.firstname)
|
||||
assert_equal('', customer3_lookup.lastname)
|
||||
assert_equal('', customer3_lookup.note)
|
||||
assert_equal('http://znuny.com', customer3_lookup.web)
|
||||
assert_equal('Marienstraße 11, 10117 Berlin, Germany', customer3_lookup.address)
|
||||
|
||||
organization3_lookup = Organization.find_by(name: 'Znuny / ES for OTRS')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization3_lookup.id))
|
||||
assert_equal(false, organization3_lookup.shared)
|
||||
assert_equal('OTRS Support, Consulting, Development, Training and Customizing - Znuny GmbH', organization3_lookup.note)
|
||||
|
||||
# case 4 - no person / real api call
|
||||
customer4 = User.create(
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
email: 'testing5@clearbit.com',
|
||||
note: '',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert(customer4)
|
||||
|
||||
Observer::Transaction.commit
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
assert_not(ExternalSync.find_by(source: 'clearbit', object: 'User', o_id: customer4.id))
|
||||
|
||||
customer4_lookup = User.lookup(id: customer4.id)
|
||||
assert_not_equal(customer4.updated_at, customer4_lookup.updated_at)
|
||||
|
||||
assert_equal('', customer4_lookup.firstname)
|
||||
assert_equal('', customer4_lookup.lastname)
|
||||
assert_equal('', customer4_lookup.note)
|
||||
assert_equal('http://clearbit.com', customer4_lookup.web)
|
||||
assert_equal('', customer4_lookup.address)
|
||||
|
||||
organization4_lookup = Organization.find_by(name: 'Clearbit')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization4_lookup.id))
|
||||
assert_equal(false, organization4_lookup.shared)
|
||||
assert_equal('Clearbit provides powerful products and data APIs to help your business grow. Contact enrichment, lead generation, financial compliance, and more...', organization4_lookup.note)
|
||||
|
||||
end
|
||||
|
||||
# check
|
||||
test 'base with invalid input' do
|
||||
if !ENV['CLEARBIT_CI_API_KEY']
|
||||
raise "ERROR: Need CLEARBIT_CI_API_KEY - hint CLEARBIT_CI_API_KEY='abc...'"
|
||||
end
|
||||
|
||||
# set system mode to done / to activate
|
||||
Setting.set('system_init_done', true)
|
||||
|
||||
Setting.set('clearbit_integration', true)
|
||||
Setting.set('clearbit_config', {
|
||||
api_key: ENV['CLEARBIT_CI_API_KEY'],
|
||||
organization_autocreate: true,
|
||||
organization_shared: true,
|
||||
user_sync: {
|
||||
'person.name.givenName' => 'user.firstname',
|
||||
'person.name.familyName' => 'user.lastname',
|
||||
'person.email' => 'user.email',
|
||||
'person.bio' => 'user.note_not_existing',
|
||||
'company.url' => 'user.web',
|
||||
'person.site' => 'user.web',
|
||||
'company.location' => 'user.address',
|
||||
'person.location' => 'user.address',
|
||||
},
|
||||
organization_sync: {
|
||||
'company.legalName' => 'organization.name',
|
||||
'company.name' => 'organization.name',
|
||||
'company.description' => 'organization.note_not_existing',
|
||||
},
|
||||
})
|
||||
|
||||
# case 1 - person + company (demo data set)
|
||||
customer1 = User.create(
|
||||
firstname: '',
|
||||
lastname: 'Should be still there',
|
||||
email: 'testing5@znuny.com',
|
||||
note: '',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert(customer1)
|
||||
|
||||
Observer::Transaction.commit
|
||||
Delayed::Worker.new.work_off
|
||||
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'User', o_id: customer1.id))
|
||||
|
||||
customer1_lookup = User.lookup(id: customer1.id)
|
||||
|
||||
assert_equal('Bob', customer1_lookup.firstname)
|
||||
assert_equal('Should be still there', customer1_lookup.lastname)
|
||||
assert_equal('', customer1_lookup.note)
|
||||
assert_equal('Marienstraße 11, 10117 Berlin, Germany', customer1_lookup.address)
|
||||
|
||||
organization1_lookup = Organization.find_by(name: 'Znuny2')
|
||||
assert(ExternalSync.find_by(source: 'clearbit', object: 'Organization', o_id: organization1_lookup.id))
|
||||
assert_equal(true, organization1_lookup.shared)
|
||||
assert_equal('', organization1_lookup.note)
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue