intercom 3.5.10 → 3.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +5 -0
  4. data/Gemfile +1 -4
  5. data/README.md +152 -83
  6. data/RELEASING.md +9 -0
  7. data/changes.txt +116 -0
  8. data/intercom.gemspec +1 -2
  9. data/lib/intercom.rb +4 -0
  10. data/lib/intercom/api_operations/{delete.rb → archive.rb} +4 -2
  11. data/lib/intercom/api_operations/find_all.rb +1 -1
  12. data/lib/intercom/api_operations/request_hard_delete.rb +12 -0
  13. data/lib/intercom/api_operations/search.rb +17 -0
  14. data/lib/intercom/client.rb +42 -5
  15. data/lib/intercom/customer.rb +10 -0
  16. data/lib/intercom/errors.rb +41 -4
  17. data/lib/intercom/request.rb +144 -81
  18. data/lib/intercom/search_collection_proxy.rb +82 -0
  19. data/lib/intercom/service/base_service.rb +6 -0
  20. data/lib/intercom/service/company.rb +14 -2
  21. data/lib/intercom/service/contact.rb +4 -2
  22. data/lib/intercom/service/conversation.rb +12 -0
  23. data/lib/intercom/service/customer.rb +14 -0
  24. data/lib/intercom/service/event.rb +12 -0
  25. data/lib/intercom/service/subscription.rb +2 -2
  26. data/lib/intercom/service/tag.rb +1 -1
  27. data/lib/intercom/service/team.rb +17 -0
  28. data/lib/intercom/service/user.rb +4 -2
  29. data/lib/intercom/service/visitor.rb +2 -2
  30. data/lib/intercom/team.rb +7 -0
  31. data/lib/intercom/traits/api_resource.rb +4 -9
  32. data/lib/intercom/version.rb +1 -1
  33. data/spec/spec_helper.rb +124 -2
  34. data/spec/unit/intercom/client_collection_proxy_spec.rb +5 -5
  35. data/spec/unit/intercom/client_spec.rb +69 -1
  36. data/spec/unit/intercom/company_spec.rb +20 -16
  37. data/spec/unit/intercom/contact_spec.rb +6 -0
  38. data/spec/unit/intercom/conversation_spec.rb +15 -0
  39. data/spec/unit/intercom/event_spec.rb +19 -0
  40. data/spec/unit/intercom/request_spec.rb +150 -9
  41. data/spec/unit/intercom/search_collection_proxy_spec.rb +56 -0
  42. data/spec/unit/intercom/team_spec.rb +21 -0
  43. data/spec/unit/intercom/traits/api_resource_spec.rb +34 -7
  44. data/spec/unit/intercom/user_spec.rb +15 -3
  45. metadata +33 -22
  46. data/.travis.yml +0 -6
  47. data/lib/intercom/extended_api_operations/users.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0f98bf7f9725ad035949ca88859ba807a6323a83
4
- data.tar.gz: 97e46a4507500d311495e11114fb80d0715cb0a0
2
+ SHA256:
3
+ metadata.gz: 204538ee7ce2d0d8b41b4c0b8ff4c6d80084570c410850ba02fc936a14292b8d
4
+ data.tar.gz: 6704e411dcc92ae860d3d519bdd592e35ac2b931fb20e188b934bb4228232f12
5
5
  SHA512:
6
- metadata.gz: 8c83c5d9c5ad9d4844b5b8f7c3602e6bf76cbbb9e9836b264acbdcfdb5e3567310c1441e23c7cd0b2dac30f0200bbea46175fe9eea5c130aa49d16e9ca5cd2d4
7
- data.tar.gz: b480c171fd98135e719c37be86b0d13f7288f65130583d863afad3dd32acdc42de3e66be8941620047ba57db9fc54548b10307cbed55bd5278563825e6728de0
6
+ metadata.gz: 496d153506de79e3527db4ba20176dd375a29ad37ab259121030f8b70ab5ba934db19fa917c28755d7205f092df2756f493742f47dbbc1eab895ac8ffa15a330
7
+ data.tar.gz: 7248e5d8c2734a256c499b3145758965b2efd48b0b531a337e1337553724c40f156263b67f8db5612ed5bc2c92fb6a57b3d3068d2360647e412f8861c1a9f205
@@ -0,0 +1,35 @@
1
+ version: 2
2
+ jobs:
3
+ "Test against Ruby 2.4":
4
+ docker:
5
+ - image: circleci/ruby:2.4.9
6
+ working_directory: ~/intercom-ruby
7
+ steps:
8
+ - checkout
9
+ - run: bundle install
10
+ - run: bundle exec rake
11
+ "Test against Ruby 2.5":
12
+ docker:
13
+ - image: circleci/ruby:2.5.7
14
+ working_directory: ~/intercom-ruby
15
+ steps:
16
+ - checkout
17
+ - run: bundle install
18
+ - run: bundle exec rake
19
+ "Test against Ruby 2.6":
20
+ docker:
21
+ - image: circleci/ruby:2.6.5
22
+ working_directory: ~/intercom-ruby
23
+ steps:
24
+ - checkout
25
+ - run: bundle install
26
+ - run: bundle exec rake
27
+
28
+ workflows:
29
+ version: 2
30
+ build_and_test:
31
+ jobs:
32
+ - "Test against Ruby 2.4"
33
+ - "Test against Ruby 2.5"
34
+ - "Test against Ruby 2.6"
35
+
@@ -0,0 +1,5 @@
1
+ #### Why?
2
+ Why are you making this change?
3
+
4
+ #### How?
5
+ Technical details on your change
data/Gemfile CHANGED
@@ -1,13 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem 'webmock'
3
4
  gemspec
4
5
 
5
6
  group :development, :test do
6
7
  platforms :jruby do
7
- gem 'json-jruby'
8
8
  gem 'jruby-openssl'
9
9
  end
10
- platforms :ruby_18 do
11
- gem 'json_pure'
12
- end
13
10
  end
data/README.md CHANGED
@@ -18,23 +18,29 @@ This version of the gem is compatible with `Ruby 2.1` and above.
18
18
 
19
19
  ## Installation
20
20
 
21
+
21
22
  gem install intercom
22
23
 
23
24
  Using bundler:
24
25
 
25
- gem 'intercom', '~> 3.5.9'
26
+ gem 'intercom', '~> 3.9.4'
26
27
 
27
28
  ## Basic Usage
28
29
 
29
30
  ### Configure your client
30
31
 
31
- > If you already have a personal access token you can find it [here](https://app.intercom.io/a/apps/_/settings/personal-access-token). If you want to create or learn more about personal access tokens then you can find more info [here](https://developers.intercom.io/docs/personal-access-tokens).
32
+ > If you already have a personal access token you can find it [here](https://app.intercom.io/a/apps/_/developer-hub/). If you want to create or learn more about personal access tokens then you can find more info [here](https://developers.intercom.io/docs/personal-access-tokens).
32
33
 
33
34
  ```ruby
34
35
  # With an OAuth or Personal Access token:
35
36
  intercom = Intercom::Client.new(token: 'my_token')
36
37
  ```
37
38
 
39
+ ```ruby
40
+ # With a versioned app:
41
+ intercom = Intercom::Client.new(token: 'my_token', api_version: '1.0')
42
+ ```
43
+
38
44
  If you are building a third party application you can get your access_tokens by [setting-up-oauth](https://developers.intercom.io/page/setting-up-oauth) for Intercom.
39
45
  You can also use the [omniauth-intercom lib](https://github.com/intercom/omniauth-intercom) which is a middleware helping you to handle the authentication process with Intercom.
40
46
 
@@ -43,6 +49,7 @@ You can also use the [omniauth-intercom lib](https://github.com/intercom/omniaut
43
49
  Resources this API supports:
44
50
 
45
51
  https://api.intercom.io/users
52
+ https://api.intercom.io/teams
46
53
  https://api.intercom.io/contacts
47
54
  https://api.intercom.io/companies
48
55
  https://api.intercom.io/counts
@@ -54,7 +61,6 @@ Resources this API supports:
54
61
  https://api.intercom.io/messages
55
62
  https://api.intercom.io/subscriptions
56
63
  https://api.intercom.io/jobs
57
- https://api.intercom.io/bulk
58
64
 
59
65
  ### Examples
60
66
 
@@ -69,9 +75,13 @@ user = intercom.users.find(user_id: "1")
69
75
  user = intercom.users.find(id: "1")
70
76
  # Create a user
71
77
  user = intercom.users.create(email: "bob@example.com", name: "Bob Smith", signed_up_at: Time.now.to_i)
72
- # Delete a user
78
+ # archive a user
73
79
  user = intercom.users.find(id: "1")
74
- deleted_user = intercom.users.delete(user)
80
+ archived_user = intercom.users.archive(user)
81
+ # request a hard delete for a user
82
+ (https://developers.intercom.com/intercom-api-reference/reference#delete-users)
83
+ user = intercom.users.find(id: "1")
84
+ deleted_user = intercom.users.request_hard_delete(user)
75
85
  # Update custom_attributes for a user
76
86
  user.custom_attributes["average_monthly_spend"] = 1234.56
77
87
  intercom.users.save(user)
@@ -88,6 +98,14 @@ intercom.users.all.map {|user| user.email }
88
98
  intercom.users.find_all(type: 'users', page: 1, per_page: 10, created_since: 2, order: :asc).to_a.each_with_index {|usr, i| puts "#{i+1}: #{usr.name}"};
89
99
  # Paginate through your list of users choosing how many to return per page (default and max is 50 per page)
90
100
  intercom.users.find_all(type: 'users', page: 1, per_page: 10, order: :asc).to_a.each_with_index {|usr, i| puts "#{i+1}: #{usr.name}"}
101
+
102
+ # Duplicate users? If you have duplicate users you can search for them via their email address.
103
+ # Note this feature is only available from version 1.1 of the API so you will need to switch to that version
104
+ # This will return multiple users if they have the same email address
105
+ usrs = intercom.users.find_all(type: 'users', email: 'myemail@example.com', page: 1, per_page: 10, order: :asc)
106
+ # This returns a user.list so you can access it via
107
+ usrs.to_a.each_with_index {|usr, i| puts "#{i+1}: #{usr.id}"};
108
+
91
109
  # If you have over 10,000 users then you will need to use the scroll function to list your users
92
110
  # otherwise you will encounter a page limit with list all your users
93
111
  # You can use the scroll method to list all your users
@@ -100,16 +118,6 @@ result = intercom.users.scroll.next
100
118
  result.scroll_param
101
119
  => "0730e341-63ef-44da-ab9c-9113f886326d"
102
120
  result = intercom.users.scroll.next("0730e341-63ef-44da-ab9c-9113f886326d");
103
-
104
- #Bulk operations.
105
- # Submit bulk job to create users. If any of the items in create_items match an existing user that user will be updated
106
- intercom.users.submit_bulk_job(create_items: [{user_id: "25", email: "alice@example.com"}, {user_id: "25", email: "bob@example.com"}])
107
- # Submit bulk job to create users with companies. Companies must be sent as an array of objects nested within each applicable user object
108
- intercom.users.submit_bulk_job(create_items: [{user_id: "25", email: "alice@example.com", companies: [{company_id: 9, name: "Test Company"}]}])
109
- # Submit bulk job, to delete users
110
- intercom.users.submit_bulk_job(delete_items: [{user_id: "25", email: "alice@example.com"}, {user_id: "25", email: "bob@example.com"}])
111
- # Submit bulk job, to add items to existing job
112
- intercom.users.submit_bulk_job(create_items: [{user_id: "25", email: "alice@example.com"}], delete_items: [{user_id: "25", email: "bob@example.com"}], job_id:'job_abcd1234')
113
121
  ```
114
122
 
115
123
  #### Admins
@@ -122,6 +130,14 @@ intercom.admins.find(id: admin_id)
122
130
  intercom.admins.all.each {|admin| puts admin.email }
123
131
  ```
124
132
 
133
+ #### Teams
134
+ ```ruby
135
+ # Find a team by id
136
+ intercom.teams.find(id: team_id)
137
+ # Iterate over all teams
138
+ intercom.teams.all.each {|team| puts team.name }
139
+ ```
140
+
125
141
  #### Companies
126
142
  ```ruby
127
143
  # Add a user to one or more companies
@@ -143,8 +159,13 @@ intercom.companies.save(company)
143
159
  # Iterate over all companies
144
160
  intercom.companies.all.each {|company| puts %Q(#{company.name} - #{company.custom_attributes["referral_source"]}) }
145
161
  intercom.companies.all.map {|company| company.name }
146
- # Get a list of users in a company
147
- intercom.companies.users(company.id)
162
+ # Get a list of users in a company by Intercom Company ID
163
+ intercom.companies.users_by_intercom_company_id(company.id)
164
+ # Get a list of users in a company by external company_id
165
+ intercom.companies.users_by_company_id(company.company_id)
166
+ # Get a large list of companies using scroll
167
+ intercom.companies.scroll.each { |comp| puts comp.name}
168
+ # Please see users scroll for more details of how to use scroll
148
169
  ```
149
170
 
150
171
  #### Tags
@@ -157,7 +178,7 @@ intercom.tags.untag(name: 'blue', users: [{user_id: "42ea2f1b93891f6a99000427"}
157
178
  intercom.tags.all.each {|tag| "#{tag.id} - #{tag.name}" }
158
179
  intercom.tags.all.map {|tag| tag.name }
159
180
  # Tag companies
160
- tag = intercom.tags.tag(name: 'blue', companies: [{id: "42ea2f1b93891f6a99000427"}])
181
+ tag = intercom.tags.tag(name: 'blue', companies: [{company_id: "42ea2f1b93891f6a99000427"}])
161
182
  ```
162
183
 
163
184
  #### Segments
@@ -182,6 +203,9 @@ intercom.notes.find_all(user_id: '123').each {|note| puts note.body}
182
203
 
183
204
  #### Conversations
184
205
  ```ruby
206
+ # Iterate over all conversations for your app
207
+ intercom.conversations.all.each { |convo| ... }
208
+
185
209
  # FINDING CONVERSATIONS FOR AN ADMIN
186
210
  # Iterate over all conversations (open and closed) assigned to an admin
187
211
  intercom.conversations.find_all(type: 'admin', id: '7').each {|convo| ... }
@@ -189,7 +213,7 @@ intercom.conversations.find_all(type: 'admin', id: '7').each {|convo| ... }
189
213
  intercom.conversations.find_all(type: 'admin', id: 7, open: true).each {|convo| ... }
190
214
  # Iterate over closed conversations assigned to an admin
191
215
  intercom.conversations.find_all(type: 'admin', id: 7, open: false).each {|convo| ... }
192
- # Iterate over closed conversations for assigned an admin, before a certain moment in time
216
+ # Iterate over closed conversations which are assigned to an admin, and where updated_at is before a certain moment in time
193
217
  intercom.conversations.find_all(type: 'admin', id: 7, open: false, before: 1374844930).each {|convo| ... }
194
218
 
195
219
  # FINDING CONVERSATIONS FOR A USER
@@ -199,6 +223,11 @@ intercom.conversations.find_all(email: 'joe@example.com', type: 'user').each {|c
199
223
  intercom.conversations.find_all(email: 'joe@example.com', type: 'user', unread: false).each {|convo| ... }
200
224
  # Iterate over all unread conversations with a user based on the users email
201
225
  intercom.conversations.find_all(email: 'joe@example.com', type: 'user', unread: true).each {|convo| ... }
226
+ # Iterate over all conversations for a user with their Intercom user ID
227
+ intercom.conversations.find_all(intercom_user_id: '536e564f316c83104c000020', type: 'user').each {|convo| ... }
228
+ # Iterate over all conversations for a lead
229
+ # NOTE: to iterate over a lead's conversations you MUST use their Intercom User ID and type User
230
+ intercom.conversations.find_all(intercom_user_id: lead.id, type: 'user').each {|convo| ... }
202
231
 
203
232
  # FINDING A SINGLE CONVERSATION
204
233
  conversation = intercom.conversations.find(id: '1')
@@ -219,6 +248,9 @@ intercom.conversations.reply(id: conversation.id, type: 'admin', admin_id: '123'
219
248
  # User (identified by email) replies with a comment and attachment
220
249
  intercom.conversations.reply(id: conversation.id, type: 'user', email: 'joe@example.com', message_type: 'comment', body: 'foo', attachment_urls: ['http://www.example.com/attachment.jpg'])
221
250
 
251
+ #reply to a user's last conversation
252
+ intercom.conversations.reply_to_last(type: 'user', body: 'Thanks again', message_type: 'comment', user_id: '12345', admin_id: '123')
253
+
222
254
  # Open
223
255
  intercom.conversations.open(id: conversation.id, admin_id: '123')
224
256
 
@@ -226,14 +258,25 @@ intercom.conversations.open(id: conversation.id, admin_id: '123')
226
258
  intercom.conversations.close(id: conversation.id, admin_id: '123')
227
259
 
228
260
  # Assign
261
+ # Note: Conversations can be assigned to teams. However, the entity that performs the operation of assigning the conversation has to be an existing teammate.
262
+ # You can use `intercom.admins.all.each {|a| puts a.inspect if a.type == 'admin' }` to list all of your teammates.
229
263
  intercom.conversations.assign(id: conversation.id, admin_id: '123', assignee_id: '124')
230
264
 
265
+ # Snooze
266
+ intercom.conversations.snooze(id: conversation.id, admin_id: '123', snoozed_until: 9999999999)
267
+
231
268
  # Reply and Open
232
269
  intercom.conversations.reply(id: conversation.id, type: 'admin', admin_id: '123', message_type: 'open', body: 'bar')
233
270
 
234
271
  # Reply and Close
235
272
  intercom.conversations.reply(id: conversation.id, type: 'admin', admin_id: '123', message_type: 'close', body: 'bar')
236
273
 
274
+ # Admin reply to last conversation
275
+ intercom.conversations.reply_to_last(intercom_user_id: '5678', type: 'admin', admin_id: '123', message_type: 'comment', body: 'bar')
276
+
277
+ # User reply to last conversation
278
+ intercom.conversations.reply_to_last(intercom_user_id: '5678', type: 'user', message_type: 'comment', body: 'bar')
279
+
237
280
  # ASSIGNING CONVERSATIONS TO ADMINS
238
281
  intercom.conversations.reply(id: conversation.id, type: 'admin', assignee_id: assignee_admin.id, admin_id: admin.id, message_type: 'assignment')
239
282
 
@@ -327,6 +370,13 @@ intercom.events.create(
327
370
  }
328
371
  )
329
372
 
373
+ # Alternatively, use "user_id" in case your app allows multiple accounts having the same email
374
+ intercom.events.create(
375
+ event_name: "invited-friend",
376
+ created_at: Time.now.to_i,
377
+ user_id: user.uuid,
378
+ )
379
+
330
380
  # Retrieve event list for user with id:'123abc'
331
381
  intercom.events.find_all("type" => "user", "intercom_user_id" => "123abc")
332
382
 
@@ -362,77 +412,73 @@ The metadata key values in the example are treated as follows-
362
412
 
363
413
  *NB:* This version of the gem reserves the field name `type` in Event data.
364
414
 
365
- Bulk operations.
366
- ```ruby
367
- # Submit bulk job, to create events
368
- intercom.events.submit_bulk_job(create_items: [
369
- {
370
- event_name: "ordered-item",
371
- created_at: 1438944980,
372
- user_id: "314159",
373
- metadata: {
374
- order_date: 1438944980,
375
- stripe_invoice: "inv_3434343434"
376
- }
377
- },
378
- {
379
- event_name: "invited-friend",
380
- created_at: 1438944979,
381
- user_id: "314159",
382
- metadata: {
383
- invitee_email: "pi@example.org",
384
- invite_code: "ADDAFRIEND"
385
- }
386
- }
387
- ])
388
-
389
-
390
- # Submit bulk job, to add items to existing job
391
- intercom.events.submit_bulk_job(create_items: [
392
- {
393
- event_name: "ordered-item",
394
- created_at: 1438944980,
395
- user_id: "314159",
396
- metadata: {
397
- order_date: 1438944980,
398
- stripe_invoice: "inv_3434343434"
399
- }
400
- },
401
- {
402
- event_name: "invited-friend",
403
- created_at: 1438944979,
404
- user_id: "314159",
405
- metadata: {
406
- invitee_email: "pi@example.org",
407
- invite_code: "ADDAFRIEND"
408
- }
409
- }
410
- ], job_id:'job_abcd1234')
411
- ```
412
-
413
- ### Contacts
415
+ #### Contacts
414
416
 
415
417
  `Contacts` represent logged out users of your application.
418
+ Note that `contacts` are referred to as `leads` in the [Intercom](https://developers.intercom.com/intercom-api-reference/reference#leads)
416
419
 
417
420
  ```ruby
418
421
  # Create a contact
419
422
  contact = intercom.contacts.create(email: "some_contact@example.com")
420
423
 
421
- # Update a contact
424
+ # Update a contact (via create method)
425
+ # You can update a contact by calling the create method but you MUST provide an id or user_id
426
+ # If you just provide an email, for example, it will create a new contact
427
+ # See https://developers.intercom.com/intercom-api-reference/reference#update-lead for more detail
428
+ contact = intercom.contacts.create(email: "some_contact@example.com", id: "3be0398668071a6bc6850413", name:"update_contact")
429
+
430
+ # Update a contact (via contact object)
422
431
  contact.custom_attributes['foo'] = 'bar'
423
432
  intercom.contacts.save(contact)
424
433
 
425
434
  # Find contacts by email
426
435
  contacts = intercom.contacts.find_all(email: "some_contact@example.com")
427
436
 
437
+ # Using find to search for contacts by email
438
+ contact_list = intercom.contacts.find(email: "some_contact@example.com")
439
+ # This returns a Contact object with type contact.list
440
+ # Note: Multiple contacts can be returned in this list if there are multiple matching contacts found
441
+ # #<Intercom::Contact:0x00007ff3a80789f8
442
+ # @changed_fields=#<Set: {}>,
443
+ # @contacts=
444
+ # [{"type"=>"contact",
445
+ # "id"=>"5b7fd9b683681ac52274b9c7",
446
+ # "user_id"=>"05bc4d17-72cc-433e-88ae-0bf88db5d0e6",
447
+ # "anonymous"=>true,
448
+ # "email"=>"some_contact@example.com",
449
+ # ...}],
450
+ # @custom_attributes={},
451
+ # @limited=false,
452
+ # @pages=#<Intercom::Pages:0x00007ff3a7413c58 @changed_fields=#<Set: {}>, @next=nil, @page=1, @per_page=50, @total_pages=1, @type="pages">,
453
+ # @total_count=1,
454
+ # @type="contact.list">
455
+ # Access the contact's data
456
+ contact_list.contacts.first
457
+
428
458
  # Convert a contact into a user
429
- intercom.contacts.convert(contact, user)
459
+ contact = intercom.contacts.find(id: "536e564f316c83104c000020")
460
+ intercom.contacts.convert(contact, Intercom::User.new(email: email))
461
+ # Using find with email will not work here. See https://github.com/intercom/intercom-ruby/issues/419 for more information
462
+
463
+ # archive a contact
464
+ intercom.contacts.archive(contact)
430
465
 
431
- # Delete a contact
432
- intercom.contacts.delete(contact)
466
+ # Get a large list of contacts using scroll
467
+ intercom.contacts.scroll.each { |lead| puts lead.id}
468
+ # Please see users scroll for more details of how to use scroll
433
469
  ```
434
470
 
435
- ### Counts
471
+ #### Customers
472
+
473
+ Our Customer API is a central place for all the information on your customers, whether they're users or leads. More detail in our API documentation on [Customers](https://developers.intercom.com/intercom-api-reference/v0/reference#customers).
474
+
475
+ ```ruby
476
+ # Search for customers
477
+ customers = intercom.customers.search(query: { "field": "name", "operator": "=", "value": "Alice"}, per_page: 50, sort_field: "name", sort_order: "ascending")
478
+ customers.each { |customer| p customer.name }
479
+ ```
480
+
481
+ #### Counts
436
482
 
437
483
  ```ruby
438
484
  # App-wide counts
@@ -442,7 +488,7 @@ intercom.counts.for_app
442
488
  intercom.counts.for_type(type: 'user', count: 'segment')
443
489
  ```
444
490
 
445
- ### Subscriptions
491
+ #### Subscriptions
446
492
 
447
493
  Subscribe to events in Intercom to receive webhooks.
448
494
 
@@ -453,18 +499,13 @@ intercom.subscriptions.create(url: "http://example.com", topics: ["user.created"
453
499
  # fetch a subscription
454
500
  intercom.subscriptions.find(id: "nsub_123456789")
455
501
 
502
+ # delete a subscription
503
+ subscription = intercom.subscriptions.find(id: "nsub_123456789")
504
+ intercom.subscriptions.delete(subscription)
505
+
456
506
  # list subscriptions
457
507
  intercom.subscriptions.all
458
508
  ```
459
- ### Bulk jobs
460
-
461
- ```ruby
462
- # fetch a job
463
- intercom.jobs.find(id: 'job_abcd1234')
464
-
465
- # fetch a job's error feed
466
- intercom.jobs.errors(id: 'job_abcd1234')
467
- ```
468
509
 
469
510
  ### Errors
470
511
 
@@ -480,6 +521,7 @@ Intercom::ServerError
480
521
  Intercom::ServiceUnavailableError
481
522
  Intercom::ServiceConnectionError
482
523
  Intercom::ResourceNotFound
524
+ Intercom::BlockedUserError
483
525
  Intercom::BadRequestError
484
526
  Intercom::RateLimitExceeded
485
527
  Intercom::AttributeNotSetError # Raised when you try to call a getter that does not exist on an object
@@ -496,6 +538,12 @@ intercom.rate_limit_details
496
538
  #=> {:limit=>180, :remaining=>179, :reset_at=>2014-10-07 14:58:00 +0100}
497
539
  ```
498
540
 
541
+ You can handle the rate limits yourself but a simple option is to use the handle_rate_limit flag.
542
+ This will automatically catch the 429 rate limit exceeded error and wait until the reset time to retry. After three retries a rate limit exception will be raised. Encountering this error frequently may require a revisiting of your usage of the API.
543
+
544
+ ```
545
+ intercom = Intercom::Client.new(token: ENV['AT'], handle_rate_limit: true)
546
+ ```
499
547
 
500
548
  ### Pull Requests
501
549
 
@@ -512,3 +560,24 @@ intercom.rate_limit_details
512
560
  - **Send coherent history**. Make sure each individual commit in your pull
513
561
  request is meaningful. If you had to make multiple intermediate commits while
514
562
  developing, please squash them before sending them to us.
563
+
564
+ ### Development
565
+
566
+ #### Running tests
567
+
568
+ ```bash
569
+ # all tests
570
+ bundle exec spec
571
+
572
+ # unit tests
573
+ bundle exec spec:unit
574
+
575
+ # integration tests
576
+ bundle exec spec:integration
577
+
578
+ # single test file
579
+ bundle exec m spec/unit/intercom/job_spec.rb
580
+
581
+ # single test
582
+ bundle exec m spec/unit/intercom/job_spec.rb:49
583
+ ```