intercom 3.9.4 → 4.1.1

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +340 -222
  3. data/Rakefile +1 -1
  4. data/changes.txt +25 -0
  5. data/lib/intercom.rb +33 -22
  6. data/lib/intercom/api_operations/archive.rb +2 -1
  7. data/lib/intercom/api_operations/delete.rb +16 -0
  8. data/lib/intercom/api_operations/find.rb +5 -2
  9. data/lib/intercom/api_operations/find_all.rb +4 -3
  10. data/lib/intercom/api_operations/list.rb +4 -1
  11. data/lib/intercom/api_operations/load.rb +4 -2
  12. data/lib/intercom/api_operations/nested_resource.rb +70 -0
  13. data/lib/intercom/api_operations/save.rb +6 -4
  14. data/lib/intercom/api_operations/scroll.rb +4 -5
  15. data/lib/intercom/api_operations/search.rb +3 -2
  16. data/lib/intercom/article.rb +7 -0
  17. data/lib/intercom/base_collection_proxy.rb +72 -0
  18. data/lib/intercom/client.rb +36 -25
  19. data/lib/intercom/client_collection_proxy.rb +17 -39
  20. data/lib/intercom/collection.rb +7 -0
  21. data/lib/intercom/company.rb +8 -0
  22. data/lib/intercom/contact.rb +21 -3
  23. data/lib/intercom/conversation.rb +5 -0
  24. data/lib/intercom/data_attribute.rb +7 -0
  25. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  26. data/lib/intercom/deprecated_resources.rb +13 -0
  27. data/lib/intercom/errors.rb +3 -0
  28. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  29. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  30. data/lib/intercom/lead.rb +21 -0
  31. data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
  32. data/lib/intercom/note.rb +4 -0
  33. data/lib/intercom/request.rb +37 -33
  34. data/lib/intercom/scroll_collection_proxy.rb +33 -38
  35. data/lib/intercom/search_collection_proxy.rb +30 -65
  36. data/lib/intercom/section.rb +23 -0
  37. data/lib/intercom/service/article.rb +20 -0
  38. data/lib/intercom/service/base_service.rb +7 -0
  39. data/lib/intercom/service/collection.rb +24 -0
  40. data/lib/intercom/service/company.rb +0 -12
  41. data/lib/intercom/service/contact.rb +21 -10
  42. data/lib/intercom/service/conversation.rb +12 -3
  43. data/lib/intercom/service/data_attribute.rb +20 -0
  44. data/lib/intercom/service/lead.rb +41 -0
  45. data/lib/intercom/service/note.rb +4 -8
  46. data/lib/intercom/service/section.rb +7 -0
  47. data/lib/intercom/service/subscription.rb +2 -2
  48. data/lib/intercom/service/tag.rb +9 -9
  49. data/lib/intercom/service/visitor.rb +17 -8
  50. data/lib/intercom/tag.rb +4 -0
  51. data/lib/intercom/traits/api_resource.rb +44 -18
  52. data/lib/intercom/traits/dirty_tracking.rb +8 -1
  53. data/lib/intercom/user.rb +12 -3
  54. data/lib/intercom/utils.rb +13 -2
  55. data/lib/intercom/version.rb +1 -1
  56. data/lib/intercom/visitor.rb +0 -2
  57. data/spec/spec_helper.rb +843 -520
  58. data/spec/unit/intercom/admin_spec.rb +2 -2
  59. data/spec/unit/intercom/article_spec.rb +40 -0
  60. data/spec/unit/intercom/base_collection_proxy_spec.rb +30 -0
  61. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  62. data/spec/unit/intercom/client_spec.rb +28 -25
  63. data/spec/unit/intercom/collection_spec.rb +32 -0
  64. data/spec/unit/intercom/company_spec.rb +13 -15
  65. data/spec/unit/intercom/contact_spec.rb +344 -33
  66. data/spec/unit/intercom/conversation_spec.rb +55 -7
  67. data/spec/unit/intercom/count_spec.rb +4 -4
  68. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  69. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  70. data/spec/unit/intercom/event_spec.rb +9 -11
  71. data/spec/unit/intercom/job_spec.rb +24 -24
  72. data/spec/unit/intercom/lead_spec.rb +57 -0
  73. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  74. data/spec/unit/intercom/message_spec.rb +1 -1
  75. data/spec/unit/intercom/note_spec.rb +4 -10
  76. data/spec/unit/intercom/request_spec.rb +1 -1
  77. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  78. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  79. data/spec/unit/intercom/section_spec.rb +32 -0
  80. data/spec/unit/intercom/segment_spec.rb +2 -2
  81. data/spec/unit/intercom/subscription_spec.rb +5 -6
  82. data/spec/unit/intercom/tag_spec.rb +22 -14
  83. data/spec/unit/intercom/team_spec.rb +2 -2
  84. data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
  85. data/spec/unit/intercom/user_spec.rb +224 -226
  86. data/spec/unit/intercom/visitor_spec.rb +49 -0
  87. data/spec/unit/intercom_spec.rb +5 -3
  88. metadata +34 -8
  89. data/lib/intercom/customer.rb +0 -10
  90. data/lib/intercom/service/customer.rb +0 -14
  91. data/spec/unit/intercom/visitors_spec.rb +0 -61
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/client_collection_proxy'
2
4
 
3
5
  module Intercom
@@ -17,8 +19,13 @@ module Intercom
17
19
  Intercom::ClientCollectionProxy
18
20
  end
19
21
 
22
+ def collection_name
23
+ @collection_name ||= Utils.resource_class_to_collection_name(collection_class)
24
+ end
25
+
20
26
  def from_api(api_response)
21
27
  object = collection_class.new
28
+ object.client = @client
22
29
  object.from_response(api_response)
23
30
  object
24
31
  end
@@ -0,0 +1,24 @@
1
+ require 'intercom/service/base_service'
2
+ require 'intercom/api_operations/list'
3
+ require 'intercom/api_operations/find'
4
+ require 'intercom/api_operations/delete'
5
+ require 'intercom/api_operations/save'
6
+
7
+ module Intercom
8
+ module Service
9
+ class Collection < BaseService
10
+ include ApiOperations::List
11
+ include ApiOperations::Find
12
+ include ApiOperations::Delete
13
+ include ApiOperations::Save
14
+
15
+ def collection_class
16
+ Intercom::Collection
17
+ end
18
+
19
+ def collection_name
20
+ "help_center/collections"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -23,18 +23,6 @@ module Intercom
23
23
  def collection_class
24
24
  Intercom::Company
25
25
  end
26
-
27
- def users_by_intercom_company_id(id)
28
- get_users(url: "/companies/#{id}/users")
29
- end
30
-
31
- def users_by_company_id(id)
32
- get_users(url: "/companies", params: { company_id: id, type: "user" })
33
- end
34
-
35
- private def get_users(url:, params: {})
36
- ClientCollectionProxy.new("users", finder_details: { url: url, params: params }, client: @client)
37
- end
38
26
  end
39
27
  end
40
28
  end
@@ -2,12 +2,9 @@ require 'intercom/service/base_service'
2
2
  require 'intercom/api_operations/load'
3
3
  require 'intercom/api_operations/list'
4
4
  require 'intercom/api_operations/find'
5
- require 'intercom/api_operations/find_all'
6
5
  require 'intercom/api_operations/save'
7
- require 'intercom/api_operations/scroll'
8
- require 'intercom/api_operations/convert'
9
- require 'intercom/api_operations/archive'
10
- require 'intercom/api_operations/request_hard_delete'
6
+ require 'intercom/api_operations/delete'
7
+ require 'intercom/api_operations/search'
11
8
 
12
9
  module Intercom
13
10
  module Service
@@ -15,16 +12,30 @@ module Intercom
15
12
  include ApiOperations::Load
16
13
  include ApiOperations::List
17
14
  include ApiOperations::Find
18
- include ApiOperations::FindAll
19
15
  include ApiOperations::Save
20
- include ApiOperations::Scroll
21
- include ApiOperations::Convert
22
- include ApiOperations::Archive
23
- include ApiOperations::RequestHardDelete
16
+ include ApiOperations::Delete
17
+ include ApiOperations::Search
24
18
 
25
19
  def collection_class
26
20
  Intercom::Contact
27
21
  end
22
+
23
+ def collection_proxy_class
24
+ Intercom::BaseCollectionProxy
25
+ end
26
+
27
+ def merge(lead, user)
28
+ raise_invalid_merge_error unless lead.role == 'lead' && user.role == 'user'
29
+
30
+ response = @client.post('/contacts/merge', from: lead.id, into: user.id)
31
+ raise Intercom::HttpError, 'Http Error - No response entity returned' unless response
32
+
33
+ user.from_response(response)
34
+ end
35
+
36
+ private def raise_invalid_merge_error
37
+ raise Intercom::InvalidMergeError, 'Merging can only be performed on a lead into a user'
38
+ end
28
39
  end
29
40
  end
30
41
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/service/base_service'
2
4
  require 'intercom/api_operations/find_all'
3
5
  require 'intercom/api_operations/find'
@@ -13,6 +15,7 @@ module Intercom
13
15
  include ApiOperations::Find
14
16
  include ApiOperations::Load
15
17
  include ApiOperations::Save
18
+ include ApiOperations::Search
16
19
 
17
20
  def collection_class
18
21
  Intercom::Conversation
@@ -25,7 +28,7 @@ module Intercom
25
28
  def reply(reply_data)
26
29
  id = reply_data.delete(:id)
27
30
  collection_name = Utils.resource_class_to_collection_name(collection_class)
28
- response = @client.post("/#{collection_name}/#{id}/reply", reply_data.merge(:conversation_id => id))
31
+ response = @client.post("/#{collection_name}/#{id}/reply", reply_data.merge(conversation_id: id))
29
32
  collection_class.new.from_response(response)
30
33
  end
31
34
 
@@ -44,14 +47,20 @@ module Intercom
44
47
  end
45
48
 
46
49
  def snooze(reply_data)
47
- snoozed_until = reply_data.fetch(:snoozed_until) { fail 'snoozed_until field is required' }
50
+ reply_data.fetch(:snoozed_until) { raise 'snoozed_until field is required' }
48
51
  reply reply_data.merge(message_type: 'snoozed', type: 'admin')
49
52
  end
50
53
 
51
54
  def assign(reply_data)
52
- assignee_id = reply_data.fetch(:assignee_id) { fail 'assignee_id is required' }
55
+ assignee_id = reply_data.fetch(:assignee_id) { raise 'assignee_id is required' }
53
56
  reply reply_data.merge(message_type: 'assignment', assignee_id: assignee_id, type: 'admin')
54
57
  end
58
+
59
+ def run_assignment_rules(id)
60
+ collection_name = Utils.resource_class_to_collection_name(collection_class)
61
+ response = @client.post("/#{collection_name}/#{id}/run_assignment_rules")
62
+ collection_class.new.from_response(response)
63
+ end
55
64
  end
56
65
  end
57
66
  end
@@ -0,0 +1,20 @@
1
+ require 'intercom/service/base_service'
2
+ require 'intercom/api_operations/load'
3
+ require 'intercom/api_operations/list'
4
+ require 'intercom/api_operations/find_all'
5
+ require 'intercom/api_operations/save'
6
+
7
+ module Intercom
8
+ module Service
9
+ class DataAttribute < BaseService
10
+ include ApiOperations::Load
11
+ include ApiOperations::List
12
+ include ApiOperations::FindAll
13
+ include ApiOperations::Save
14
+
15
+ def collection_class
16
+ Intercom::DataAttribute
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'intercom/service/base_service'
4
+ require 'intercom/api_operations/load'
5
+ require 'intercom/api_operations/list'
6
+ require 'intercom/api_operations/find'
7
+ require 'intercom/api_operations/find_all'
8
+ require 'intercom/api_operations/save'
9
+ require 'intercom/api_operations/scroll'
10
+ require 'intercom/api_operations/convert'
11
+ require 'intercom/api_operations/archive'
12
+ require 'intercom/api_operations/request_hard_delete'
13
+ require 'intercom/deprecated_leads_collection_proxy'
14
+
15
+ module Intercom
16
+ module Service
17
+ class Lead < BaseService
18
+ include ApiOperations::Load
19
+ include ApiOperations::List
20
+ include ApiOperations::Find
21
+ include ApiOperations::FindAll
22
+ include ApiOperations::Save
23
+ include ApiOperations::Scroll
24
+ include ApiOperations::Convert
25
+ include ApiOperations::Archive
26
+ include ApiOperations::RequestHardDelete
27
+
28
+ def collection_proxy_class
29
+ Intercom::DeprecatedLeadsCollectionProxy
30
+ end
31
+
32
+ def collection_class
33
+ Intercom::Lead
34
+ end
35
+
36
+ def collection_name
37
+ 'contacts'
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,22 +1,18 @@
1
1
  require 'intercom/service/base_service'
2
- require 'intercom/api_operations/list'
3
- require 'intercom/api_operations/find_all'
4
2
  require 'intercom/api_operations/find'
5
- require 'intercom/api_operations/load'
6
- require 'intercom/api_operations/save'
7
3
 
8
4
  module Intercom
9
5
  module Service
10
6
  class Note < BaseService
11
- include ApiOperations::Save
12
- include ApiOperations::List
13
- include ApiOperations::FindAll
14
7
  include ApiOperations::Find
15
- include ApiOperations::Load
16
8
 
17
9
  def collection_class
18
10
  Intercom::Note
19
11
  end
12
+
13
+ def collection_proxy_class
14
+ Intercom::BaseCollectionProxy
15
+ end
20
16
  end
21
17
  end
22
18
  end
@@ -0,0 +1,7 @@
1
+ require 'intercom/traits/api_resource'
2
+
3
+ module Intercom
4
+ class Section
5
+ include Traits::ApiResource
6
+ end
7
+ end
@@ -2,7 +2,7 @@ require 'intercom/api_operations/list'
2
2
  require 'intercom/api_operations/find_all'
3
3
  require 'intercom/api_operations/find'
4
4
  require 'intercom/api_operations/save'
5
- require 'intercom/api_operations/archive'
5
+ require 'intercom/api_operations/delete'
6
6
 
7
7
  module Intercom
8
8
  module Service
@@ -11,7 +11,7 @@ module Intercom
11
11
  include ApiOperations::Find
12
12
  include ApiOperations::FindAll
13
13
  include ApiOperations::Save
14
- include ApiOperations::Archive
14
+ include ApiOperations::Delete
15
15
 
16
16
  def collection_class
17
17
  Intercom::Subscription
@@ -2,6 +2,7 @@ require 'intercom/service/base_service'
2
2
  require 'intercom/api_operations/save'
3
3
  require 'intercom/api_operations/list'
4
4
  require 'intercom/api_operations/find_all'
5
+ require 'intercom/api_operations/find'
5
6
 
6
7
  module Intercom
7
8
  module Service
@@ -9,12 +10,17 @@ module Intercom
9
10
  include ApiOperations::Save
10
11
  include ApiOperations::List
11
12
  include ApiOperations::FindAll
12
- include ApiOperations::Archive
13
+ include ApiOperations::Delete
14
+ include ApiOperations::Find
13
15
 
14
16
  def collection_class
15
17
  Intercom::Tag
16
18
  end
17
19
 
20
+ def collection_proxy_class
21
+ Intercom::BaseCollectionProxy
22
+ end
23
+
18
24
  def tag(params)
19
25
  params['tag_or_untag'] = 'tag'
20
26
  create(params)
@@ -22,17 +28,11 @@ module Intercom
22
28
 
23
29
  def untag(params)
24
30
  params['tag_or_untag'] = 'untag'
25
- users_or_companies(params).each do |user_or_company|
26
- user_or_company[:untag] = true
31
+ params[:companies].each do |company|
32
+ company[:untag] = true
27
33
  end
28
34
  create(params)
29
35
  end
30
-
31
- private
32
-
33
- def users_or_companies(params)
34
- params[:users] || params[:companies]
35
- end
36
36
  end
37
37
  end
38
38
  end
@@ -1,26 +1,35 @@
1
1
  require 'intercom/service/base_service'
2
2
  require 'intercom/api_operations/load'
3
- require 'intercom/api_operations/list'
4
3
  require 'intercom/api_operations/find'
5
- require 'intercom/api_operations/find_all'
6
4
  require 'intercom/api_operations/save'
7
- require 'intercom/api_operations/convert'
8
- require 'intercom/api_operations/archive'
5
+ require 'intercom/api_operations/delete'
9
6
 
10
7
  module Intercom
11
8
  module Service
12
9
  class Visitor < BaseService
13
10
  include ApiOperations::Load
14
- include ApiOperations::List
15
11
  include ApiOperations::Find
16
- include ApiOperations::FindAll
17
12
  include ApiOperations::Save
18
- include ApiOperations::Convert
19
- include ApiOperations::Archive
13
+ include ApiOperations::Delete
20
14
 
21
15
  def collection_class
22
16
  Intercom::Visitor
23
17
  end
18
+
19
+ def convert(visitor, contact = false)
20
+ req = { visitor: { user_id: visitor.user_id } }
21
+ if contact
22
+ req[:user] = identity_hash(contact)
23
+ req[:type] = 'user'
24
+ else
25
+ req[:type] = 'lead'
26
+ end
27
+ Intercom::Contact.new.from_response(
28
+ @client.post(
29
+ "/visitors/convert", req
30
+ )
31
+ )
32
+ end
24
33
  end
25
34
  end
26
35
  end
@@ -3,5 +3,9 @@ require 'intercom/traits/api_resource'
3
3
  module Intercom
4
4
  class Tag
5
5
  include Traits::ApiResource
6
+
7
+ def self.collection_proxy_class
8
+ Intercom::BaseCollectionProxy
9
+ end
6
10
  end
7
11
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'intercom/lib/flat_store'
2
4
  require 'intercom/lib/dynamic_accessors'
3
5
  require 'intercom/lib/dynamic_accessors_on_method_missing'
@@ -6,16 +8,19 @@ require 'intercom/lib/typed_json_deserializer'
6
8
 
7
9
  module Intercom
8
10
  module Traits
9
-
10
11
  module ApiResource
11
12
  include DirtyTracking
12
13
 
13
- attr_accessor :id
14
+ attr_accessor :id, :client
14
15
 
15
16
  def initialize(attributes = {})
16
17
  from_hash(attributes)
17
18
  end
18
19
 
20
+ def ==(other)
21
+ self.class == other.class && to_json == other.to_json
22
+ end
23
+
19
24
  def from_response(response)
20
25
  from_hash(response)
21
26
  reset_changed_fields!
@@ -31,49 +36,71 @@ module Intercom
31
36
  end
32
37
 
33
38
  def to_hash
34
- instance_variables_excluding_dirty_tracking_field.inject({}) do |hash, variable|
35
- hash[variable.to_s.delete("@")] = instance_variable_get(variable)
36
- hash
39
+ instance_variables_excluding_dirty_tracking_field.each_with_object({}) do |variable, hash|
40
+ hash[variable.to_s.delete('@')] = instance_variable_get(variable)
41
+ end
42
+ end
43
+
44
+ def to_json(*args)
45
+ instance_variables_excluding_dirty_tracking_field.each_with_object({}) do |variable, hash|
46
+ next if variable == :@client
47
+
48
+ value = instance_variable_get(variable)
49
+ hash[variable.to_s.delete('@')] = value.respond_to?(:to_json) ? value.to_json(*args) : value
37
50
  end
38
51
  end
39
52
 
40
53
  def to_submittable_hash
41
54
  submittable_hash = {}
42
55
  to_hash.each do |attribute, value|
43
- submittable_hash[attribute] = value if submittable_attribute?(attribute, value)
56
+ next unless submittable_attribute?(attribute, value)
57
+
58
+ submittable_hash[attribute] = value.respond_to?(:to_submittable_hash) ? value.to_submittable_hash : value
44
59
  end
45
60
  submittable_hash
46
61
  end
47
62
 
48
63
  def method_missing(method_sym, *arguments, &block)
49
- Lib::DynamicAccessorsOnMethodMissing.new(method_sym, *arguments, self).
50
- define_accessors_or_call { super }
64
+ Lib::DynamicAccessorsOnMethodMissing.new(method_sym, *arguments, self)
65
+ .define_accessors_or_call { super }
51
66
  end
52
67
 
53
68
  def flat_store_attribute?(attribute)
54
- (respond_to?(:flat_store_attributes)) && (flat_store_attributes.map(&:to_s).include?(attribute.to_s))
69
+ respond_to?(:flat_store_attributes) && flat_store_attributes.map(&:to_s).include?(attribute.to_s)
55
70
  end
56
71
 
57
72
  private
58
73
 
59
74
  def initialize_property(attribute, value)
75
+ return if addressable_list?(attribute, value)
76
+
60
77
  Lib::DynamicAccessors.define_accessors(attribute, value, self) unless accessors_already_defined?(attribute)
61
78
  set_property(attribute, value)
62
79
  end
63
80
 
81
+ def addressable_list?(attribute, value)
82
+ return false unless typed_property?(attribute, value)
83
+
84
+ value['type'] == 'list' && value['url']
85
+ end
86
+
64
87
  def accessors_already_defined?(attribute)
65
88
  respond_to?(attribute) && respond_to?("#{attribute}=")
66
89
  end
67
90
 
68
91
  def set_property(attribute, value)
92
+ value_to_set = parsed_value_for_attribute(attribute, value)
93
+ call_setter_for_attribute(attribute, value_to_set)
94
+ end
95
+
96
+ def parsed_value_for_attribute(attribute, value)
69
97
  if typed_property?(attribute, value)
70
- value_to_set = Intercom::Lib::TypedJsonDeserializer.new(value).deserialize
98
+ Intercom::Lib::TypedJsonDeserializer.new(value, client).deserialize
71
99
  elsif flat_store_attribute?(attribute)
72
- value_to_set = Intercom::Lib::FlatStore.new(value)
100
+ Intercom::Lib::FlatStore.new(value)
73
101
  else
74
- value_to_set = value
102
+ value
75
103
  end
76
- call_setter_for_attribute(attribute, value_to_set)
77
104
  end
78
105
 
79
106
  def custom_attribute_field?(attribute)
@@ -97,12 +124,12 @@ module Intercom
97
124
  end
98
125
 
99
126
  def typed_value?(value)
100
- value.is_a? Hash and !!value['type']
127
+ value.is_a?(Hash) && !!value['type']
101
128
  end
102
129
 
103
130
  def call_setter_for_attribute(attribute, value)
104
- setter_method = "#{attribute.to_s}="
105
- self.send(setter_method, value)
131
+ setter_method = "#{attribute}="
132
+ send(setter_method, value)
106
133
  end
107
134
 
108
135
  def initialize_missing_flat_store_attributes
@@ -120,7 +147,7 @@ module Intercom
120
147
 
121
148
  module ClassMethods
122
149
  def from_api(api_response)
123
- object = self.new
150
+ object = new
124
151
  object.from_response(api_response)
125
152
  object
126
153
  end
@@ -129,7 +156,6 @@ module Intercom
129
156
  def self.included(base)
130
157
  base.extend(ClassMethods)
131
158
  end
132
-
133
159
  end
134
160
  end
135
161
  end