intercom 1.0.0 → 2.0.0

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -8
  3. data/Gemfile +3 -0
  4. data/README.md +208 -52
  5. data/changes.txt +3 -0
  6. data/intercom.gemspec +2 -2
  7. data/lib/ext/hash.rb +18 -0
  8. data/lib/intercom.rb +38 -43
  9. data/lib/intercom/api_operations/count.rb +16 -0
  10. data/lib/intercom/api_operations/delete.rb +15 -0
  11. data/lib/intercom/api_operations/find.rb +22 -0
  12. data/lib/intercom/api_operations/find_all.rb +33 -0
  13. data/lib/intercom/api_operations/list.rb +17 -0
  14. data/lib/intercom/api_operations/load.rb +15 -0
  15. data/lib/intercom/api_operations/save.rb +44 -0
  16. data/lib/intercom/collection_proxy.rb +66 -0
  17. data/lib/intercom/company.rb +29 -0
  18. data/lib/intercom/conversation.rb +15 -0
  19. data/lib/intercom/count.rb +21 -0
  20. data/lib/intercom/errors.rb +52 -0
  21. data/lib/intercom/event.rb +4 -101
  22. data/lib/intercom/extended_api_operations/reply.rb +16 -0
  23. data/lib/intercom/extended_api_operations/tags.rb +14 -0
  24. data/lib/intercom/extended_api_operations/users.rb +17 -0
  25. data/lib/intercom/generic_handlers/base_handler.rb +22 -0
  26. data/lib/intercom/generic_handlers/count.rb +59 -0
  27. data/lib/intercom/generic_handlers/tag.rb +71 -0
  28. data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
  29. data/lib/intercom/lib/dynamic_accessors.rb +59 -0
  30. data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
  31. data/lib/intercom/lib/flat_store.rb +31 -0
  32. data/lib/intercom/lib/typed_json_deserializer.rb +52 -0
  33. data/lib/intercom/message.rb +9 -0
  34. data/lib/intercom/note.rb +14 -42
  35. data/lib/intercom/request.rb +40 -4
  36. data/lib/intercom/segment.rb +14 -0
  37. data/lib/intercom/tag.rb +19 -78
  38. data/lib/intercom/traits/api_resource.rb +120 -0
  39. data/lib/intercom/traits/dirty_tracking.rb +33 -0
  40. data/lib/intercom/traits/generic_handler_binding.rb +29 -0
  41. data/lib/intercom/traits/incrementable_attributes.rb +23 -0
  42. data/lib/intercom/user.rb +25 -361
  43. data/lib/intercom/utils.rb +50 -0
  44. data/lib/intercom/version.rb +1 -1
  45. data/spec/spec_helper.rb +64 -33
  46. data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
  47. data/spec/unit/intercom/event_spec.rb +25 -0
  48. data/spec/unit/intercom/{flat_store_spec.rb → lib/flat_store_spec.rb} +7 -7
  49. data/spec/unit/intercom/note_spec.rb +5 -4
  50. data/spec/unit/intercom/tag_spec.rb +3 -3
  51. data/spec/unit/intercom/traits/api_resource_spec.rb +79 -0
  52. data/spec/unit/intercom/user_spec.rb +101 -119
  53. data/spec/unit/intercom_spec.rb +7 -7
  54. metadata +50 -26
  55. data/lib/intercom/flat_store.rb +0 -27
  56. data/lib/intercom/hashable_object.rb +0 -22
  57. data/lib/intercom/impression.rb +0 -63
  58. data/lib/intercom/message_thread.rb +0 -189
  59. data/lib/intercom/requires_parameters.rb +0 -10
  60. data/lib/intercom/social_profile.rb +0 -24
  61. data/lib/intercom/unix_timestamp_unwrapper.rb +0 -12
  62. data/lib/intercom/user_collection_proxy.rb +0 -52
  63. data/lib/intercom/user_resource.rb +0 -82
  64. data/spec/integration/fixtures/v1-user.json +0 -45
  65. data/spec/integration/fixtures/v1-users-impression.json +0 -3
  66. data/spec/integration/fixtures/v1-users-message_thread.json +0 -44
  67. data/spec/integration/fixtures/v1-users-message_threads.json +0 -46
  68. data/spec/integration/fixtures/v1-users-note.json +0 -49
  69. data/spec/integration/fixtures/v1-users.json +0 -144
  70. data/spec/integration/intercom_api_integration_spec.rb +0 -134
  71. data/spec/unit/intercom/impression_spec.rb +0 -18
  72. data/spec/unit/intercom/message_thread_spec.rb +0 -74
  73. data/spec/unit/intercom/user_collection_proxy_spec.rb +0 -46
  74. data/spec/unit/intercom/user_event_spec.rb +0 -83
  75. data/spec/unit/intercom/user_resource_spec.rb +0 -13
@@ -0,0 +1,23 @@
1
+ module Intercom
2
+ module Traits
3
+ module IncrementableAttributes
4
+
5
+ def increment(key, value=1)
6
+ mark_field_as_changed!(:increments)
7
+ increments[key] ||= 0
8
+ increments[key] += value
9
+ end
10
+
11
+ private
12
+
13
+ def increments
14
+ @increments ||= {}
15
+ end
16
+
17
+ def increments=(hash)
18
+ mark_field_as_changed!(:increments)
19
+ @increments = hash
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/intercom/user.rb CHANGED
@@ -1,366 +1,30 @@
1
- require 'intercom/user_resource'
2
- require 'intercom/flat_store'
3
- require 'intercom/user_collection_proxy'
4
- require 'intercom/social_profile'
1
+ require 'intercom/api_operations/count'
2
+ require 'intercom/api_operations/list'
3
+ require 'intercom/api_operations/load'
4
+ require 'intercom/api_operations/find'
5
+ require 'intercom/api_operations/find_all'
6
+ require 'intercom/api_operations/save'
7
+ require 'intercom/api_operations/delete'
8
+ require 'intercom/extended_api_operations/tags'
9
+ require 'intercom/traits/incrementable_attributes'
10
+ require 'intercom/traits/api_resource'
5
11
 
6
12
  module Intercom
7
- # Represents a user of your application on Intercom.
8
- #
9
- # == Example usage
10
- # * Fetching a user
11
- # Intercom::User.find_by_email("bob@example.com")
12
- #
13
- # * Getting the count of all users
14
- # Intercom::User.all.count
15
- #
16
- # * Fetching all users
17
- # Intercom::User.all.each { |user| puts user.email }
18
- #
19
- # * Updating custom data on a user
20
- # user = Intercom::User.find_by_email("bob@example.com")
21
- # user.custom_data["number_of_applications"] = 11
22
- # user.save
23
- class User < UserResource
13
+ class User
14
+ include ApiOperations::Count
15
+ include ApiOperations::List
16
+ include ApiOperations::Load
17
+ include ApiOperations::Find
18
+ include ApiOperations::FindAll
19
+ include ApiOperations::Save
20
+ include ApiOperations::Delete
21
+ include ExtendedApiOperations::Tags
22
+ include Traits::IncrementableAttributes
23
+ include Traits::ApiResource
24
+
25
+ def identity_vars ; [:id, :email, :user_id] ; end
26
+ def flat_store_attributes ; [:custom_attributes] ; end
27
+ def update_verb ; 'post' ; end
24
28
 
25
-
26
- ##
27
- # Fetches an Intercom::User from our API.
28
- #
29
- # Calls GET https://api.intercom.io/v1/users
30
- #
31
- # returns Intercom::User object representing the state on our servers.
32
- #
33
- # @return [User]
34
- def self.find(params)
35
- response = Intercom.get("/v1/users", params)
36
- User.from_api(response)
37
- end
38
-
39
- # Calls GET https://api.intercom.io/v1/users?email=EMAIL
40
- #
41
- # returns Intercom::User object representing the state on our servers.
42
- #
43
- # @param [String] email address of the user
44
- # @return [User]
45
- def self.find_by_email(email)
46
- find({:email => email})
47
- end
48
-
49
- # Calls GET https://api.intercom.io/v1/users?user_id=USER-ID
50
- #
51
- # returns Intercom::User object representing the state on our servers.
52
- #
53
- # @param [String] user_id user id of the user
54
- # @return [User]
55
- def self.find_by_user_id(user_id)
56
- find({:user_id => user_id})
57
- end
58
-
59
- # Creates (or updates when a user already exists for that email/user_id) a user record on your application.
60
- #
61
- # Calls POST https://api.intercom.io/v1/users
62
- #
63
- # returns Intercom::User object representing the state on our servers.
64
- #
65
- # This operation is idempotent.
66
- # @return [User]
67
- def self.create(params)
68
- User.new(params).save
69
- end
70
-
71
- # Retrieve all the users
72
- # Examples:
73
- # Intercom::User.all.each do |user|
74
- # puts user.inspect
75
- # end
76
- # > ["user1@example.com" ,"user2@example.com" ,....]
77
- # Intercom::User.all.map(&:email)
78
- # > ["user1@example.com" ,"user2@example.com" ,....]
79
- #
80
- # @return [UserCollectionProxy]
81
- def self.all
82
- UserCollectionProxy.new
83
- end
84
-
85
- # Retrieve all the users that match a query
86
- # Examples:
87
- # Intercom::User.where(:tag_name => 'Free Trial').each do |user|
88
- # puts user.inspect
89
- # end
90
- # > ["user1@example.com" ,"user2@example.com" ,....]
91
- # Intercom::User.where(:tag_name => 'Free Trial').map(&:email)
92
- # > ["user1@example.com" ,"user2@example.com" ,....]
93
- #
94
- # Currently only supports tag_name and tag_id querying
95
- #
96
- # @return [UserCollectionProxy]
97
- def self.where(params)
98
- UserCollectionProxy.new(params)
99
- end
100
-
101
- # Fetches a count of all Users tracked on Intercom.
102
- # Example:
103
- # Intercom::User.all.count
104
- # > 5346
105
- #
106
- # @return [Integer]
107
- def self.count
108
- response = Intercom.get("/v1/users", {:per_page => 1})
109
- response["total_count"]
110
- end
111
-
112
- # Deletes a user record on your application.
113
- #
114
- # Calls DELETE https://api.intercom.io/v1/users
115
- #
116
- # returns Intercom::User object representing the user just before deletion.
117
- #
118
- # This operation is not idempotent.
119
- # @return [User]
120
- def self.delete(params)
121
- response = Intercom.delete("/v1/users", params)
122
- User.from_api(response)
123
- end
124
-
125
- # instance method alternative to #create
126
- # @return [User]
127
- def save
128
- response = Intercom.post("/v1/users", to_hash)
129
- self.update_from_api_response(response)
130
- end
131
-
132
- # Increment a custom data value on a user
133
- # @return [User]
134
- def increment(key, value=1)
135
- increments[key] ||= 0
136
- increments[key] += value
137
- end
138
-
139
- # @return [String] the {User}'s name
140
- def name
141
- @attributes["name"]
142
- end
143
-
144
- # @param [String] name {User}'s name
145
- # @return [void]
146
- def name=(name)
147
- @attributes["name"]=name
148
- end
149
-
150
- # @return [String]
151
- def last_seen_ip
152
- @attributes["last_seen_ip"]
153
- end
154
-
155
- # @return [void]
156
- def last_seen_ip=(last_seen_ip)
157
- @attributes["last_seen_ip"]=last_seen_ip
158
- end
159
-
160
- # @return [String]
161
- def last_seen_user_agent
162
- @attributes["last_seen_user_agent"]
163
- end
164
-
165
- # @return [void]
166
- def last_seen_user_agent=(last_seen_user_agent)
167
- @attributes["last_seen_user_agent"]=last_seen_user_agent
168
- end
169
-
170
- # @return [Integer]
171
- def relationship_score
172
- @attributes["relationship_score"]
173
- end
174
-
175
- # @return [Integer]
176
- def session_count
177
- @attributes["session_count"]
178
- end
179
-
180
- ##
181
- # Get last time this User interacted with your application
182
- # @return [Time]
183
- def last_impression_at
184
- time_at("last_impression_at")
185
- end
186
-
187
- ##
188
- # Set Time at which this User last made a request your application.
189
- # @return [void]
190
- def last_impression_at=(time)
191
- set_time_at("last_impression_at", time)
192
- end
193
-
194
- ##
195
- # Get last time this User interacted with your application
196
- # @return [Time]
197
- def last_request_at
198
- time_at("last_request_at")
199
- end
200
-
201
- ##
202
- # Set Time at which this User last made a request your application.
203
- # @return [void]
204
- def last_request_at=(time)
205
- set_time_at("last_request_at", time)
206
- end
207
-
208
- ##
209
- # Get Time at which this User started using your application.
210
- # @return [Time]
211
- def created_at
212
- time_at("created_at")
213
- end
214
-
215
- ##
216
- # Set Time at which this User started using your application.
217
- # @return [void]
218
- def created_at=(time)
219
- set_time_at("created_at", time)
220
- end
221
-
222
- ##
223
- # Get whether user has unsubscribed from email
224
- # @return [Boolean]
225
- def unsubscribed_from_emails
226
- @attributes['unsubscribed_from_emails']
227
- end
228
-
229
- ##
230
- # Get url for user's avatar, if present. Otherwise, nil.
231
- # @return [String]
232
- def avatar_url
233
- @attributes["avatar_url"]
234
- end
235
-
236
- ##
237
- # Set whether user has unsubscribed from email
238
- # @return [void]
239
- def unsubscribed_from_emails=(unsubscribed_from_emails)
240
- @attributes['unsubscribed_from_emails'] = unsubscribed_from_emails
241
- end
242
-
243
- ##
244
- # Get array of Intercom::SocialProfile objects attached to this Intercom::User
245
- #
246
- # See http://docs.intercom.io/#SocialProfiles for more information
247
- # @return [Array<SocialProfile>]
248
- def social_profiles
249
- @social_profiles ||= [].freeze
250
- end
251
-
252
- ##
253
- # Get hash of location attributes associated with this Intercom::User
254
- #
255
- # Possible entries: city_name, continent_code, country_code, country_name, latitude, longitude, postal_code, region_name, timezone
256
- #
257
- # e.g.
258
- #
259
- # {"city_name"=>"Santiago", "continent_code"=>"SA", "country_code"=>"CHL", "country_name"=>"Chile",
260
- # "latitude"=>-33.44999999999999, "longitude"=>-70.6667, "postal_code"=>"", "region_name"=>"12",
261
- # "timezone"=>"Chile/Continental"}
262
- # @return [Hash]
263
- def location_data
264
- @location_data ||= {}.freeze
265
- end
266
-
267
- # Custom attributes stored for this Intercom::User
268
- #
269
- # See http://docs.intercom.io/#CustomData for more information
270
- #
271
- # Example: Reading custom_data value for an existing user
272
- # user = Intercom::User.find(:email => "someone@example.com")
273
- # puts user.custom_data[:plan]
274
- #
275
- # Example: Setting some custom data for an existing user
276
- # user = Intercom::User.find(:email => "someone@example.com")
277
- # user.custom_data[:plan] = "pro"
278
- # user.save
279
- #
280
- # @return [FlatStore]
281
- def custom_data
282
- @attributes["custom_data"] ||= FlatStore.new
283
- end
284
-
285
- # Set a {Hash} of custom data attributes to save/update on this user
286
- #
287
- # @param [Hash] custom_data
288
- # @return [FlatStore]
289
- def custom_data=(custom_data)
290
- @attributes["custom_data"] = FlatStore.new(custom_data)
291
- end
292
-
293
- # Company stored for this Intercom::User
294
- #
295
- # See http://docs.intercom.io/#Companies for more information
296
- #
297
- # Example: Setting a company for an existing user
298
- # user = Intercom::User.find(:email => "someone@example.com")
299
- # user.company[:id] = 6
300
- # user.company[:name] = "Intercom"
301
- # user.save
302
- #
303
- # @return [FlatStore]
304
- def company
305
- @attributes["company"] ||= FlatStore.new
306
- end
307
-
308
- # Set a {Hash} of company attributes to save/update on this user
309
- #
310
- # @param [Hash] company
311
- # @return [FlatStore]
312
- def company=(company)
313
- @attributes["company"] = FlatStore.new(company)
314
- end
315
-
316
- # Multiple companies for this Intercom::User
317
- #
318
- # See http://docs.intercom.io/#Companies for more information
319
- #
320
- # Example: Setting a company for an existing user
321
- # user = Intercom::User.find(:email => "someone@example.com")
322
- # user.companies = [{:id => 6, :name => "intercom"}, {:id => 9, :name => "Test Company"}]
323
- # user.save
324
- #
325
- # @return [Array]
326
- def companies
327
- @attributes["companies"] ||= []
328
- end
329
-
330
- # Set an {Array} of {Hash} company attributes to save/update on this user
331
- #
332
- # @param [Array] companies
333
- # @return [Array]
334
- def companies=(companies)
335
- raise ArgumentError.new("Companies requires an array of hashes of companies") unless companies.is_a?(Array) && companies.all? {|company| company.is_a?(Hash)}
336
- @attributes["companies"] = companies.collect {|company| FlatStore.new(company) }
337
- end
338
-
339
- ##
340
- # Creates an Event for the given User
341
- # @param {Hash} options, keys for :created_at (Unix timestamp) and metadata
342
- def track_event(event_name, options={})
343
- attributes = {:event_name => event_name, :user => self}
344
- attributes[:created_at] = options[:created_at] unless options[:created_at].nil?
345
- attributes[:metadata] = options[:metadata] unless options[:metadata].nil?
346
- Event.create(attributes)
347
- end
348
-
349
- protected
350
- def social_profiles=(social_profiles) #:nodoc:
351
- @social_profiles = social_profiles.map { |account| SocialProfile.new(account) }.freeze
352
- end
353
-
354
- def location_data=(hash) #:nodoc:
355
- @location_data = hash.freeze
356
- end
357
-
358
- def increments #:nodoc:
359
- @attributes["increments"] ||= {}
360
- end
361
-
362
- def increments=(hash) #:nodoc:
363
- @attributes["increments"] = hash
364
- end
365
29
  end
366
30
  end
@@ -0,0 +1,50 @@
1
+ module Intercom
2
+ module Utils
3
+ class << self
4
+ def singularize(str)
5
+ str.gsub(/ies$/, 'y').gsub(/s$/, '')
6
+ end
7
+
8
+ def pluralize(str)
9
+ return str.gsub(/y$/, 'ies') if str =~ /y$/
10
+ "#{str}s"
11
+ end
12
+
13
+ def resource_class_to_singular_name(resource_class)
14
+ resource_class.to_s.split('::')[-1].downcase
15
+ end
16
+
17
+ def resource_class_to_collection_name(resource_class)
18
+ Utils.pluralize(resource_class_to_singular_name(resource_class))
19
+ end
20
+
21
+ def constantize_resource_name(resource_name)
22
+ class_name = Utils.singularize(resource_name.capitalize)
23
+ define_lightweight_class(class_name) unless Intercom.const_defined?(class_name)
24
+ namespaced_class_name = "Intercom::#{class_name}"
25
+ Object.const_get(namespaced_class_name)
26
+ end
27
+
28
+ def constantize_singular_resource_name(resource_name)
29
+ class_name = resource_name.split('_').map(&:capitalize).join
30
+ define_lightweight_class(class_name) unless Intercom.const_defined?(class_name)
31
+ namespaced_class_name = "Intercom::#{class_name}"
32
+ Object.const_get(namespaced_class_name )
33
+ end
34
+
35
+ def define_lightweight_class(class_name)
36
+ #File.open('./intercom_ruby_dynamically_defined_classes.log', 'a') {|f| f.puts("Dynamically defining the class Intercom::#{class_name}") } #HACK
37
+ new_class_definition = Class.new(Object) do
38
+ include Traits::ApiResource
39
+ end
40
+ Intercom.const_set(class_name, new_class_definition)
41
+ end
42
+
43
+ def entity_key_from_type(type)
44
+ is_list = type.split('.')[1] == 'list'
45
+ entity_name = type.split('.')[0]
46
+ is_list ? Utils.pluralize(entity_name) : entity_name
47
+ end
48
+ end
49
+ end
50
+ end