killbill-zendesk 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +38 -0
- data/Gemfile +3 -0
- data/Jarfile +3 -0
- data/README.md +71 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/config.ru +4 -0
- data/db/ddl.sql +10 -0
- data/db/schema.rb +13 -0
- data/killbill-zendesk.gemspec +41 -0
- data/killbill.properties +3 -0
- data/lib/zendesk/config/application.rb +36 -0
- data/lib/zendesk/user_updater.rb +115 -0
- data/lib/zendesk/user_updater_initializer.rb +44 -0
- data/lib/zendesk/zendesk_user.rb +6 -0
- data/lib/zendesk.rb +26 -0
- data/pom.xml +44 -0
- data/release.sh +28 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/zendesk/remote/integration_spec.rb +86 -0
- data/spec/zendesk/user_updater_spec.rb +34 -0
- metadata +219 -0
data/.gitignore
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.swp
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
coverage
|
7
|
+
InstalledFiles
|
8
|
+
lib/bundler/man
|
9
|
+
pkg
|
10
|
+
rdoc
|
11
|
+
spec/reports
|
12
|
+
test/tmp
|
13
|
+
test/version_tmp
|
14
|
+
tmp
|
15
|
+
|
16
|
+
# YARD artifacts
|
17
|
+
.yardoc
|
18
|
+
_yardoc
|
19
|
+
doc/
|
20
|
+
|
21
|
+
.jbundler
|
22
|
+
Jarfile.lock
|
23
|
+
Gemfile.lock
|
24
|
+
|
25
|
+
.DS_Store
|
26
|
+
|
27
|
+
# Build directory
|
28
|
+
killbill-zendesk/
|
29
|
+
|
30
|
+
# Config file
|
31
|
+
zendesk.yml
|
32
|
+
|
33
|
+
target
|
34
|
+
pom.xml.asc
|
35
|
+
|
36
|
+
.idea/
|
37
|
+
|
38
|
+
test.db
|
data/Gemfile
ADDED
data/Jarfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
killbill-zendesk-plugin
|
2
|
+
=======================
|
3
|
+
|
4
|
+
Plugin to mirror Kill Bill data into Zendesk.
|
5
|
+
|
6
|
+
User data mapping
|
7
|
+
-----------------
|
8
|
+
|
9
|
+
<table>
|
10
|
+
<tr>
|
11
|
+
<th>Zendesk attribute</th><th>Value</th>
|
12
|
+
</tr>
|
13
|
+
<tr>
|
14
|
+
<td>name</td><td><em>Kill Bill account name</em></td>
|
15
|
+
</tr>
|
16
|
+
<tr>
|
17
|
+
<td>external_id</td><td><em>Kill Bill account external key</em> if specified, <em>Kill Bill account id</em> otherwise</td>
|
18
|
+
</tr>
|
19
|
+
<tr>
|
20
|
+
<td>locale</td><td><em>Kill Bill account locale</em></td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<td>time_zone</td><td><em>Kill Bill account timezone</em></td>
|
24
|
+
</tr>
|
25
|
+
<tr>
|
26
|
+
<td>email</td><td><em>Kill Bill account email</em></td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<td>phone</td><td><em>Kill Bill account phone</em></td>
|
30
|
+
</tr>
|
31
|
+
<tr>
|
32
|
+
<td>details</td><td><em>Kill Bill account address1</em>, <em>Kill Bill account address2</em>, <em>Kill Bill account city</em>, <em>Kill Bill account state or province</em>, <em>Kill Bill account postal code</em>, <em>Kill Bill account country</em></td>
|
33
|
+
</tr>
|
34
|
+
</table>
|
35
|
+
|
36
|
+
|
37
|
+
Requirements
|
38
|
+
------------
|
39
|
+
|
40
|
+
The plugin needs a database to keep a local mapping between Kill Bill account ids and Zendesk user ids (this is to work around indexing delays in Zendesk). The latest version of the schema can be found here: https://raw.github.com/killbill/killbill-zendesk-plugin/master/db/ddl.sql.
|
41
|
+
|
42
|
+
|
43
|
+
Configuration
|
44
|
+
-------------
|
45
|
+
|
46
|
+
The plugin expects a `zendesk.yml` configuration file containing the following:
|
47
|
+
|
48
|
+
```
|
49
|
+
:zendesk:
|
50
|
+
:subdomain: 'mysubdomain'
|
51
|
+
:username: 'email@domain.com'
|
52
|
+
:password: 'password'
|
53
|
+
# Alternatively, to use Token Authentication or OAuth
|
54
|
+
#token: 'kX53RIXZKUFhZxSYhRxe7QGFocTkDmmERDxpcddF'
|
55
|
+
#access_token: 'kX53RIXZKUFhZxSYhRxe7QGFocTkDmmERDxpcddF'
|
56
|
+
# Optional
|
57
|
+
# :retry: true
|
58
|
+
|
59
|
+
:database:
|
60
|
+
:adapter: 'sqlite3'
|
61
|
+
:database: 'test.db'
|
62
|
+
# For MySQL
|
63
|
+
# :adapter: 'jdbc'
|
64
|
+
# :username: 'your-username'
|
65
|
+
# :password: 'your-password'
|
66
|
+
# :driver: 'com.mysql.jdbc.Driver'
|
67
|
+
# :url: 'jdbc:mysql://127.0.0.1:3306/your-database'
|
68
|
+
```
|
69
|
+
|
70
|
+
By default, the plugin will look at the plugin directory root (where `killbill.properties` is located) to find this file.
|
71
|
+
Alternatively, set the Kill Bill system property `-Dcom.ning.billing.osgi.bundles.jruby.conf.dir=/my/directory` to specify another location.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
# Install tasks to build and release the plugin
|
4
|
+
require 'bundler/setup'
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
7
|
+
# Install test tasks
|
8
|
+
require 'rspec/core/rake_task'
|
9
|
+
namespace :test do
|
10
|
+
desc 'Run RSpec tests'
|
11
|
+
RSpec::Core::RakeTask.new do |task|
|
12
|
+
task.name = 'spec'
|
13
|
+
task.pattern = './spec/*/*_spec.rb'
|
14
|
+
end
|
15
|
+
|
16
|
+
namespace :remote do
|
17
|
+
desc 'Run RSpec remote tests'
|
18
|
+
RSpec::Core::RakeTask.new do |task|
|
19
|
+
task.name = 'spec'
|
20
|
+
task.pattern = './spec/*/remote/*_spec.rb'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Install tasks to package the plugin for Killbill
|
26
|
+
require 'killbill/rake_task'
|
27
|
+
Killbill::PluginHelper.install_tasks
|
28
|
+
|
29
|
+
# Run tests by default
|
30
|
+
task :default => 'test:spec'
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/config.ru
ADDED
data/db/ddl.sql
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
CREATE TABLE `zendesk_users` (
|
2
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
3
|
+
`kb_account_id` varchar(255) NOT NULL,
|
4
|
+
`zd_user_id` int(11) NOT NULL,
|
5
|
+
`created_at` datetime NOT NULL,
|
6
|
+
`updated_at` datetime NOT NULL,
|
7
|
+
PRIMARY KEY (`id`),
|
8
|
+
UNIQUE KEY `index_zendesk_users_on_kb_account_id` (`kb_account_id`),
|
9
|
+
UNIQUE KEY `index_zendesk_users_on_zd_user_id` (`zd_user_id`)
|
10
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
data/db/schema.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define(:version => 20130606153635) do
|
4
|
+
create_table 'zendesk_users', :force => true do |t|
|
5
|
+
t.string 'kb_account_id', :null => false
|
6
|
+
t.integer 'zd_user_id', :null => false
|
7
|
+
t.datetime 'created_at', :null => false
|
8
|
+
t.datetime 'updated_at', :null => false
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index(:zendesk_users, :kb_account_id, :unique => true)
|
12
|
+
add_index(:zendesk_users, :zd_user_id, :unique => true)
|
13
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'killbill-zendesk'
|
5
|
+
s.version = version
|
6
|
+
s.summary = 'Plugin to mirror Kill Bill data into Zendesk'
|
7
|
+
s.description = 'Kill Bill notification plugin for Zendesk.'
|
8
|
+
|
9
|
+
s.required_ruby_version = '>= 1.9.3'
|
10
|
+
|
11
|
+
s.license = 'Apache License (2.0)'
|
12
|
+
|
13
|
+
s.author = 'Kill Bill core team'
|
14
|
+
s.email = 'killbilling-users@googlegroups.com'
|
15
|
+
s.homepage = 'http://kill-bill.org'
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.bindir = 'bin'
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.rdoc_options << '--exclude' << '.'
|
24
|
+
|
25
|
+
s.add_dependency 'killbill', '~> 1.0.19'
|
26
|
+
s.add_dependency 'sinatra', '~> 1.3.4'
|
27
|
+
s.add_dependency 'zendesk_api', '~> 0.3.10'
|
28
|
+
s.add_dependency 'activerecord', '~> 3.2.1'
|
29
|
+
if defined?(JRUBY_VERSION)
|
30
|
+
s.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.2.9'
|
31
|
+
end
|
32
|
+
|
33
|
+
s.add_development_dependency 'jbundler', '~> 0.4.1'
|
34
|
+
s.add_development_dependency 'rake', '>= 10.0.0'
|
35
|
+
s.add_development_dependency 'rspec', '~> 2.12.0'
|
36
|
+
if defined?(JRUBY_VERSION)
|
37
|
+
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.2.6'
|
38
|
+
else
|
39
|
+
s.add_development_dependency 'sqlite3', '~> 1.3.7'
|
40
|
+
end
|
41
|
+
end
|
data/killbill.properties
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
configure do
|
2
|
+
# Usage: rackup -Ilib -E test
|
3
|
+
if (development? or test?) and !Killbill::Zendesk::UserUpdaterInitializer.instance.initialized?
|
4
|
+
require 'logger'
|
5
|
+
Killbill::Zendesk::UserUpdaterInitializer.instance.initialize! File.expand_path(File.dirname(__FILE__) + '../../../../'),
|
6
|
+
nil,
|
7
|
+
Logger.new(STDOUT)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# curl -v -d'webrick=stupid' -XPUT http://127.0.0.1:9292/plugins/killbill-zendesk/users/6939c8c0-cf89-11e2-8b8b-0800200c9a66
|
12
|
+
put '/plugins/killbill-zendesk/users/:id' do
|
13
|
+
zendesk_user_url = Killbill::Zendesk::UserUpdaterInitializer.instance.updater.update(params[:id])
|
14
|
+
|
15
|
+
if zendesk_user_url
|
16
|
+
redirect zendesk_user_url
|
17
|
+
else
|
18
|
+
status 500, "Unable to update Zendesk user for id #{params[:id]}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# curl -v http://127.0.0.1:9292/plugins/killbill-zendesk/users/6939c8c0-cf89-11e2-8b8b-0800200c9a66
|
23
|
+
# Given a Kill Bill account id or Zendesk user id, retrieve the Kill Bill - Zendesk mapping
|
24
|
+
get '/plugins/killbill-zendesk/users/:id', :provides => 'json' do
|
25
|
+
if params[:id] =~ /[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}/
|
26
|
+
mapping = Killbill::Zendesk::ZendeskUser.find_by_kb_account_id(params[:id])
|
27
|
+
else
|
28
|
+
mapping = Killbill::Zendesk::ZendeskUser.find_by_zd_user_id(params[:id])
|
29
|
+
end
|
30
|
+
|
31
|
+
if mapping
|
32
|
+
mapping.to_json
|
33
|
+
else
|
34
|
+
status 404
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Killbill::Zendesk
|
2
|
+
class UserUpdater
|
3
|
+
def initialize(client, kb_apis, logger)
|
4
|
+
@client = client
|
5
|
+
@kb_apis = kb_apis
|
6
|
+
@logger = logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def update(lookup_key)
|
10
|
+
kb_account = lookup_kb_account(lookup_key)
|
11
|
+
|
12
|
+
user = find_by_kb_account(kb_account)
|
13
|
+
user = create_user(kb_account) if user.nil?
|
14
|
+
|
15
|
+
user.name = kb_account.name
|
16
|
+
user.external_id = kb_account.external_key || kb_account.id.to_s
|
17
|
+
user.locale = kb_account.locale
|
18
|
+
user.timezone = kb_account.time_zone
|
19
|
+
user.email = kb_account.email
|
20
|
+
user.phone = kb_account.phone
|
21
|
+
user.details = build_details_field(kb_account)
|
22
|
+
|
23
|
+
if user.save
|
24
|
+
@logger.info "Successfully updated #{user.name} in Zendesk: #{user.url}"
|
25
|
+
user.url
|
26
|
+
else
|
27
|
+
@logger.warn "Unable to update #{user.name} in Zendesk: #{user.url}"
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Find the Kill Bill account associated with that lookup_key (account id or external key)
|
33
|
+
def lookup_kb_account(lookup_key)
|
34
|
+
if lookup_key.is_a?(Killbill::Plugin::Model::UUID)
|
35
|
+
@kb_apis.get_account_by_id(lookup_key)
|
36
|
+
else
|
37
|
+
lookup_key_s = lookup_key.to_s
|
38
|
+
if lookup_key_s =~ /[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}/
|
39
|
+
lookup_kb_account(Killbill::Plugin::Model::UUID.new(lookup_key_s))
|
40
|
+
else
|
41
|
+
@kb_apis.get_account_by_key(lookup_key_s)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Build the Zendesk details field (address information)
|
47
|
+
def build_details_field(kb_account)
|
48
|
+
details = [kb_account.address1, kb_account.address2, kb_account.city, kb_account.state_or_province, kb_account.postal_code, kb_account.country]
|
49
|
+
(details.reject { |detail| detail.blank? }).join(', ')
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a user in Zendesk and save the id mapping locally
|
53
|
+
def create_user(kb_account)
|
54
|
+
# Create the user in Zendesk
|
55
|
+
user = @client.users.create(:name => kb_account.name)
|
56
|
+
|
57
|
+
# Save the mapping locally - this is required due to the indexing lag on the Zendesk side,
|
58
|
+
# see https://support.zendesk.com/entries/20239737:
|
59
|
+
# When you add new data to your Zendesk, it typically takes about 2 to 3 minutes before it's indexed and can be searched.
|
60
|
+
# This is unacceptable for us: if an account creation event is quickly followed by a account update event,
|
61
|
+
# we wouldn't be able to retrieve the user, potentially causing duplicates and/or triggering validation errors, e.g.
|
62
|
+
# Email 1370587241-test@tester.com is already being used by another user
|
63
|
+
ZendeskUser.create! :kb_account_id => kb_account.id.to_s, :zd_user_id => user.id
|
64
|
+
|
65
|
+
user
|
66
|
+
end
|
67
|
+
|
68
|
+
# Find the Zendesk user associated with that Kill Bill account
|
69
|
+
def find_by_kb_account(kb_account)
|
70
|
+
# Do we have already a mapping for that user?
|
71
|
+
zd_account = find_by_id(kb_account.id.to_s)
|
72
|
+
return zd_account if zd_account
|
73
|
+
|
74
|
+
# TODO In the search results below, should we worry about potential dups?
|
75
|
+
|
76
|
+
# First search by external_id, which is the safest method.
|
77
|
+
# The external_id is either the account external key...
|
78
|
+
zd_account = find_by_external_id(kb_account.external_key) if kb_account.external_key
|
79
|
+
return zd_account if zd_account
|
80
|
+
|
81
|
+
# ...or the Kill Bill account id
|
82
|
+
zd_account = find_by_external_id(kb_account.id.to_s)
|
83
|
+
return zd_account if zd_account
|
84
|
+
|
85
|
+
# At this point, we haven't matched this user yet. To reconcile it, use the email address which is guaranteed
|
86
|
+
# to exist on the Zendesk side
|
87
|
+
zd_account = find_by_email(kb_account.email) if kb_account.email
|
88
|
+
return zd_account if zd_account
|
89
|
+
|
90
|
+
# We couldn't find a match - the account will be created
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
def find_by_id(kb_account_id)
|
95
|
+
zd_user = ZendeskUser.find_by_kb_account_id(kb_account_id)
|
96
|
+
zd_user ? @client.users.find(:id => zd_user.zd_user_id) : nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def find_by_external_id(external_id)
|
100
|
+
find_all_by_external_id(external_id).first
|
101
|
+
end
|
102
|
+
|
103
|
+
def find_all_by_external_id(external_id)
|
104
|
+
@client.search(:query => "type:user external_id:#{external_id}", :reload => true)
|
105
|
+
end
|
106
|
+
|
107
|
+
def find_by_email(email)
|
108
|
+
find_all_by_email(email).first
|
109
|
+
end
|
110
|
+
|
111
|
+
def find_all_by_email(email)
|
112
|
+
@client.search(:query => "type:user email:#{email}", :reload => true)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Killbill::Zendesk
|
2
|
+
class UserUpdaterInitializer
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
attr_reader :updater
|
6
|
+
|
7
|
+
def initialize!(conf_dir, kb_apis, logger)
|
8
|
+
# Parse the config file
|
9
|
+
begin
|
10
|
+
@config = YAML.load_file("#{conf_dir}/zendesk.yml")
|
11
|
+
rescue Errno::ENOENT
|
12
|
+
logger.warn "Unable to find the config file #{conf_dir}/zendesk.yml"
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
client = ZendeskAPI::Client.new do |config|
|
17
|
+
config.url = "https://#{@config[:zendesk][:subdomain]}.zendesk.com/api/v2"
|
18
|
+
|
19
|
+
config.username = @config[:zendesk][:username]
|
20
|
+
config.password = @config[:zendesk][:password]
|
21
|
+
config.token = @config[:zendesk][:token]
|
22
|
+
# Not yet available?
|
23
|
+
#config.access_token = @config[:zendesk][:access_token]
|
24
|
+
config.retry = true if @config[:zendesk][:retry]
|
25
|
+
|
26
|
+
config.logger = logger
|
27
|
+
end
|
28
|
+
|
29
|
+
if defined?(JRUBY_VERSION)
|
30
|
+
# See https://github.com/jruby/activerecord-jdbc-adapter/issues/302
|
31
|
+
require 'jdbc/mysql'
|
32
|
+
Jdbc::MySQL.load_driver(:require) if Jdbc::MySQL.respond_to?(:load_driver)
|
33
|
+
end
|
34
|
+
|
35
|
+
ActiveRecord::Base.establish_connection(@config[:database])
|
36
|
+
|
37
|
+
@updater = UserUpdater.new(client, kb_apis, logger)
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialized?
|
41
|
+
!@updater.nil?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/zendesk.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'sinatra'
|
3
|
+
|
4
|
+
require 'killbill'
|
5
|
+
require 'zendesk_api'
|
6
|
+
|
7
|
+
require 'zendesk/zendesk_user'
|
8
|
+
require 'zendesk/user_updater'
|
9
|
+
require 'zendesk/user_updater_initializer'
|
10
|
+
|
11
|
+
module Killbill::Zendesk
|
12
|
+
class ZendeskPlugin < Killbill::Plugin::Notification
|
13
|
+
|
14
|
+
# For testing
|
15
|
+
attr_reader :updater
|
16
|
+
|
17
|
+
def start_plugin
|
18
|
+
super
|
19
|
+
@updater = Killbill::Zendesk::UserUpdaterInitializer.instance.initialize!(@conf_dir, @kb_apis, @logger)
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_event(event)
|
23
|
+
@updater.update(event.account_id) if [:ACCOUNT_CREATION, :ACCOUNT_CHANGE].include?(event.event_type.enum)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/pom.xml
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!--
|
3
|
+
~ Copyright 2010-2013 Ning, Inc.
|
4
|
+
~
|
5
|
+
~ Ning licenses this file to you under the Apache License, version 2.0
|
6
|
+
~ (the "License"); you may not use this file except in compliance with the
|
7
|
+
~ License. You may obtain a copy of the License at:
|
8
|
+
~
|
9
|
+
~ http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
~
|
11
|
+
~ Unless required by applicable law or agreed to in writing, software
|
12
|
+
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
+
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
+
~ License for the specific language governing permissions and limitations
|
15
|
+
~ under the License.
|
16
|
+
-->
|
17
|
+
|
18
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
19
|
+
<parent>
|
20
|
+
<groupId>org.sonatype.oss</groupId>
|
21
|
+
<artifactId>oss-parent</artifactId>
|
22
|
+
<version>5</version>
|
23
|
+
</parent>
|
24
|
+
<modelVersion>4.0.0</modelVersion>
|
25
|
+
<groupId>com.ning.killbill.ruby</groupId>
|
26
|
+
<artifactId>zendesk-plugin</artifactId>
|
27
|
+
<packaging>pom</packaging>
|
28
|
+
<version>0.1.0</version>
|
29
|
+
<name>zendesk-plugin</name>
|
30
|
+
<url>http://github.com/killbill/killbill-zendesk-plugin</url>
|
31
|
+
<description>Plugin to mirror Kill Bill data into Zendesk</description>
|
32
|
+
<licenses>
|
33
|
+
<license>
|
34
|
+
<name>Apache License 2.0</name>
|
35
|
+
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
|
36
|
+
<distribution>repo</distribution>
|
37
|
+
</license>
|
38
|
+
</licenses>
|
39
|
+
<scm>
|
40
|
+
<connection>scm:git:git://github.com/killbill/killbill-zendesk-plugin.git</connection>
|
41
|
+
<url>https://github.com/killbill/killbill-zendesk-plugin/</url>
|
42
|
+
<developerConnection>scm:git:git@github.com:killbill/killbill-zendesk-plugin.git</developerConnection>
|
43
|
+
</scm>
|
44
|
+
</project>
|
data/release.sh
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
set -e
|
2
|
+
|
3
|
+
VERSION=`grep -E '<version>([0-9]+\.[0-9]+\.[0-9]+)</version>' pom.xml | sed 's/[\t \n]*<version>\(.*\)<\/version>[\t \n]*/\1/'`
|
4
|
+
if [ "$VERSION" != "$(cat $PWD/VERSION)" ]; then
|
5
|
+
echo "Unable to release: make sure the versions in pom.xml and VERSION match"
|
6
|
+
exit 1
|
7
|
+
fi
|
8
|
+
|
9
|
+
echo "Cleaning up"
|
10
|
+
rake killbill:clean ; rake build
|
11
|
+
|
12
|
+
echo "Pushing the gem to Rubygems"
|
13
|
+
rake release
|
14
|
+
|
15
|
+
echo "Building artifact"
|
16
|
+
rake killbill:package
|
17
|
+
|
18
|
+
ARTIFACT="$PWD/pkg/killbill-zendesk-$VERSION.tar.gz"
|
19
|
+
echo "Pushing $ARTIFACT to Maven Central"
|
20
|
+
mvn gpg:sign-and-deploy-file \
|
21
|
+
-DgroupId=com.ning.killbill.ruby \
|
22
|
+
-DartifactId=zendesk-plugin \
|
23
|
+
-Dversion=$VERSION \
|
24
|
+
-Dpackaging=tar.gz \
|
25
|
+
-DrepositoryId=ossrh-releases \
|
26
|
+
-Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ \
|
27
|
+
-Dfile=$ARTIFACT \
|
28
|
+
-DpomFile=pom.xml
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'zendesk'
|
3
|
+
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.color_enabled = true
|
10
|
+
config.tty = true
|
11
|
+
config.formatter = 'documentation'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'active_record'
|
15
|
+
ActiveRecord::Base.establish_connection(
|
16
|
+
:adapter => 'sqlite3',
|
17
|
+
:database => 'test.db'
|
18
|
+
)
|
19
|
+
# Create the schema
|
20
|
+
require File.expand_path(File.dirname(__FILE__) + '../../db/schema.rb')
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class KillbillApiWithFakeGetAccountById < Killbill::Plugin::KillbillApi
|
4
|
+
def initialize(*args)
|
5
|
+
super(*args)
|
6
|
+
@accounts = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_account(id, external_key, name, email)
|
10
|
+
@accounts[id.to_s] = Killbill::Plugin::Model::Account.new(id, nil, nil, nil, external_key, name, 1, email, 1, 'USD', nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, true)
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_account_by_id(id)
|
14
|
+
@accounts[id.to_s]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class MockEvent
|
19
|
+
attr_reader :event_type
|
20
|
+
attr_reader :account_id
|
21
|
+
|
22
|
+
def initialize(event_type, account_id)
|
23
|
+
@event_type = event_type
|
24
|
+
@account_id = account_id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Killbill::Zendesk::ZendeskPlugin do
|
29
|
+
before(:each) do
|
30
|
+
@plugin = Killbill::Zendesk::ZendeskPlugin.new
|
31
|
+
@plugin.conf_dir = File.expand_path(File.dirname(__FILE__) + '../../../../')
|
32
|
+
|
33
|
+
logger = Logger.new(STDOUT)
|
34
|
+
logger.level = Logger::DEBUG
|
35
|
+
@plugin.logger = logger
|
36
|
+
|
37
|
+
@plugin.kb_apis = KillbillApiWithFakeGetAccountById.new(nil)
|
38
|
+
|
39
|
+
@plugin.start_plugin
|
40
|
+
end
|
41
|
+
|
42
|
+
after(:each) do
|
43
|
+
@plugin.stop_plugin
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should be able to create and update a user' do
|
47
|
+
external_key, kb_account_id = create_kb_account
|
48
|
+
|
49
|
+
# Verify the initial state of our table
|
50
|
+
Killbill::Zendesk::ZendeskUser.count.should == 0
|
51
|
+
|
52
|
+
# Verify the account doesn't exist yet
|
53
|
+
@plugin.updater.find_by_external_id(external_key).should be_nil
|
54
|
+
|
55
|
+
# Send a creation event
|
56
|
+
@plugin.on_event MockEvent.new(Killbill::Plugin::Model::ExtBusEventType.new(:ACCOUNT_CREATION), kb_account_id)
|
57
|
+
|
58
|
+
# We should now verify the account exists, but we can't, due to indexing lag :/
|
59
|
+
#@plugin.updater.find_by_external_id(external_key).email.should == email
|
60
|
+
# Instead, we use our table
|
61
|
+
Killbill::Zendesk::ZendeskUser.count.should == 1
|
62
|
+
|
63
|
+
# Send an update event
|
64
|
+
@plugin.on_event MockEvent.new(Killbill::Plugin::Model::ExtBusEventType.new(:ACCOUNT_CHANGE), kb_account_id)
|
65
|
+
|
66
|
+
# Verify we didn't create dups
|
67
|
+
#@plugin.updater.find_all_by_external_id(external_key).count.should == 1
|
68
|
+
Killbill::Zendesk::ZendeskUser.count.should == 1
|
69
|
+
|
70
|
+
# Create a new user
|
71
|
+
external_key, kb_account_id = create_kb_account
|
72
|
+
@plugin.on_event MockEvent.new(Killbill::Plugin::Model::ExtBusEventType.new(:ACCOUNT_CREATION), kb_account_id)
|
73
|
+
|
74
|
+
Killbill::Zendesk::ZendeskUser.count.should == 2
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def create_kb_account
|
80
|
+
external_key = Time.now.to_i.to_s + '-test'
|
81
|
+
kb_account_id = Killbill::Plugin::Model::UUID.new(external_key)
|
82
|
+
email = external_key + '@tester.com'
|
83
|
+
@plugin.kb_apis.create_account(kb_account_id, external_key, 'Test tester', email)
|
84
|
+
return external_key, kb_account_id
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Killbill::Zendesk::UserUpdater do
|
4
|
+
it 'should build the details line' do
|
5
|
+
updater = Killbill::Zendesk::UserUpdater.new(nil, nil, nil)
|
6
|
+
|
7
|
+
account = build_account(nil, nil, nil, nil, nil, nil)
|
8
|
+
updater.build_details_field(account).should == ''
|
9
|
+
|
10
|
+
account = build_account('493 Slro road', nil, nil, nil, nil, nil)
|
11
|
+
updater.build_details_field(account).should == '493 Slro road'
|
12
|
+
|
13
|
+
account = build_account('493 Slro road', nil, 'Fola', nil, nil, nil)
|
14
|
+
updater.build_details_field(account).should == '493 Slro road, Fola'
|
15
|
+
|
16
|
+
account = build_account('493 Slro road', nil, 'Fola', 'FG', nil, nil)
|
17
|
+
updater.build_details_field(account).should == '493 Slro road, Fola, FG'
|
18
|
+
|
19
|
+
account = build_account('493 Slro road', nil, 'Fola', 'FG', 140, nil)
|
20
|
+
updater.build_details_field(account).should == '493 Slro road, Fola, FG, 140'
|
21
|
+
|
22
|
+
account = build_account('493 Slro road', 'apt 33', 'Fola', 'FG', 140, nil)
|
23
|
+
updater.build_details_field(account).should == '493 Slro road, apt 33, Fola, FG, 140'
|
24
|
+
|
25
|
+
account = build_account('493 Slro road', 'apt 33', 'Fola', 'FG', 140, 'Floq')
|
26
|
+
updater.build_details_field(account).should == '493 Slro road, apt 33, Fola, FG, 140, Floq'
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def build_account(address1, address2, city, state_or_province, postal_code, country)
|
32
|
+
Killbill::Plugin::Model::Account.new(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, address1, address2, nil, city, state_or_province, postal_code, country, nil, nil, nil)
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: killbill-zendesk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kill Bill core team
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: killbill
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 1.0.19
|
21
|
+
none: false
|
22
|
+
requirement: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.19
|
27
|
+
none: false
|
28
|
+
prerelease: false
|
29
|
+
type: :runtime
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sinatra
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - "~>"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.3.4
|
37
|
+
none: false
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - "~>"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.3.4
|
43
|
+
none: false
|
44
|
+
prerelease: false
|
45
|
+
type: :runtime
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: zendesk_api
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - "~>"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.3.10
|
53
|
+
none: false
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - "~>"
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 0.3.10
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
type: :runtime
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activerecord
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.2.1
|
69
|
+
none: false
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 3.2.1
|
75
|
+
none: false
|
76
|
+
prerelease: false
|
77
|
+
type: :runtime
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: activerecord-jdbcmysql-adapter
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - "~>"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.2.9
|
85
|
+
none: false
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.2.9
|
91
|
+
none: false
|
92
|
+
prerelease: false
|
93
|
+
type: :runtime
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: jbundler
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 0.4.1
|
101
|
+
none: false
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - "~>"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 0.4.1
|
107
|
+
none: false
|
108
|
+
prerelease: false
|
109
|
+
type: :development
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rake
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 10.0.0
|
117
|
+
none: false
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 10.0.0
|
123
|
+
none: false
|
124
|
+
prerelease: false
|
125
|
+
type: :development
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rspec
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - "~>"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 2.12.0
|
133
|
+
none: false
|
134
|
+
requirement: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.12.0
|
139
|
+
none: false
|
140
|
+
prerelease: false
|
141
|
+
type: :development
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: activerecord-jdbcsqlite3-adapter
|
144
|
+
version_requirements: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - "~>"
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 1.2.6
|
149
|
+
none: false
|
150
|
+
requirement: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - "~>"
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: 1.2.6
|
155
|
+
none: false
|
156
|
+
prerelease: false
|
157
|
+
type: :development
|
158
|
+
description: Kill Bill notification plugin for Zendesk.
|
159
|
+
email: killbilling-users@googlegroups.com
|
160
|
+
executables: []
|
161
|
+
extensions: []
|
162
|
+
extra_rdoc_files: []
|
163
|
+
files:
|
164
|
+
- ".gitignore"
|
165
|
+
- Gemfile
|
166
|
+
- Jarfile
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- VERSION
|
170
|
+
- config.ru
|
171
|
+
- db/ddl.sql
|
172
|
+
- db/schema.rb
|
173
|
+
- killbill-zendesk.gemspec
|
174
|
+
- killbill.properties
|
175
|
+
- lib/zendesk.rb
|
176
|
+
- lib/zendesk/config/application.rb
|
177
|
+
- lib/zendesk/user_updater.rb
|
178
|
+
- lib/zendesk/user_updater_initializer.rb
|
179
|
+
- lib/zendesk/zendesk_user.rb
|
180
|
+
- pom.xml
|
181
|
+
- release.sh
|
182
|
+
- spec/spec_helper.rb
|
183
|
+
- spec/zendesk/remote/integration_spec.rb
|
184
|
+
- spec/zendesk/user_updater_spec.rb
|
185
|
+
homepage: http://kill-bill.org
|
186
|
+
licenses:
|
187
|
+
- Apache License (2.0)
|
188
|
+
post_install_message:
|
189
|
+
rdoc_options:
|
190
|
+
- "--exclude"
|
191
|
+
- "."
|
192
|
+
require_paths:
|
193
|
+
- lib
|
194
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: 1.9.3
|
199
|
+
none: false
|
200
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
|
+
requirements:
|
202
|
+
- - ">="
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
segments:
|
205
|
+
- 0
|
206
|
+
version: !binary |-
|
207
|
+
MA==
|
208
|
+
hash: 2
|
209
|
+
none: false
|
210
|
+
requirements: []
|
211
|
+
rubyforge_project:
|
212
|
+
rubygems_version: 1.8.24
|
213
|
+
signing_key:
|
214
|
+
specification_version: 3
|
215
|
+
summary: Plugin to mirror Kill Bill data into Zendesk
|
216
|
+
test_files:
|
217
|
+
- spec/spec_helper.rb
|
218
|
+
- spec/zendesk/remote/integration_spec.rb
|
219
|
+
- spec/zendesk/user_updater_spec.rb
|