active_campaign 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +4 -0
- data/.rspec +2 -1
- data/.rubocop.yml +19 -0
- data/.travis.yml +5 -7
- data/Gemfile +10 -11
- data/README.md +21 -6
- data/Rakefile +14 -1
- data/active_campaign.gemspec +13 -11
- data/circle.yml +16 -0
- data/lib/active_campaign.rb +26 -28
- data/lib/active_campaign/client.rb +75 -75
- data/lib/active_campaign/client/campaigns.rb +5 -20
- data/lib/active_campaign/client/contacts.rb +17 -26
- data/lib/active_campaign/client/lists.rb +6 -4
- data/lib/active_campaign/client/messages.rb +3 -19
- data/lib/active_campaign/configuration.rb +35 -0
- data/lib/active_campaign/error.rb +36 -26
- data/lib/active_campaign/version.rb +1 -1
- data/spec/active_campaign_spec.rb +6 -12
- data/spec/cassettes/ActiveCampaign_Client_Contacts/_contact_sync/when_successful/returns_1_for_result_code.json +1 -1
- data/spec/cassettes/ActiveCampaign_Client_Contacts/_contact_view/can_find_contact_by_id.json +1 -1
- data/spec/cassettes/ActiveCampaign_Client_Lists/_list_list/can_find_a_list_of_lists.json +1 -1
- data/spec/cassettes/ActiveCampaign_Client_Lists/_list_view/can_find_lists_by_id.json +1 -1
- data/spec/client/contacts_spec.rb +24 -23
- data/spec/client/lists_spec.rb +8 -10
- data/spec/client_spec.rb +1 -2
- data/spec/spec_helper.rb +14 -53
- data/spec/support/coverage.rb +12 -0
- data/spec/support/vcr.rb +27 -0
- data/spec/support/webmock.rb +2 -0
- metadata +41 -6
- data/lib/active_campaign/configurable.rb +0 -66
- data/lib/active_campaign/default.rb +0 -81
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f49cb05b48c6d485e7aeef4c124e5ffc4a497065
|
4
|
+
data.tar.gz: eb82879f1a6a707ee4ca92a66ef0220b07e60048
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 920f478ce29086f94efdd3787be205f81b7b4118bf48ca1cd2d23c3470afaa98f7939b7e9cc02a0aace15097c871116ee780bb7e91c47e9cecedb95c52a4d70c
|
7
|
+
data.tar.gz: 2177d9dc0f1b73e32edf76cbd96a56d4bb2dc3354be9d3c223338d1a06bec2dfacdb137d77dca1e64a4b217f721af4c217db4bc9ef164f2bda2b5fa871e1e74a
|
data/.codeclimate.yml
ADDED
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# AllCops:
|
2
|
+
# Include:
|
3
|
+
# Exclude:
|
4
|
+
|
5
|
+
Documentation:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
ParameterLists:
|
9
|
+
Enabled: true
|
10
|
+
Max: 5
|
11
|
+
CountKeywordArgs: false
|
12
|
+
|
13
|
+
LineLength:
|
14
|
+
Enabled: true
|
15
|
+
Max: 107
|
16
|
+
|
17
|
+
IfUnlessModifier:
|
18
|
+
Enabled: false
|
19
|
+
MaxLineLength: 79
|
data/.travis.yml
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
before_script:
|
2
|
-
- chmod 600 spec/fixtures/.netrc
|
3
1
|
bundler_args: --without development
|
2
|
+
|
4
3
|
language: ruby
|
4
|
+
|
5
5
|
rvm:
|
6
|
-
- jruby-18mode
|
7
6
|
- jruby-19mode
|
8
|
-
- rbx-18mode
|
9
|
-
- rbx-19mode
|
10
7
|
- rbx-2.1.1
|
11
|
-
- 1.8.7
|
12
8
|
- 1.9.2
|
13
9
|
- 1.9.3
|
14
|
-
- 2.0.0
|
10
|
+
- 2.0.0
|
11
|
+
- 2.1.6
|
12
|
+
- 2.2.2
|
data/Gemfile
CHANGED
@@ -1,23 +1,22 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'rake'
|
4
|
-
gem 'activesupport'
|
5
3
|
gem 'rubysl', '~> 2', platform: :rbx
|
6
4
|
|
7
5
|
group :development do
|
8
|
-
gem '
|
9
|
-
gem 'pry'
|
6
|
+
gem 'pry', platform: :mri
|
10
7
|
end
|
11
8
|
|
12
9
|
group :test do
|
13
|
-
gem 'simplecov',
|
14
|
-
gem
|
15
|
-
gem
|
10
|
+
gem 'simplecov', '>= 0.9.4'
|
11
|
+
gem 'rubinius-coverage', platform: :rbx
|
12
|
+
gem 'codeclimate-test-reporter', require: false
|
16
13
|
gem 'coveralls', require: false
|
17
|
-
gem 'rb-fsevent'
|
18
|
-
gem 'rspec', '~> 2.
|
19
|
-
gem 'vcr'
|
20
|
-
gem 'webmock'
|
14
|
+
gem 'rb-fsevent'
|
15
|
+
gem 'rspec', '~> 3.2.0'
|
16
|
+
gem 'vcr'
|
17
|
+
gem 'webmock'
|
18
|
+
gem 'rubocop'
|
19
|
+
gem 'fuubar'
|
21
20
|
end
|
22
21
|
|
23
22
|
gemspec
|
data/README.md
CHANGED
@@ -24,6 +24,21 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
Read their [API documentation](http://www.activecampaign.com/api/overview.php)for how to use this gem.
|
26
26
|
|
27
|
+
```ruby
|
28
|
+
# To setup the client
|
29
|
+
client = ::ActiveCampaign::Client.new(
|
30
|
+
api_endpoint: 'YOUR-ENDPOINT', # e.g. 'https://yourendpoint.api-us1.com'
|
31
|
+
api_key: 'YOUR-API-KEY') # e.g. 'a4e60a1ba200595d5cc37ede5732545184165e'
|
32
|
+
|
33
|
+
# or configure globally for all clients
|
34
|
+
::ActiveCampaign.configure do |config|
|
35
|
+
config.api_endpoint = 'YOUR-ENDPOINT', # e.g. 'https://yourendpoint.api-us1.com'
|
36
|
+
config.api_key = 'YOUR-API-KEY') # e.g. 'a4e60a1ba200595d5cc37ede5732545184165e'
|
37
|
+
end
|
38
|
+
|
39
|
+
```
|
40
|
+
|
41
|
+
|
27
42
|
```ruby
|
28
43
|
# To fetch all lists
|
29
44
|
ActiveCampaign.list_list ids: 'all'
|
@@ -34,12 +49,12 @@ ActiveCampaign.list_list ids: 'all'
|
|
34
49
|
# you have to resort to some really ugly hacks. Due to the form serialization # type of API (read not a object oriented REST API) you need to translate
|
35
50
|
# something pretty into something horrific when it comes to the parameters.
|
36
51
|
ActiveCampaign.contact_sync({
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
"status[#{user.active_campaign_list_id}" => user.receive_emails ? 1 : 2
|
52
|
+
"id" => user.active_campaign_contact_id,
|
53
|
+
"email" => user.email,
|
54
|
+
"first_name" => user.first,
|
55
|
+
"last_name" => user.last,
|
56
|
+
"p[#{user.active_campaign_list_id}]" => user.active_campaign_list_id,
|
57
|
+
"status[#{user.active_campaign_list_id}]" => user.receive_emails ? 1 : 2
|
43
58
|
})
|
44
59
|
|
45
60
|
# Another example of syncing a contact:
|
data/Rakefile
CHANGED
@@ -1 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
|
5
|
+
desc 'Run RuboCop on the lib directory'
|
6
|
+
RuboCop::RakeTask.new(:style) do |task|
|
7
|
+
task.formatters = ['fuubar']
|
8
|
+
task.options = %w(--display-cop-names)
|
9
|
+
task.fail_on_error = true
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new(:spec)
|
13
|
+
|
14
|
+
task default: [:style, :spec]
|
data/active_campaign.gemspec
CHANGED
@@ -4,20 +4,22 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'active_campaign/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'active_campaign'
|
8
8
|
spec.version = ActiveCampaign::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
9
|
+
spec.authors = ['Mikael Henriksson']
|
10
|
+
spec.email = ['mikael@zoolutions.se']
|
11
|
+
spec.description = 'A simple ruby wrapper for the ActiveCampaign API'
|
12
|
+
spec.summary = 'See http://www.activecampaign.com/api/overview.php for more information'
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.files = `git ls-files`.split(
|
16
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
21
|
+
spec.add_dependency 'httpi'
|
22
|
+
spec.add_dependency 'hashie'
|
23
|
+
spec.add_dependency 'activesupport'
|
24
|
+
spec.add_dependency 'multi_json'
|
23
25
|
end
|
data/circle.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
machine:
|
2
|
+
ruby:
|
3
|
+
version: 2.2.2
|
4
|
+
|
5
|
+
dependencies:
|
6
|
+
bundler:
|
7
|
+
without: [production, staging, benchmarking]
|
8
|
+
cache_directories:
|
9
|
+
- vendor/bundle_java
|
10
|
+
- vendor/bundle
|
11
|
+
override:
|
12
|
+
- rvm-exec 2.2.2 bundle install
|
13
|
+
|
14
|
+
test:
|
15
|
+
override:
|
16
|
+
- rvm-exec 2.2.2 bundle exec rspec
|
data/lib/active_campaign.rb
CHANGED
@@ -1,41 +1,39 @@
|
|
1
|
-
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
2
4
|
require 'active_campaign/client'
|
3
|
-
require 'active_campaign/
|
5
|
+
require 'active_campaign/configuration'
|
4
6
|
|
5
7
|
module ActiveCampaign
|
8
|
+
extend Configuration
|
6
9
|
|
7
|
-
|
10
|
+
module_function
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
unless defined?(@client) && @client.same_options?(options)
|
16
|
-
@client = ActiveCampaign::Client.new(options)
|
17
|
-
end
|
18
|
-
|
19
|
-
@client
|
12
|
+
# API client based on configured options {Configurable}
|
13
|
+
#
|
14
|
+
# @return [ActiveCampaign::Client] API wrapper
|
15
|
+
def client
|
16
|
+
unless defined?(@client) && @client.same_options?(configuration)
|
17
|
+
@client = ActiveCampaign::Client.new(configuration)
|
20
18
|
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
@client
|
21
|
+
end
|
22
|
+
|
23
|
+
# @private
|
24
|
+
def respond_to_missing?(method_name, include_private = false)
|
25
|
+
client.respond_to?(method_name, include_private)
|
26
|
+
end if RUBY_VERSION >= '1.9'
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
# @private
|
29
|
+
def respond_to?(method_name, include_private = false)
|
30
|
+
client.respond_to?(method_name, include_private) || super
|
31
|
+
end if RUBY_VERSION < '1.9'
|
31
32
|
|
32
33
|
private
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
35
|
+
def method_missing(method_name, *args, &block)
|
36
|
+
return super unless client.respond_to?(method_name)
|
37
|
+
client.send(method_name, *args, &block)
|
38
38
|
end
|
39
|
-
|
40
|
-
ActiveCampaign.setup
|
41
39
|
end
|
@@ -1,33 +1,36 @@
|
|
1
|
-
require '
|
1
|
+
require 'httpi'
|
2
|
+
require 'hashie'
|
3
|
+
|
2
4
|
require 'active_campaign/client/contacts'
|
3
5
|
require 'active_campaign/client/lists'
|
4
6
|
require 'active_campaign/client/campaigns'
|
5
|
-
require 'httpi'
|
6
|
-
require 'hashie'
|
7
7
|
|
8
8
|
module ActiveCampaign
|
9
9
|
class Client
|
10
|
-
include
|
10
|
+
include Comparable
|
11
11
|
include ActiveCampaign::Client::Contacts
|
12
12
|
include ActiveCampaign::Client::Lists
|
13
13
|
include ActiveCampaign::Client::Campaigns
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
delegate :api_key, :api_output, :api_endpoint, :user_agent, :log, :log_level,
|
16
|
+
:logger, :mash, :debug, to: :config
|
17
|
+
|
18
|
+
attr_accessor :config
|
19
|
+
|
20
|
+
def initialize(configuration = nil)
|
21
|
+
self.config = configuration
|
22
|
+
self.config ||= ActiveCampaign.configuration
|
20
23
|
end
|
21
24
|
|
22
25
|
# Compares client options to a Hash of requested options
|
23
26
|
#
|
24
27
|
# @param opts [Hash] Options to compare with current client options
|
25
28
|
# @return [Boolean]
|
26
|
-
def same_options?(
|
27
|
-
|
29
|
+
def same_options?(other_config)
|
30
|
+
config.to_h.sort == other_config.to_h.sort
|
28
31
|
end
|
29
32
|
|
30
|
-
|
33
|
+
# Make a HTTP GET request
|
31
34
|
#
|
32
35
|
# @param url [String] The path, relative to {#api_endpoint}
|
33
36
|
# @param options [Hash] Query and header params for request
|
@@ -36,6 +39,15 @@ module ActiveCampaign
|
|
36
39
|
request :get, api_method, options
|
37
40
|
end
|
38
41
|
|
42
|
+
def hash
|
43
|
+
[config, Client].hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def <=>(other)
|
47
|
+
other.is_a?(ActiveCampaign::Client) &&
|
48
|
+
config.to_h.sort <=> other.config.to_h.sort
|
49
|
+
end
|
50
|
+
|
39
51
|
# Make a HTTP POST request
|
40
52
|
#
|
41
53
|
# @param url [String] The path, relative to {#api_endpoint}
|
@@ -47,81 +59,69 @@ module ActiveCampaign
|
|
47
59
|
|
48
60
|
private
|
49
61
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
|
62
|
+
def request(method, api_method, data)
|
63
|
+
req = create_request method, api_method, data
|
64
|
+
response = HTTPI.send(method, req)
|
65
|
+
response = JSON.parse(response.body)
|
66
|
+
normalize(response)
|
67
|
+
end
|
58
68
|
|
59
|
-
|
60
|
-
|
69
|
+
def create_request(method, api_method, options = {})
|
70
|
+
req = HTTPI::Request.new(
|
71
|
+
url: File.join(api_endpoint),
|
72
|
+
headers: { 'User-Agent' => user_agent },
|
73
|
+
query: query(method, api_method, options),
|
74
|
+
body: body(method, api_method, options)
|
75
|
+
)
|
76
|
+
req.auth.ssl.verify_mode = :none
|
77
|
+
req.auth.ssl.ssl_version = :TLSv1
|
78
|
+
req
|
79
|
+
end
|
61
80
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
81
|
+
def query(method, api_method, options = {})
|
82
|
+
q = options.delete(:query) { Hash.new }
|
83
|
+
q.merge!(api_key: api_key,
|
84
|
+
api_action: api_method.to_s,
|
85
|
+
api_output: api_output)
|
66
86
|
|
67
|
-
|
68
|
-
end
|
87
|
+
q.merge!(options) if method == :get
|
69
88
|
|
70
|
-
|
71
|
-
|
72
|
-
q.merge!({
|
73
|
-
:api_key => api_key,
|
74
|
-
:api_action => api_method.to_s,
|
75
|
-
:api_output => api_output
|
76
|
-
})
|
89
|
+
q
|
90
|
+
end
|
77
91
|
|
78
|
-
|
79
|
-
|
80
|
-
end
|
92
|
+
def body(method, _api_method, options = {})
|
93
|
+
return nil unless method == :post
|
81
94
|
|
82
|
-
|
95
|
+
fields = options.delete(:fields) { Hash.new }
|
96
|
+
options[:field] = fields.inject({}) do |hash, (k, v)|
|
97
|
+
hash.merge("%#{k}%,0" => v)
|
83
98
|
end
|
84
99
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
fields = options.delete(:fields){ Hash.new }
|
89
|
-
options[:field] = fields.inject({}) do |hash, (k,v)|
|
90
|
-
hash.merge("%#{k}%,0" => v)
|
91
|
-
end
|
100
|
+
options.to_query
|
101
|
+
end
|
92
102
|
|
93
|
-
|
103
|
+
def normalize(response)
|
104
|
+
keys, values = keys_values(response)
|
105
|
+
if keys.all? { |key| numeric?(key) }
|
106
|
+
response[:results] = values
|
107
|
+
keys.each { |key| response.delete(key) }
|
94
108
|
end
|
95
109
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
if keys.all?{|key| is_numeric?(key) }
|
100
|
-
response[:results] = values
|
101
|
-
keys.each do |key|
|
102
|
-
response.delete(key)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
if mash
|
107
|
-
Hashie::Mash.new response
|
108
|
-
else
|
109
|
-
ActiveSupport::HashWithIndifferentAccess.new(response)
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
110
|
+
return Hashie::Mash.new response if mash
|
111
|
+
ActiveSupport::HashWithIndifferentAccess.new(response)
|
112
|
+
end
|
113
113
|
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
def numeric?(string)
|
115
|
+
string.to_s.match(/\A[+-]?\d+\Z/).nil? ? false : true
|
116
|
+
end
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
118
|
+
def keys_values(response)
|
119
|
+
results = results(response)
|
120
|
+
[results.keys, results.values]
|
121
|
+
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
123
|
+
def results(response)
|
124
|
+
response.reject { |k, _v| %w(result_code result_message result_output).include?(k) }
|
125
|
+
end
|
126
126
|
end
|
127
|
-
end
|
127
|
+
end
|