mautic 2.3.11 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54130da5f454542319794381488da40d7ddf9b44ae18e9071cee61a4ae6cee65
4
- data.tar.gz: f81597d7b092e25ed9cc7f18905e681ae92f1afc61e1cd143f2fecb1f704b026
3
+ metadata.gz: 7d46a059bc0ca2814a69988d070546a021dda7b0e75985ead3230e503bfb0262
4
+ data.tar.gz: 97f5dbcc3c37d42d148903cc8f604d26016423eb128cb40ded8cb9bfc590c12a
5
5
  SHA512:
6
- metadata.gz: fdf11781f6797c3174c5e49612d0369660b7fde520cdfecc237396879b110bbe3ac56fd23c6ffd20dc9cf1878ea76faec45e0132930c3992afffd92c3b66cd53
7
- data.tar.gz: 5d82c6eed700f377967347e8bc0bb759557d3f006a7a3ec4fb709a78026086eb8dfaedc6be3c0d3fef667a17a9b2cf472f8819ddfcfae757f2442d6b077c11b6
6
+ metadata.gz: 53c9b9a777ec9cd835d36af42d4eb120831527afa1a147fd61dfa106e078bef5cef072398ef8e1f80bafc3253e916e9fab4438f273eb8c61149768bb7ee6b5bc
7
+ data.tar.gz: 3b46074c6a05f4977666bee64655e5ef621fc023d8b58e8f13144d8d6d8d1358f90c942555ec9aefdc80c9b5b2949ee077749c9e49589fa00a2c865b7c75aac0
data/README.md CHANGED
@@ -94,11 +94,11 @@ end
94
94
  ```
95
95
  Get specify contact:
96
96
  ```ruby
97
- contact = m.contact.find(1) # => #<Mautic::Contact id=1 ...>
97
+ contact = m.contact.find(1) # => #<Mautic::Contact id=1 ...>
98
98
  ```
99
99
  Collections of contacts:
100
100
  ```ruby
101
- m.contacts.where("gmail").each do |contact|
101
+ m.contacts.where(search: "gmail").each do |contact|
102
102
  #<Mautic::Contact id=12 ...>
103
103
  #<Mautic::Contact id=21 ...>
104
104
  #<Mautic::Contact id=99 ...>
@@ -115,7 +115,7 @@ end
115
115
  contact.save # => false
116
116
  contact.errors # => [{"code"=>400, "message"=>"email: This field is required.", "details"=>{"email"=>["This field is required."]}}]
117
117
  ```
118
- Do not contact
118
+ #### Do not contact
119
119
  ```ruby
120
120
  contact.do_not_contact? # => false
121
121
  contact.do_not_contact! message: "Some reason"
@@ -127,6 +127,18 @@ end
127
127
  contact.remove_do_not_contact!
128
128
  contact.do_not_contact? # => false
129
129
  ```
130
+ #### Campaigns
131
+ list of contacts campaigns (where contact is a member) and remove it from one
132
+ ```ruby
133
+ contact.campaigns #=> [Mautic::Campaign, ...]
134
+ campaign = contact.campaigns.find { |campaign| campaign.name == "Newsletter" }
135
+ campaign.remove_contact! contact.id
136
+ ```
137
+ or add contact back
138
+ ```ruby
139
+ campaign = connection.campaigns.where(search: "Newsletter").first
140
+ campaign.add_contact! contact.id
141
+ ```
130
142
  Of course you can use more than contact: `assets`, `emails`, `companies`, `forms`, `points` ...
131
143
  ### Gem provides simple Mautic form submit
132
144
  There are two options of usage:
@@ -0,0 +1,22 @@
1
+ module Mautic
2
+ class Campaign < Model
3
+
4
+ # @see https://developer.mautic.org/#add-contact-to-a-campaign
5
+ # @param [Integer] id of Mautic::Contact
6
+ def add_contact!(id)
7
+ json = @connection.request(:post, "api/campaigns/#{self.id}/contact/#{id}/add")
8
+ json["success"]
9
+ rescue RequestError => _e
10
+ false
11
+ end
12
+
13
+ # @see https://developer.mautic.org/#remove-contact-from-a-campaign
14
+ # @param [Integer] id of Mautic::Contact
15
+ def remove_contact!(id)
16
+ json = @connection.request(:post, "api/campaigns/#{self.id}/contact/#{id}/remove")
17
+ json["success"]
18
+ rescue RequestError => _e
19
+ false
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ module Mautic
2
+ class CompanyField < Model
3
+ def self.endpoint
4
+ "fields/company"
5
+ end
6
+
7
+ def self.in(connection)
8
+ Proxy.new(connection, endpoint, klass: name, data_name: "field")
9
+ end
10
+ end
11
+ end
@@ -1,6 +1,9 @@
1
1
  module Mautic
2
2
  class Contact < Model
3
3
 
4
+ around_create :ensure_stage, if: ->(contact) { contact.changes.has_key?(:stage_id) }
5
+ around_update :ensure_stage, if: ->(contact) { contact.changes.has_key?(:stage_id) }
6
+
4
7
  alias_attribute :first_name, :firstname
5
8
  alias_attribute :last_name, :lastname
6
9
 
@@ -41,11 +44,13 @@ module Mautic
41
44
 
42
45
  if source
43
46
  self.owner = source['owner'] || {}
47
+ self.stage = source['stage'] || {}
44
48
  tags = (source['tags'] || []).map { |t| Mautic::Tag.new(self, t) }.sort_by(&:name)
45
49
  self.attributes = {
46
50
  tags: Tag::Collection.new(self, *tags),
47
51
  doNotContact: source['doNotContact'] || [],
48
52
  owner: owner['id'],
53
+ stage_id: stage&.id,
49
54
  }
50
55
  end
51
56
  end
@@ -117,11 +122,64 @@ module Mautic
117
122
 
118
123
  # !endgroup
119
124
 
125
+ # @!group Campaigns
126
+
127
+ # @return [Array<Mautic::Campaign>]
128
+ def campaigns
129
+ return @campaigns if @campaigns
130
+
131
+ json = @connection.request(:get, "api/contacts/#{id}/campaigns")
132
+
133
+ @campaigns = json["campaigns"].collect do |_campaign_id, campaign_attributes|
134
+ Mautic::Campaign.new @connection, campaign_attributes
135
+ end
136
+ rescue RequestError => _e
137
+ []
138
+ end
139
+
140
+ # !endgroup
141
+
142
+ # @!group Stage
143
+
144
+ # @return [Mautic::Stage, nil]
145
+ def stage
146
+ @stage
147
+ end
148
+
149
+ # @param [Mautic:::Stage,Hash, nil] hash
150
+ def stage=(object_or_hash)
151
+ @stage = case object_or_hash
152
+ when Mautic::Stage
153
+ object_or_hash
154
+ when Hash
155
+ Mautic::Stage.new(connection, object_or_hash)
156
+ end
157
+ @table[:stage_id] = @stage&.id
158
+ @stage
159
+ end
160
+
161
+ # !endgroup
162
+
120
163
  private
121
164
 
122
165
  def clear_change
123
166
  super
124
167
  remove_instance_variable :@do_not_contact
125
168
  end
169
+
170
+ # Add or Remove contact in stage after contact save
171
+ def ensure_stage
172
+ stage_id_change = changes[:stage_id]
173
+ yield
174
+ if stage_id_change
175
+ self.stage = Mautic::Stage.in(connection).find(stage_id_change)
176
+ stage.add_contact!(id)
177
+ @table[:stage_id] = stage.id
178
+ else
179
+ stage.remove_contact!(id)
180
+ @table.delete(:stage_id)
181
+ end
182
+ clear_changes
183
+ end
126
184
  end
127
- end
185
+ end
@@ -0,0 +1,11 @@
1
+ module Mautic
2
+ class ContactField < Model
3
+ def self.endpoint
4
+ "fields/contact"
5
+ end
6
+
7
+ def self.in(connection)
8
+ Proxy.new(connection, endpoint, klass: name, data_name: "field")
9
+ end
10
+ end
11
+ end
@@ -5,5 +5,34 @@ module Mautic
5
5
  self.attributes = { name: source['name'], fields: source['fields'] } if source.is_a? Hash
6
6
  end
7
7
 
8
+ # @param [Integer] submission_id
9
+ # @return Mautic::Submissions::Form
10
+ # @see https://developer.mautic.org/#get-form-submission
11
+ def submission(submission_id)
12
+ json = @connection.request(:get, "api/forms/#{id}/submissions/#{submission_id}")
13
+ Mautic::Submissions::Form.new @connection, json["submission"]
14
+ rescue Mautic::RecordNotFound => _e
15
+ nil
16
+ end
17
+
18
+ # @see https://developer.mautic.org/#list-form-submissions
19
+ # @param [Hash] options
20
+ # @option options [String] :search String or search command to filter entities by.
21
+ # @option options [String] :start Starting row for the entities returned. Defaults to 0.
22
+ # @option options [String] :limit Limit number of entities to return. Defaults to the system configuration for pagination (30).
23
+ # @option options [String] :orderBy Column to sort by. Can use any column listed in the response, also can use column of joined table with prefix. Sort by submitted date is s.date_submitted
24
+ # @option options [String] :orderByDir Sort direction: asc or desc.
25
+ # @option options [String] :publishedOnly Only return currently published entities.
26
+ # @option options [String] :minimal Return only array of entities without additional lists in it.
27
+ # @return Array[Mautic::Submissions::Form]
28
+ def submissions(**options)
29
+ json = @connection.request(:get, "api/forms/#{id}/submissions", params: options)
30
+ @submissions = json["submissions"].collect do |attributes|
31
+ Mautic::Submissions::Form.new @connection, attributes
32
+ end
33
+ rescue RequestError => _e
34
+ []
35
+ end
36
+
8
37
  end
9
- end
38
+ end
@@ -0,0 +1,22 @@
1
+ module Mautic
2
+ class Stage < Model
3
+
4
+ # @see https://developer.mautic.org/#add-contact-to-a-stage
5
+ # @param [Integer] id of Mautic::Contact
6
+ def add_contact!(id)
7
+ json = @connection.request(:post, "api/stages/#{self.id}/contact/#{id}/add")
8
+ json["success"]
9
+ rescue RequestError => _e
10
+ false
11
+ end
12
+
13
+ # @see https://developer.mautic.org/#remove-contact-from-a-stage
14
+ # @param [Integer] id of Mautic::Contact
15
+ def remove_contact!(id)
16
+ json = @connection.request(:post, "api/stages/#{self.id}/contact/#{id}/remove")
17
+ json["success"]
18
+ rescue RequestError => _e
19
+ false
20
+ end
21
+ end
22
+ end
@@ -12,7 +12,7 @@ module Mautic
12
12
 
13
13
  def form_submissions
14
14
  @forms ||= Array.wrap(@params.require("mautic.form_on_submit")).collect do |data|
15
- p = data.permit(submission: [:id, :referer, form: {}, lead: {}, results: {}]).to_h
15
+ p = data.permit(submission: [:id, :referer, form: {}, lead: {}, results: {}, ipAddress: {}]).to_h
16
16
  ::Mautic::Submissions::Form.new(@connection, p["submission"]) if p["submission"]
17
17
  end.compact
18
18
  end
@@ -2,8 +2,6 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Mautic</title>
5
- <%= stylesheet_link_tag "mautic/application", media: "all" %>
6
- <%= javascript_include_tag "mautic/application" %>
7
5
  <%= csrf_meta_tags %>
8
6
  </head>
9
7
  <body>
data/lib/mautic/model.rb CHANGED
@@ -2,6 +2,7 @@ module Mautic
2
2
  # Virtual model for Mautic endpoint
3
3
  # @see https://developer.mautic.org/#endpoints
4
4
  class Model < OpenStruct
5
+ extend ActiveModel::Callbacks
5
6
 
6
7
  class MauticHash < Hash
7
8
 
@@ -37,6 +38,8 @@ module Mautic
37
38
 
38
39
  end
39
40
 
41
+ define_model_callbacks :create, :update, :save
42
+
40
43
  attr_reader :connection
41
44
  attr_accessor :errors
42
45
  attr_writer :changed
@@ -55,15 +58,19 @@ module Mautic
55
58
  end
56
59
 
57
60
  def save(force = false)
58
- id.present? ? update(force) : create
61
+ run_callbacks :save do
62
+ id.present? ? update(force) : create
63
+ end
59
64
  end
60
65
 
61
66
  def update(force = false)
62
67
  return false unless changed?
63
68
 
64
69
  begin
65
- json = @connection.request((force && :put || :patch), "api/#{endpoint}/#{id}/edit", body: to_mautic)
66
- assign_attributes json[endpoint.singularize]
70
+ run_callbacks :create do
71
+ json = @connection.request((force && :put || :patch), "api/#{endpoint}/#{id}/edit", body: to_mautic)
72
+ assign_attributes json[endpoint.singularize]
73
+ end
67
74
  clear_changes
68
75
  rescue ValidationError => e
69
76
  self.errors = e.errors
@@ -82,8 +89,10 @@ module Mautic
82
89
 
83
90
  def create
84
91
  begin
85
- json = @connection.request(:post, "api/#{endpoint}/#{id && "#{id}/"}new", body: to_mautic)
86
- assign_attributes json[endpoint.singularize]
92
+ run_callbacks :create do
93
+ json = @connection.request(:post, "api/#{endpoint}/#{id && "#{id}/"}new", body: to_mautic)
94
+ assign_attributes json[endpoint.singularize]
95
+ end
87
96
  clear_changes
88
97
  rescue ValidationError => e
89
98
  self.errors = e.errors
@@ -124,14 +133,14 @@ module Mautic
124
133
  end
125
134
 
126
135
  def to_mautic(data = @table)
127
- data.each_with_object({}) do |(key, val), mem|
128
- mem[key] = if val.respond_to?(:to_mautic)
129
- val.to_mautic
130
- elsif val.is_a?(Array)
131
- val.join("|")
132
- else
133
- val
134
- end
136
+ data.transform_values do |val|
137
+ if val.respond_to?(:to_mautic)
138
+ val.to_mautic
139
+ elsif val.is_a?(Array)
140
+ val.join("|")
141
+ else
142
+ val
143
+ end
135
144
  end
136
145
  end
137
146
 
data/lib/mautic/proxy.rb CHANGED
@@ -14,7 +14,7 @@ module Mautic
14
14
  end
15
15
 
16
16
  def data_name
17
- @endpoint.split("/").last
17
+ @options[:data_name] || @endpoint.split("/").last
18
18
  end
19
19
 
20
20
  def build_instance(data)
@@ -79,4 +79,4 @@ module Mautic
79
79
  end
80
80
 
81
81
  end
82
- end
82
+ end
@@ -1,5 +1,6 @@
1
1
  module Mautic
2
2
  module Submissions
3
+ # @see https://developer.mautic.org/#get-form-submissions
3
4
  class Form
4
5
  attr_reader :id
5
6
 
@@ -31,11 +32,26 @@ module Mautic
31
32
  @contact ||= @connection.contacts.new(@raw["lead"])
32
33
  end
33
34
 
35
+ # @return [Hash]
36
+ def ip_details
37
+ ip_address["ipDetails"] || {}
38
+ end
39
+
40
+ # @return [Hash]
41
+ def ip_address
42
+ @raw["ipAddress"] || {}
43
+ end
44
+
34
45
  # @return [String]
35
46
  def referer
36
47
  @raw["referer"].to_s
37
48
  end
38
49
 
50
+ # @return [Hash]
51
+ def results
52
+ @raw["results"]
53
+ end
54
+
39
55
  end
40
56
  end
41
57
  end
@@ -1,3 +1,3 @@
1
1
  module Mautic
2
- VERSION = '2.3.11'
2
+ VERSION = '2.6.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mautic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.11
4
+ version: 2.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukáš Pokorný
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-02 00:00:00.000000000 Z
11
+ date: 2021-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -160,12 +160,6 @@ files:
160
160
  - MIT-LICENSE
161
161
  - README.md
162
162
  - Rakefile
163
- - app/assets/config/mautic_manifest.js
164
- - app/assets/javascripts/mautic/application.js
165
- - app/assets/javascripts/mautic/mautic_connections.js
166
- - app/assets/stylesheets/mautic/application.css
167
- - app/assets/stylesheets/mautic/mautic_connections.css
168
- - app/assets/stylesheets/scaffold.css
169
163
  - app/controllers/concerns/mautic/connections_controller_concern.rb
170
164
  - app/controllers/concerns/mautic/receive_web_hooks.rb
171
165
  - app/controllers/mautic/application_controller.rb
@@ -174,11 +168,15 @@ files:
174
168
  - app/jobs/mautic/application_job.rb
175
169
  - app/mailers/mautic/application_mailer.rb
176
170
  - app/models/mautic/application_record.rb
171
+ - app/models/mautic/campaign.rb
172
+ - app/models/mautic/company_field.rb
177
173
  - app/models/mautic/connection.rb
178
174
  - app/models/mautic/connections/oauth2.rb
179
175
  - app/models/mautic/contact.rb
176
+ - app/models/mautic/contact_field.rb
180
177
  - app/models/mautic/event.rb
181
178
  - app/models/mautic/form.rb
179
+ - app/models/mautic/stage.rb
182
180
  - app/models/mautic/tag.rb
183
181
  - app/models/mautic/web_hook.rb
184
182
  - app/views/layouts/mautic/application.html.erb
@@ -207,7 +205,7 @@ licenses:
207
205
  - MIT
208
206
  metadata:
209
207
  allowed_push_host: https://rubygems.org
210
- post_install_message:
208
+ post_install_message:
211
209
  rdoc_options: []
212
210
  require_paths:
213
211
  - lib
@@ -222,8 +220,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
220
  - !ruby/object:Gem::Version
223
221
  version: '0'
224
222
  requirements: []
225
- rubygems_version: 3.0.8
226
- signing_key:
223
+ rubygems_version: 3.1.4
224
+ signing_key:
227
225
  specification_version: 4
228
226
  summary: Ruby on Rails Mautic integration
229
227
  test_files:
@@ -1,2 +0,0 @@
1
- //= link_directory ../javascripts/mautic .js
2
- //= link_directory ../stylesheets/mautic .css
@@ -1,14 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
- //
10
- // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
- // require rails-ujs
14
- //= require_tree .
@@ -1,2 +0,0 @@
1
- // Place all the behaviors and hooks related to the matching controller here.
2
- // All this logic will automatically be available in application.js.
@@ -1,15 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
- * files in this directory. Styles in this file should be added after the last require_* statement.
11
- * It is generally better to create a new file per style scope.
12
- *
13
- *= require_tree .
14
- *= require_self
15
- */
@@ -1,4 +0,0 @@
1
- /*
2
- Place all the styles related to the matching controller here.
3
- They will automatically be included in application.css.
4
- */
@@ -1,80 +0,0 @@
1
- body {
2
- background-color: #fff;
3
- color: #333;
4
- margin: 33px;
5
- }
6
-
7
- body, p, ol, ul, td {
8
- font-family: verdana, arial, helvetica, sans-serif;
9
- font-size: 13px;
10
- line-height: 18px;
11
- }
12
-
13
- pre {
14
- background-color: #eee;
15
- padding: 10px;
16
- font-size: 11px;
17
- }
18
-
19
- a {
20
- color: #000;
21
- }
22
-
23
- a:visited {
24
- color: #666;
25
- }
26
-
27
- a:hover {
28
- color: #fff;
29
- background-color: #000;
30
- }
31
-
32
- th {
33
- padding-bottom: 5px;
34
- }
35
-
36
- td {
37
- padding: 0 5px 7px;
38
- }
39
-
40
- div.field,
41
- div.actions {
42
- margin-bottom: 10px;
43
- }
44
-
45
- #notice {
46
- color: green;
47
- }
48
-
49
- .field_with_errors {
50
- padding: 2px;
51
- background-color: red;
52
- display: table;
53
- }
54
-
55
- #error_explanation {
56
- width: 450px;
57
- border: 2px solid red;
58
- padding: 7px 7px 0;
59
- margin-bottom: 20px;
60
- background-color: #f0f0f0;
61
- }
62
-
63
- #error_explanation h2 {
64
- text-align: left;
65
- font-weight: bold;
66
- padding: 5px 5px 5px 15px;
67
- font-size: 12px;
68
- margin: -7px -7px 0;
69
- background-color: #c00;
70
- color: #fff;
71
- }
72
-
73
- #error_explanation ul li {
74
- font-size: 12px;
75
- list-style: square;
76
- }
77
-
78
- label {
79
- display: block;
80
- }