mautic 2.3.4 → 2.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afb8b76cddd73b61cfefac55cd183fd3b84603dfc1681fe00d4c524838cf5bcb
4
- data.tar.gz: 8a632817a47a0e2819a4cd74fef4798ebddf80cd9c68fdebad462bb0ca3a570d
3
+ metadata.gz: 59800fcfc64665ad1873fc20ef004bffe54edd38c2bb4da6263e702c0caba571
4
+ data.tar.gz: e32ddec1e3707e5cf8fab1232de729a6c8df75d30f2520dc1620eec57bf857c7
5
5
  SHA512:
6
- metadata.gz: cb0312a5a188a6619421a33b4768dd5e2aa90ea6ef7764e67a7ad169e9b1ec24bf342c9eb1ce4c22958a24562c22a2c80285daa8f48c14c9df1fc2bca2603dcf
7
- data.tar.gz: 4b4b003e569e396529ece6d0971d749131996d0e0692cf33f64af21efa164820dab732b155526d3074d4e136c9ac91648180d540407523f8f4a9e9815de5ca5f
6
+ metadata.gz: 0b8433f04ee7a96e9474a0f8b39a883637d68b5b2135203f150fc697d5a495e3a7447311c1d27171fe7545c74b979ee4b7727397ba279fde1ce9472b2ed29809
7
+ data.tar.gz: 495c134933d712de9598cc618bf308f5b297e59bf86040d3e1c25b7ad636ee910932b08adc46c3a1a7144459b3f17e49dbb8cb57b167d28084715f8e19ed8197
data/README.md CHANGED
@@ -32,13 +32,40 @@ Mautic.configure do |config|
32
32
  # OR it can be Proc
33
33
  # *optional* This is your default mautic URL - used in form helper
34
34
  config.mautic_url = "https://mautic.my.app"
35
+ # Set authorize condition for manage Mautic::Connections
36
+ config.authorize_mautic_connections = ->(controller) { false }
35
37
  end
36
38
  ```
39
+ ### Manage mautic connections
40
+ You can use builtin Mautic:ConnectionsController:
37
41
 
38
42
  add to `config/routes.rb`
39
43
  ```ruby
40
44
  mount Mautic::Engine => "/mautic"
41
45
  ```
46
+ note: Make sure that you have some user authorization. There is builtin mechanism, in `Mautic.config.authorize_mautic_connections` = which return `false` to prevent all access by default (see: app/controllers/mautic/connections_controller.rb:3). For change this, you need add to `config/initializers/mautic.rb`:
47
+ ```ruby
48
+ Mautic.config.authorize_mautic_connections = ->(controller) { current_user.admin? }
49
+ ```
50
+
51
+ OR use your own controller, by including concern
52
+ ```ruby
53
+ class MyOwnController < ApplicationController
54
+ before_action :authorize_user
55
+
56
+ include Mautic::ConnectionsControllerConcern
57
+ end
58
+ ```
59
+ Concern require additional routes (authorize and oauth2) in `routes.rb`
60
+ ```ruby
61
+ resources :my_resources do
62
+ member do
63
+ get :authorize
64
+ get :oauth2
65
+ end
66
+ end
67
+ ```
68
+
42
69
  ### Create mautic connection
43
70
 
44
71
  1. In your mautic, create new
@@ -88,6 +115,18 @@ mount Mautic::Engine => "/mautic"
88
115
  contact.save # => false
89
116
  contact.errors # => [{"code"=>400, "message"=>"email: This field is required.", "details"=>{"email"=>["This field is required."]}}]
90
117
  ```
118
+ Do not contact
119
+ ```ruby
120
+ contact.do_not_contact? # => false
121
+ contact.do_not_contact! message: "Some reason"
122
+ contact.do_not_contact? # => true
123
+ ```
124
+ Remove do not contact
125
+ ```ruby
126
+ contact.do_not_contact? # => true
127
+ contact.remove_do_not_contact!
128
+ contact.do_not_contact? # => false
129
+ ```
91
130
  Of course you can use more than contact: `assets`, `emails`, `companies`, `forms`, `points` ...
92
131
  ### Gem provides simple Mautic form submit
93
132
  There are two options of usage:
@@ -85,12 +85,12 @@ module Mautic
85
85
  # ==--==--==--==--
86
86
 
87
87
  def authorize
88
- redirect_to @mautic_connection.authorize
88
+ redirect_to @mautic_connection.authorize(self)
89
89
  end
90
90
 
91
91
  def oauth2
92
92
  begin
93
- response = @mautic_connection.get_code(params.require(:code))
93
+ response = @mautic_connection.get_code(params.require(:code), self)
94
94
  @mautic_connection.update(token: response.token, refresh_token: response.refresh_token)
95
95
  return render plain: t('mautic.text_mautic_authorize_successfully')
96
96
  rescue OAuth2::Error => e
@@ -1,5 +1,15 @@
1
1
  module Mautic
2
2
  class ConnectionsController < ApplicationController
3
+ before_action :authorize_me
3
4
  include ::Mautic::ConnectionsControllerConcern
5
+
6
+ private
7
+
8
+ def authorize_me
9
+ unless Mautic.config.authorize_mautic_connections.call(self)
10
+ logger.warn "Mautic::ConnectionsController unauthorized, you can change this by Mautic.config.authorize_mautic_connections. See: lib/mautic.rb:77"
11
+ render plain: "Unauthorized", status: 403
12
+ end
13
+ end
4
14
  end
5
15
  end
@@ -17,11 +17,11 @@ module Mautic
17
17
  raise NotImplementedError
18
18
  end
19
19
 
20
- def authorize
20
+ def authorize(context)
21
21
  raise NotImplementedError
22
22
  end
23
23
 
24
- def get_code(code)
24
+ def get_code(code, context)
25
25
  raise NotImplementedError
26
26
  end
27
27
 
@@ -55,7 +55,7 @@ module Mautic
55
55
 
56
56
  private
57
57
 
58
- def callback_url
58
+ def callback_url(context)
59
59
  if (conf = Mautic.config.base_url).is_a?(Proc)
60
60
  conf = conf.call(self)
61
61
  end
@@ -11,12 +11,12 @@ module Mautic
11
11
  })
12
12
  end
13
13
 
14
- def authorize
15
- client.auth_code.authorize_url(redirect_uri: callback_url)
14
+ def authorize(context)
15
+ client.auth_code.authorize_url(redirect_uri: callback_url(context))
16
16
  end
17
17
 
18
- def get_code(code)
19
- client.auth_code.get_token(code, redirect_uri: callback_url)
18
+ def get_code(code, context)
19
+ client.auth_code.get_token(code, redirect_uri: callback_url(context))
20
20
  end
21
21
 
22
22
  def connection
@@ -37,9 +37,10 @@ module Mautic
37
37
 
38
38
  private
39
39
 
40
- def callback_url
40
+ def callback_url(context)
41
41
  uri = super
42
- uri.path = Mautic::Engine.routes.url_helpers.oauth2_connection_path(self)
42
+ # uri.path = Mautic::Engine.routes.url_helpers.oauth2_connection_path(self)
43
+ uri.path = context.url_for(action: "oauth2", id: self , only_path: true)
43
44
  uri.to_s
44
45
  end
45
46
 
@@ -3,6 +3,7 @@ module Mautic
3
3
 
4
4
  alias_attribute :first_name, :firstname
5
5
  alias_attribute :last_name, :lastname
6
+
6
7
  def self.in(connection)
7
8
  Proxy.new(connection, endpoint, default_params: { search: '!is:anonymous' })
8
9
  end
@@ -11,16 +12,116 @@ module Mautic
11
12
  "#{firstname} #{lastname}"
12
13
  end
13
14
 
15
+ # @param [Hash] hash
16
+ # option hash [Integer] :id
17
+ # option hash [String] :firstName
18
+ # option hash [String] :lastName
19
+ def owner=(hash)
20
+ raise ArgumentError, "must be a hash !" unless hash.is_a?(Hash)
21
+
22
+ @table[:owner] = hash["id"]
23
+ @owner = hash
24
+ end
25
+
26
+ # @return [Hash]
27
+ # @example {id: 12, firstName: "Joe", lastName: "Doe"}
28
+ def owner
29
+ @owner || {}
30
+ end
31
+
32
+ # Assign mautic User ID as owner - for example for update author of contact
33
+ # @see https://developer.mautic.org/#edit-contact set owner
34
+ # @param [Integer] int
35
+ def owner_id=(int)
36
+ @table[:owner] = int
37
+ end
38
+
14
39
  def assign_attributes(source = nil)
15
40
  super
16
- self.attributes = {
17
- tags: (source['tags'] || []).collect { |t| Mautic::Tag.new(@connection, t) }.sort_by(&:name)
18
- } if source
41
+
42
+ if source
43
+ self.owner = source['owner'] || {}
44
+ self.attributes = {
45
+ tags: (source['tags'] || []).collect { |t| Mautic::Tag.new(@connection, t) }.sort_by(&:name),
46
+ doNotContact: source['doNotContact'] || [],
47
+ owner: owner['id'],
48
+ }
49
+ end
50
+ end
51
+
52
+ def to_mautic(data = @table)
53
+ data.delete(:doNotContact)
54
+ data.delete(:tags)
55
+ super(data)
19
56
  end
20
57
 
21
58
  def events
22
59
  @proxy_events ||= Proxy.new(connection, "contacts/#{id}/events", klass: "Mautic::Event")
23
60
  end
24
61
 
62
+ # @!group Do Not Contact
63
+ # @see https://developer.mautic.org/#add-do-not-contact
64
+
65
+ def do_not_contact?
66
+ doNotContact.present?
67
+ end
68
+
69
+ alias dnc? do_not_contact?
70
+
71
+ # @return [Array[Hash]]
72
+ def do_not_contact
73
+ return unless do_not_contact?
74
+
75
+ # Based on mautic docs => Contacts constants: Contacts::UNSUBSCRIBED (1), Contacts::BOUNCED (2), Contacts::MANUAL (3)
76
+ reason_list = { 1 => :unsubscribed, 2 => :bounced, 3 => :manual }
77
+ @do_not_contact ||= doNotContact.collect do |hsh|
78
+ { reason_list[hsh["reason"]] => hsh["comments"] }
79
+ end
80
+ end
81
+
82
+ def bounced?
83
+ do_not_contact? && !!do_not_contact.detect { |dnc| dnc.key?(:bounced) }
84
+ end
85
+
86
+ def unsubscribed?
87
+ do_not_contact? && !!do_not_contact.detect { |dnc| dnc.key?(:unsubscribed) }
88
+ end
89
+
90
+ def do_not_contact!(comments: '')
91
+ begin
92
+ json = @connection.request(:post, "api/contacts/#{id}/dnc/email/add", body: { comments: comments })
93
+ self.attributes = { doNotContact: json[endpoint.singularize]["doNotContact"] }
94
+ clear_changes
95
+ rescue ValidationError => e
96
+ self.errors = e.errors
97
+ end
98
+
99
+ self.errors.blank?
100
+ end
101
+
102
+ alias add_dnc do_not_contact!
103
+
104
+ def remove_do_not_contact!
105
+ begin
106
+ json = @connection.request(:post, "api/contacts/#{id}/dnc/email/remove", body: {})
107
+ self.attributes = { doNotContact: json[endpoint.singularize]["doNotContact"] }
108
+ clear_changes
109
+ rescue ValidationError => e
110
+ self.errors = e.errors
111
+ end
112
+
113
+ self.errors.blank?
114
+ end
115
+
116
+ alias remove_dnc remove_do_not_contact!
117
+
118
+ # !endgroup
119
+
120
+ private
121
+
122
+ def clear_change
123
+ super
124
+ remove_instance_variable :@do_not_contact
125
+ end
25
126
  end
26
127
  end
@@ -6,6 +6,10 @@ module Mautic
6
6
  tag
7
7
  end
8
8
 
9
+ def to_s
10
+ name
11
+ end
12
+
9
13
  def name=(name)
10
14
  self.tag = name
11
15
  end
@@ -24,7 +24,7 @@
24
24
  <% if form.object.persisted? %>
25
25
  <div class="field">
26
26
  <label>Now generate pair of tokens with this callback url:</label>
27
- <pre><%= @mautic_connection.send :callback_url %></pre>
27
+ <pre><%= @mautic_connection.send :callback_url, controller %></pre>
28
28
  </div>
29
29
 
30
30
  <div class="field">
@@ -3,8 +3,6 @@ Mautic::Engine.routes.draw do
3
3
  member do
4
4
  get :authorize
5
5
  get :oauth2
6
-
7
6
  end
8
- # post "webhook/:mautic_connection_id", action: "webhook", on: :collection
9
7
  end
10
8
  end
@@ -67,10 +67,14 @@ module Mautic
67
67
  end
68
68
 
69
69
  configure do |config|
70
- # This is URL your application - its for oauth callbacks
70
+ # This is URL of your application - its for oauth callbacks
71
71
  config.base_url = "http://localhost:3000"
72
+
72
73
  # *optional* This is your default mautic URL - used in form helper
73
74
  config.mautic_url = "https://mautic.my.app"
75
+
76
+ # Set authorize condition for manage Mautic::Connections
77
+ config.authorize_mautic_connections = ->(controller) { false }
74
78
  end
75
79
  # Your code goes here...
76
80
 
@@ -38,6 +38,7 @@ module Mautic
38
38
  end
39
39
 
40
40
  attr_reader :connection
41
+ attr_accessor :errors
41
42
 
42
43
  # @param [Mautic::Connection] connection
43
44
  def initialize(connection, hash = nil)
@@ -58,9 +59,10 @@ module Mautic
58
59
 
59
60
  def update(force = false)
60
61
  return false if changes.blank?
62
+
61
63
  begin
62
- json = @connection.request((force && :put || :patch), "api/#{endpoint}/#{id}/edit", { body: to_mautic })
63
- self.attributes = json[endpoint.singularize]
64
+ json = @connection.request((force && :put || :patch), "api/#{endpoint}/#{id}/edit", body: to_mautic)
65
+ assign_attributes json[endpoint.singularize]
64
66
  clear_changes
65
67
  rescue ValidationError => e
66
68
  self.errors = e.errors
@@ -69,10 +71,18 @@ module Mautic
69
71
  self.errors.blank?
70
72
  end
71
73
 
74
+ def update_columns(attributes = {})
75
+ json = @connection.request(:patch, "api/#{endpoint}/#{id}/edit", body: to_mautic(attributes))
76
+ assign_attributes json[endpoint.singularize]
77
+ clear_changes
78
+ rescue ValidationError => e
79
+ self.errors = e.errors
80
+ end
81
+
72
82
  def create
73
83
  begin
74
- json = @connection.request(:post, "api/#{endpoint}/#{id && "#{id}/"}new", { body: to_mautic })
75
- self.attributes = json[endpoint.singularize]
84
+ json = @connection.request(:post, "api/#{endpoint}/#{id && "#{id}/"}new", body: to_mautic)
85
+ assign_attributes json[endpoint.singularize]
76
86
  clear_changes
77
87
  rescue ValidationError => e
78
88
  self.errors = e.errors
@@ -106,8 +116,8 @@ module Mautic
106
116
  end
107
117
  end
108
118
 
109
- def to_mautic
110
- @table.each_with_object({}) do |(key,val), mem|
119
+ def to_mautic(data = @table)
120
+ data.each_with_object({}) do |(key, val), mem|
111
121
  mem[key] = val.is_a?(Array) ? val.join("|") : val
112
122
  end
113
123
  end
@@ -1,3 +1,3 @@
1
1
  module Mautic
2
- VERSION = '2.3.4'
2
+ VERSION = '2.3.9'
3
3
  end
@@ -46,6 +46,9 @@ RSpec.configure do |config|
46
46
 
47
47
  config.before(:each) do
48
48
  DatabaseCleaner.strategy = :transaction
49
+ Mautic.configure do |config|
50
+ config.authorize_mautic_connections = ->(controller) { true }
51
+ end
49
52
  end
50
53
 
51
54
  config.before(:each) do
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.4
4
+ version: 2.3.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukáš Pokorný
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-10 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -222,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  - !ruby/object:Gem::Version
223
223
  version: '0'
224
224
  requirements: []
225
- rubygems_version: 3.0.4
225
+ rubygems_version: 3.0.6
226
226
  signing_key:
227
227
  specification_version: 4
228
228
  summary: Ruby on Rails Mautic integration