mautic_api 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +32 -0
- data/lib/mautic_api.rb +41 -0
- data/lib/mautic_api/api/api.rb +248 -0
- data/lib/mautic_api/api/companies.rb +11 -0
- data/lib/mautic_api/api/contacts.rb +96 -0
- data/lib/mautic_api/api/segments.rb +33 -0
- data/lib/mautic_api/auth/abstract_auth.rb +258 -0
- data/lib/mautic_api/auth/api_auth.rb +57 -0
- data/lib/mautic_api/auth/auth.rb +6 -0
- data/lib/mautic_api/auth/auth_interface.rb +29 -0
- data/lib/mautic_api/auth/oauth2.rb +62 -0
- data/lib/mautic_api/engine.rb +10 -0
- data/lib/mautic_api/exception/context_not_found_exception.rb +14 -0
- data/lib/mautic_api/version.rb +3 -0
- data/lib/tasks/mautic_api_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +78 -0
- data/test/dummy/config/environments/test.rb +39 -0
- data/test/dummy/config/initializers/assets.rb +8 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/mautic_api_test.rb +7 -0
- data/test/test_helper.rb +18 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6c0377d4275602d93edfae7d0ac8109d516d7e6baabd86e6101d97b9b3924eba
|
4
|
+
data.tar.gz: 2718533221f8c003cd4dee335a5abc02345da7748a17f43c83b72c00c3c33521
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 990ec179a899e644717cede7fad70babd70af5adc63a4d5a9ff18cf0dca8aad3697943f6e7ab175005315cb89ea33ba91c63b137480cb96b846de16f7b6de9bd
|
7
|
+
data.tar.gz: e5b1324f9521bf3480dce847b5ace649628da43affd445083cc4ad2c65feeab938c275434063a057c4a96a09468c7a049064529ff2b8c64509150b7dadcd0e64
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'MauticApi'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task default: :test
|
data/lib/mautic_api.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# @package Mautic
|
2
|
+
# @copyright 2016 trampos.co. All rights reserved.
|
3
|
+
# @author marcel@trampos.co
|
4
|
+
# @link http://trampos.co
|
5
|
+
# @license MIT http://opensource.org/licenses/MIT
|
6
|
+
|
7
|
+
require "mautic_api/engine"
|
8
|
+
|
9
|
+
module MauticApi
|
10
|
+
|
11
|
+
autoload :Auth, 'mautic_api/auth/auth'
|
12
|
+
autoload :Api, 'mautic_api/api/api'
|
13
|
+
autoload :Contacts, 'mautic_api/api/contacts'
|
14
|
+
autoload :Companies, 'mautic_api/api/companies'
|
15
|
+
autoload :Segments, 'mautic_api/api/segments'
|
16
|
+
autoload :ContextNotFoundException, 'mautic_api/exception/context_not_found_exception'
|
17
|
+
|
18
|
+
|
19
|
+
class Context
|
20
|
+
|
21
|
+
# Get an API context object
|
22
|
+
#
|
23
|
+
# @param string $apiContext API context (leads, forms, etc)
|
24
|
+
# @param AuthInterface $auth API Auth object
|
25
|
+
# @param string $baseUrl Base URL for API endpoints
|
26
|
+
#
|
27
|
+
# @return Api\Api
|
28
|
+
# @throws ContextNotFoundException
|
29
|
+
|
30
|
+
def new_api api_context, auth, base_url=""
|
31
|
+
|
32
|
+
class_name = "MauticApi::#{api_context.camelize}"
|
33
|
+
|
34
|
+
if Object.const_defined?(class_name)
|
35
|
+
return class_name.constantize.new(auth, base_url)
|
36
|
+
else
|
37
|
+
raise ContextNotFoundException "A context of 'api_context' was not found."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
module MauticApi
|
2
|
+
|
3
|
+
class Api
|
4
|
+
|
5
|
+
attr_accessor :base_url, :auth
|
6
|
+
|
7
|
+
ENDPOINT = ""
|
8
|
+
LIST_NAME = ""
|
9
|
+
ITEM_NAME = ""
|
10
|
+
|
11
|
+
BASE_API_ENDPOINT = 'api'
|
12
|
+
|
13
|
+
def endpoint
|
14
|
+
self.class::ENDPOINT
|
15
|
+
end
|
16
|
+
|
17
|
+
def list_name
|
18
|
+
self.class::LIST_NAME
|
19
|
+
end
|
20
|
+
|
21
|
+
def item_name
|
22
|
+
self.class::ITEM_NAME
|
23
|
+
end
|
24
|
+
|
25
|
+
def base_api_endpoint
|
26
|
+
self.class::BASE_API_ENDPOINT
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize auth, base_url
|
30
|
+
@auth = auth
|
31
|
+
set_base_url(base_url)
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_base_url url
|
35
|
+
url += "/" if url[-1] != "/"
|
36
|
+
url += "api/" if url[-4,4] != "api/"
|
37
|
+
@base_url = url
|
38
|
+
return self
|
39
|
+
end
|
40
|
+
|
41
|
+
def action_not_supported action
|
42
|
+
return {
|
43
|
+
error: {
|
44
|
+
code: 500,
|
45
|
+
message: "#{action} is not supported at this time."
|
46
|
+
}
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
# Make the API request
|
51
|
+
#
|
52
|
+
# @param $endpoint
|
53
|
+
# @param array parameters
|
54
|
+
# @param string method
|
55
|
+
#
|
56
|
+
# @return array
|
57
|
+
# @throws \Exception
|
58
|
+
|
59
|
+
def make_request endpoint, parameters = {}, method = :get, settings = {}
|
60
|
+
|
61
|
+
response = {}
|
62
|
+
|
63
|
+
# Validate if this endpoint has a BC url
|
64
|
+
bc_endpoint = nil
|
65
|
+
|
66
|
+
if @bc_attempt
|
67
|
+
if @bc_regex_endpoints.present?
|
68
|
+
@bc_regex_endpoints.each do |regex, bc|
|
69
|
+
|
70
|
+
if endpoint.scan(/@#{regex}@/)
|
71
|
+
@bc_attempt = true
|
72
|
+
bcEndpoint = endpoint.gsub(/@#{regex}@/, bc)
|
73
|
+
break
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
url = "#{@base_url}#{endpoint}"
|
80
|
+
# Don't make the call if we're unit testing a BC endpoint
|
81
|
+
|
82
|
+
if !bc_endpoint || !@bc_testing || (bc_endpoint && @bc_testing && @bc_attempt)
|
83
|
+
|
84
|
+
# Hack for unit testing to ensure this isn't being called due to a bad regex
|
85
|
+
# if @bc_testing && !@bc_attempt
|
86
|
+
|
87
|
+
# bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)
|
88
|
+
# if !@bc_testing.kind_of?(Array)
|
89
|
+
# @bc_testing = [@bc_testing]
|
90
|
+
# end
|
91
|
+
|
92
|
+
# The method is not catching the BC endpoint so fail the test
|
93
|
+
# if @bc_testing.include?($bt[1]['function'])
|
94
|
+
# throw new \Exception($endpoint.' not matched in '.var_export(@bc_regex_endpoints, true))
|
95
|
+
# }
|
96
|
+
# end
|
97
|
+
|
98
|
+
@bc_attempt = false
|
99
|
+
|
100
|
+
if url.index('http').nil?
|
101
|
+
error = {
|
102
|
+
code: 500,
|
103
|
+
message: "URL is incomplete. Please use #{}, set the base URL as the third argument to MauticApi.newApi, or make endpoint a complete URL."
|
104
|
+
}
|
105
|
+
else
|
106
|
+
|
107
|
+
begin
|
108
|
+
settings = {}
|
109
|
+
|
110
|
+
if self.respond_to?(:get_temporary_file_path)
|
111
|
+
settings[:temporary_file_path] = self.get_temporary_file_path
|
112
|
+
end
|
113
|
+
|
114
|
+
response = @auth.make_request(url, parameters, method, settings)
|
115
|
+
|
116
|
+
# TODO: $this->getLogger()->debug('API Response', array('response' => $response))
|
117
|
+
|
118
|
+
if response[:code] >= 300
|
119
|
+
|
120
|
+
# TODO: $this->getLogger()->warning($response)
|
121
|
+
# assume an error
|
122
|
+
|
123
|
+
error = {
|
124
|
+
code: response[:code],
|
125
|
+
message: response[:body],
|
126
|
+
response: response
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
rescue Exception => e
|
131
|
+
# TODO: $this->getLogger()->error('Failed connecting to Mautic API: '.$e->getMessage(), array('trace' => $e->getTraceAsString()))
|
132
|
+
|
133
|
+
error = {
|
134
|
+
code: 500,
|
135
|
+
message: e
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if error.present?
|
141
|
+
return { errors: [error] }
|
142
|
+
end
|
143
|
+
|
144
|
+
# Ensure a code is present in the error array
|
145
|
+
# if response[:errors].present?
|
146
|
+
# info = @auth.get_response_info
|
147
|
+
# response[:errors].each do |key, error|
|
148
|
+
# if response[:errors][key]['code']
|
149
|
+
# response[:errors][key]['code'] = info['http_code']
|
150
|
+
# end
|
151
|
+
# end
|
152
|
+
# end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Check for a 404 code and a BC URL then try again if applicable
|
156
|
+
# if bc_endpoint && (@bc_testing || (response['errors'][0]['code'].to_i === 404))
|
157
|
+
# @bc_attempt = true
|
158
|
+
# return self.make_request(bc_endpoint, parameters, method)
|
159
|
+
# end
|
160
|
+
|
161
|
+
return response
|
162
|
+
end
|
163
|
+
|
164
|
+
# Get a single item
|
165
|
+
#
|
166
|
+
# @param int $id
|
167
|
+
#
|
168
|
+
# @returnarray|mixed
|
169
|
+
|
170
|
+
def get id
|
171
|
+
return make_request("#{self.endpoint}/#{id}")
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get a list of items
|
175
|
+
#
|
176
|
+
# @param string $search
|
177
|
+
# @param int $start
|
178
|
+
# @param int $limit
|
179
|
+
# @param string $orderBy
|
180
|
+
# @param string $orderByDir
|
181
|
+
# @param bool $publishedOnly
|
182
|
+
#
|
183
|
+
# @return array|mixed
|
184
|
+
|
185
|
+
def get_list search = '', start = 0, limit = 0, order_by = '', order_by_dir = 'ASC', published_only = false
|
186
|
+
|
187
|
+
parameters = {}
|
188
|
+
|
189
|
+
args = ['search', 'start', 'limit', 'order_by', 'order_by_dir', 'published_only']
|
190
|
+
|
191
|
+
args.each do |arg|
|
192
|
+
parameters[arg.to_sym] = (eval arg) if (eval arg).present?
|
193
|
+
end
|
194
|
+
|
195
|
+
return make_request(self.endpoint, parameters)
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
# Proxy function to getList with $publishedOnly set to true
|
200
|
+
#
|
201
|
+
# @param string $search
|
202
|
+
# @param int $start
|
203
|
+
# @param int $limit
|
204
|
+
# @param string $orderBy
|
205
|
+
# @param string $orderByDir
|
206
|
+
#
|
207
|
+
# @return array|mixed
|
208
|
+
|
209
|
+
def get_published_list search = '', start = 0, limit = 0, order_by = '', order_by_dir = 'ASC'
|
210
|
+
return get_list(search, start, limit, order_by, order_by_dir, true)
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
# Create a new item (if supported)
|
215
|
+
#
|
216
|
+
# @param array parameters
|
217
|
+
#
|
218
|
+
# @return array|mixed
|
219
|
+
|
220
|
+
def create parameters
|
221
|
+
return make_request("#{self.endpoint}/new", parameters, :post)
|
222
|
+
end
|
223
|
+
|
224
|
+
# Edit an item with option to create if it doesn't exist
|
225
|
+
#
|
226
|
+
# @param int $id
|
227
|
+
# @param array parameters
|
228
|
+
# @param bool $createIfNotExists = false
|
229
|
+
#
|
230
|
+
# @return array|mixed
|
231
|
+
|
232
|
+
def edit(id, parameters, create_if_not_exists = false)
|
233
|
+
method = create_if_not_exists ? :put : :patch
|
234
|
+
return make_request("#{self.endpoint}/#{id}/edit", parameters, method)
|
235
|
+
end
|
236
|
+
|
237
|
+
# Delete an item
|
238
|
+
#
|
239
|
+
# @param $id
|
240
|
+
#
|
241
|
+
# @return array|mixed
|
242
|
+
|
243
|
+
def delete id
|
244
|
+
return make_request("#{self.endpoint}/#{id}/delete", {}, :delete)
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module MauticApi
|
2
|
+
|
3
|
+
class Contacts < Api
|
4
|
+
|
5
|
+
ENDPOINT = "contacts"
|
6
|
+
LIST_NAME = "contacts"
|
7
|
+
ITEM_NAME = "contact"
|
8
|
+
|
9
|
+
# Get a list of users available as contact owners
|
10
|
+
#
|
11
|
+
# @return array|mixed
|
12
|
+
|
13
|
+
def get_owners
|
14
|
+
return make_request("#{self.endpoint}/list/owners")
|
15
|
+
end
|
16
|
+
|
17
|
+
# Get a list of custom fields
|
18
|
+
#
|
19
|
+
# @return array|mixed
|
20
|
+
|
21
|
+
def get_field_list
|
22
|
+
return make_request("#{self.endpoint}/list/fields")
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get a list of contact segments
|
26
|
+
#
|
27
|
+
# @return array|mixed
|
28
|
+
|
29
|
+
def get_segments
|
30
|
+
return make_request("#{self.endpoint}/list/segments")
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get a list of a contact's notes
|
34
|
+
#
|
35
|
+
# @param int $id Contact ID
|
36
|
+
# @param string $search
|
37
|
+
# @param int $start
|
38
|
+
# @param int $limit
|
39
|
+
# @param string $orderBy
|
40
|
+
# @param string $orderByDir
|
41
|
+
#
|
42
|
+
# @return array|mixed
|
43
|
+
|
44
|
+
def get_contact_notes id, search = '', start = 0, limit = 0, orderBy = '', order_by_dir = 'ASC'
|
45
|
+
|
46
|
+
parameters = {}
|
47
|
+
|
48
|
+
args = ['search', 'start', 'limit', 'orderBy', 'order_by_dir']
|
49
|
+
|
50
|
+
args.each do |arg|
|
51
|
+
parameters[arg.to_sym] = (eval arg) if (eval arg).present?
|
52
|
+
end
|
53
|
+
|
54
|
+
return make_request("#{self.endpoint}/#{id}/notes", parameters)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get a segment of smart segments the lead is in
|
58
|
+
#
|
59
|
+
# @param $id
|
60
|
+
# @return array|mixed
|
61
|
+
|
62
|
+
def get_contact_segments(id)
|
63
|
+
return make_request("#{self.endpoint}/#{id}/segments")
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add do not contact to lead
|
67
|
+
#
|
68
|
+
# @param int $id Contact ID
|
69
|
+
# @param string $comments
|
70
|
+
#
|
71
|
+
# @return array|mixed
|
72
|
+
|
73
|
+
def add_do_not_contact id, reason = 1, comments = ''
|
74
|
+
parameters = {}
|
75
|
+
|
76
|
+
args = ['reason', 'comments']
|
77
|
+
|
78
|
+
args.each do |arg|
|
79
|
+
parameters[arg.to_sym] = (eval arg) if (eval arg).present?
|
80
|
+
end
|
81
|
+
|
82
|
+
return make_request("#{self.endpoint}/#{id}/dnc/add/email", parameters, :post)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Get a segment of campaigns the lead is in
|
86
|
+
#
|
87
|
+
# @param $id
|
88
|
+
# @return array|mixed
|
89
|
+
|
90
|
+
def get_contact_campaigns(id)
|
91
|
+
return make_request("#{self.endpoint}/#{id}/campaigns")
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|