intercom 3.9.5 → 4.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +483 -234
  3. data/Rakefile +1 -1
  4. data/changes.txt +37 -0
  5. data/lib/intercom/api_operations/archive.rb +2 -1
  6. data/lib/intercom/api_operations/delete.rb +16 -0
  7. data/lib/intercom/api_operations/find.rb +5 -2
  8. data/lib/intercom/api_operations/find_all.rb +4 -3
  9. data/lib/intercom/api_operations/list.rb +4 -1
  10. data/lib/intercom/api_operations/load.rb +4 -2
  11. data/lib/intercom/api_operations/nested_resource.rb +68 -0
  12. data/lib/intercom/api_operations/save.rb +6 -4
  13. data/lib/intercom/api_operations/scroll.rb +4 -5
  14. data/lib/intercom/api_operations/search.rb +3 -2
  15. data/lib/intercom/article.rb +7 -0
  16. data/lib/intercom/base_collection_proxy.rb +74 -0
  17. data/lib/intercom/client.rb +48 -25
  18. data/lib/intercom/client_collection_proxy.rb +17 -39
  19. data/lib/intercom/collection.rb +7 -0
  20. data/lib/intercom/company.rb +8 -0
  21. data/lib/intercom/contact.rb +23 -3
  22. data/lib/intercom/conversation.rb +5 -0
  23. data/lib/intercom/data_attribute.rb +7 -0
  24. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  25. data/lib/intercom/deprecated_resources.rb +13 -0
  26. data/lib/intercom/errors.rb +6 -0
  27. data/lib/intercom/export_content.rb +7 -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/dynamic_accessors.rb +9 -10
  32. data/lib/intercom/lib/typed_json_deserializer.rb +45 -35
  33. data/lib/intercom/note.rb +4 -0
  34. data/lib/intercom/phone_call_redirect.rb +7 -0
  35. data/lib/intercom/request.rb +39 -33
  36. data/lib/intercom/scroll_collection_proxy.rb +38 -42
  37. data/lib/intercom/search_collection_proxy.rb +30 -65
  38. data/lib/intercom/section.rb +23 -0
  39. data/lib/intercom/segment.rb +4 -0
  40. data/lib/intercom/service/article.rb +20 -0
  41. data/lib/intercom/service/base_service.rb +7 -0
  42. data/lib/intercom/service/collection.rb +24 -0
  43. data/lib/intercom/service/company.rb +2 -12
  44. data/lib/intercom/service/contact.rb +35 -10
  45. data/lib/intercom/service/conversation.rb +16 -3
  46. data/lib/intercom/service/data_attribute.rb +20 -0
  47. data/lib/intercom/service/export_content.rb +30 -0
  48. data/lib/intercom/service/lead.rb +41 -0
  49. data/lib/intercom/service/note.rb +4 -8
  50. data/lib/intercom/service/phone_call_redirect.rb +15 -0
  51. data/lib/intercom/service/section.rb +7 -0
  52. data/lib/intercom/service/subscription.rb +2 -2
  53. data/lib/intercom/service/subscription_type.rb +18 -0
  54. data/lib/intercom/service/tag.rb +9 -9
  55. data/lib/intercom/service/visitor.rb +17 -8
  56. data/lib/intercom/subscription_type.rb +12 -0
  57. data/lib/intercom/tag.rb +4 -0
  58. data/lib/intercom/traits/api_resource.rb +44 -18
  59. data/lib/intercom/traits/dirty_tracking.rb +8 -1
  60. data/lib/intercom/user.rb +12 -3
  61. data/lib/intercom/utils.rb +19 -3
  62. data/lib/intercom/version.rb +1 -1
  63. data/lib/intercom/visitor.rb +0 -2
  64. data/lib/intercom.rb +39 -22
  65. data/spec/spec_helper.rb +843 -520
  66. data/spec/unit/intercom/admin_spec.rb +2 -2
  67. data/spec/unit/intercom/article_spec.rb +40 -0
  68. data/spec/unit/intercom/base_collection_proxy_spec.rb +52 -0
  69. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  70. data/spec/unit/intercom/client_spec.rb +25 -26
  71. data/spec/unit/intercom/collection_spec.rb +32 -0
  72. data/spec/unit/intercom/company_spec.rb +19 -15
  73. data/spec/unit/intercom/contact_spec.rb +402 -33
  74. data/spec/unit/intercom/conversation_spec.rb +60 -7
  75. data/spec/unit/intercom/count_spec.rb +4 -4
  76. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  77. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  78. data/spec/unit/intercom/event_spec.rb +16 -11
  79. data/spec/unit/intercom/export_content_spec.rb +28 -0
  80. data/spec/unit/intercom/job_spec.rb +24 -24
  81. data/spec/unit/intercom/lead_spec.rb +57 -0
  82. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  83. data/spec/unit/intercom/message_spec.rb +1 -1
  84. data/spec/unit/intercom/note_spec.rb +4 -10
  85. data/spec/unit/intercom/phone_call_redirect.rb +12 -0
  86. data/spec/unit/intercom/request_spec.rb +14 -1
  87. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  88. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  89. data/spec/unit/intercom/section_spec.rb +32 -0
  90. data/spec/unit/intercom/segment_spec.rb +2 -2
  91. data/spec/unit/intercom/subscription_spec.rb +5 -6
  92. data/spec/unit/intercom/tag_spec.rb +28 -14
  93. data/spec/unit/intercom/team_spec.rb +2 -2
  94. data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
  95. data/spec/unit/intercom/user_spec.rb +224 -226
  96. data/spec/unit/intercom/visitor_spec.rb +49 -0
  97. data/spec/unit/intercom_spec.rb +5 -3
  98. metadata +44 -8
  99. data/lib/intercom/customer.rb +0 -10
  100. data/lib/intercom/service/customer.rb +0 -14
  101. data/spec/unit/intercom/visitors_spec.rb +0 -61
data/README.md CHANGED
@@ -1,29 +1,44 @@
1
1
  # intercom-ruby
2
2
 
3
- Ruby bindings for the Intercom API (https://developers.intercom.io/reference).
3
+ [![Circle CI](https://circleci.com/gh/intercom/intercom-ruby.png?style=shield)](https://circleci.com/gh/intercom/intercom-ruby)
4
+ [![gem](https://img.shields.io/gem/v/intercom)](https://rubygems.org/gems/intercom)
5
+ ![Intercom API Version](https://img.shields.io/badge/Intercom%20API%20Version-2.6-blue)
6
+
7
+ > Ruby bindings for the [Intercom API](https://developers.intercom.io/reference).
8
+
9
+ ## Project Updates
10
+
11
+ ### Maintenance
12
+
13
+ We're currently building a new team to provide in-depth and dedicated SDK support.
14
+
15
+ In the meantime, we'll be operating on limited capacity, meaning all pull requests will be evaluated on a best effort basis and will be limited to critical issues.
16
+
17
+ We'll communicate all relevant updates as we build this new team and support strategy in the coming months.
4
18
 
5
19
  [API Documentation](https://developers.intercom.io/docs)
6
20
 
7
21
  [Gem Documentation](http://rubydoc.info/github/intercom/intercom-ruby/master/frames)
8
22
 
9
- For generating Intercom javascript script tags for Rails, please see https://github.com/intercom/intercom-rails.
23
+ For generating Intercom JavaScript script tags for Rails, please see [intercom/intercom-rails](https://github.com/intercom/intercom-rails)
10
24
 
11
25
  ## Upgrading information
12
26
 
13
- Version 3 of intercom-ruby is not backwards compatible with previous versions.
14
-
15
- Version 3 moves away from a global setup approach to the use of an Intercom Client.
27
+ Version 4 of intercom-ruby is not backwards compatible with previous versions. Please see our [migration guide](https://github.com/intercom/intercom-ruby/wiki/Migration-guide-for-v4) for full details of breaking changes.
16
28
 
17
29
  This version of the gem is compatible with `Ruby 2.1` and above.
18
30
 
19
31
  ## Installation
20
32
 
21
-
22
- gem install intercom
33
+ ```bash
34
+ gem install intercom
35
+ ```
23
36
 
24
37
  Using bundler:
25
38
 
26
- gem 'intercom', '~> 3.9.4'
39
+ ```bundler
40
+ gem 'intercom', '~> 4.1'
41
+ ```
27
42
 
28
43
  ## Basic Usage
29
44
 
@@ -38,7 +53,7 @@ intercom = Intercom::Client.new(token: 'my_token')
38
53
 
39
54
  ```ruby
40
55
  # With a versioned app:
41
- intercom = Intercom::Client.new(token: 'my_token', api_version: '1.0')
56
+ intercom = Intercom::Client.new(token: 'my_token', api_version: '2.2')
42
57
  ```
43
58
 
44
59
  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.
@@ -48,164 +63,303 @@ You can also use the [omniauth-intercom lib](https://github.com/intercom/omniaut
48
63
 
49
64
  Resources this API supports:
50
65
 
51
- https://api.intercom.io/users
52
- https://api.intercom.io/teams
53
- https://api.intercom.io/contacts
54
- https://api.intercom.io/companies
55
- https://api.intercom.io/counts
56
- https://api.intercom.io/tags
57
- https://api.intercom.io/notes
58
- https://api.intercom.io/segments
59
- https://api.intercom.io/events
60
- https://api.intercom.io/conversations
61
- https://api.intercom.io/messages
62
- https://api.intercom.io/subscriptions
63
- https://api.intercom.io/jobs
66
+ ```text
67
+ https://api.intercom.io/contacts
68
+ https://api.intercom.io/visitors
69
+ https://api.intercom.io/companies
70
+ https://api.intercom.io/data_attributes
71
+ https://api.intercom.io/events
72
+ https://api.intercom.io/tags
73
+ https://api.intercom.io/notes
74
+ https://api.intercom.io/segments
75
+ https://api.intercom.io/conversations
76
+ https://api.intercom.io/messages
77
+ https://api.intercom.io/admins
78
+ https://api.intercom.io/teams
79
+ https://api.intercom.io/counts
80
+ https://api.intercom.io/subscriptions
81
+ https://api.intercom.io/jobs
82
+ https://api.intercom.io/articles
83
+ https://api.intercom.io/help_center/collections
84
+ https://api.intercom.io/help_center/sections
85
+ https://api.intercom.io/phone_call_redirects
86
+ https://api.intercom.io/subscription_types
87
+ https://api.intercom.io/export/content/data
88
+ ```
64
89
 
65
90
  ### Examples
66
91
 
67
- #### Users
92
+ #### Contacts
68
93
 
69
- ```ruby
70
- # Find user by email
71
- user = intercom.users.find(email: "bob@example.com")
72
- # Find user by user_id
73
- user = intercom.users.find(user_id: "1")
74
- # Find user by id
75
- user = intercom.users.find(id: "1")
76
- # Create a user
77
- user = intercom.users.create(email: "bob@example.com", name: "Bob Smith", signed_up_at: Time.now.to_i)
78
- # archive a user
79
- user = intercom.users.find(id: "1")
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)
85
- # Update custom_attributes for a user
86
- user.custom_attributes["average_monthly_spend"] = 1234.56
87
- intercom.users.save(user)
88
- # Perform incrementing
89
- user.increment('karma')
90
- intercom.users.save(user)
91
- # Perform decrementing
92
- user.decrement('karma', 5)
93
- intercom.users.save(user)
94
- # Iterate over all users
95
- intercom.users.all.each {|user| puts %Q(#{user.email} - #{user.custom_attributes["average_monthly_spend"]}) }
96
- intercom.users.all.map {|user| user.email }
97
- # List your users create in the last two days
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}"};
99
- # Paginate through your list of users choosing how many to return per page (default and max is 50 per page)
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
-
109
- # If you have over 10,000 users then you will need to use the scroll function to list your users
110
- # otherwise you will encounter a page limit with list all your users
111
- # You can use the scroll method to list all your users
112
- intercom.users.scroll.each { |user| puts user.name}
113
- # Alternatively you can use the scroll.next method to get 100 users with each request
114
- result = intercom.users.scroll.next
115
- # The result object then contains a records attributes that is an array of your user objects and it also contains a scroll_param which
116
- # you can then use to request the next 100 users. Note that the scroll parameter will time out after one minute and you will need to
117
- # make a new request
118
- result.scroll_param
119
- => "0730e341-63ef-44da-ab9c-9113f886326d"
120
- result = intercom.users.scroll.next("0730e341-63ef-44da-ab9c-9113f886326d");
121
- ```
94
+ Note that this is a new resource compatible only with the new [Contacts API](https://developers.intercom.com/intercom-api-reference/reference#contacts-model) released in API v2.0.
122
95
 
123
- #### Admins
124
96
  ```ruby
125
- # Find access token owner (only with Personal Access Token and OAuth)
126
- intercom.admins.me
127
- # Find an admin by id
128
- intercom.admins.find(id: admin_id)
129
- # Iterate over all admins
130
- intercom.admins.all.each {|admin| puts admin.email }
97
+ # Create a contact with "lead" role
98
+ contact = intercom.contacts.create(email: "some_contact2@example.com", role: "lead")
99
+
100
+ # Get a single contact using their intercom_id
101
+ intercom.contacts.find(id: contact.id)
102
+
103
+ # Update a contact
104
+ contact.name = "New name"
105
+ intercom.contacts.save(contact)
106
+
107
+ # Update a contact's role from "lead" to "user"
108
+ contact.role = "user"
109
+ intercom.contacts.save(contact)
110
+
111
+ # Archive a contact
112
+ intercom.contacts.archive(contact)
113
+
114
+ # Unarchive a contact
115
+ intercom.contacts.unarchive(contact)
116
+
117
+ # Delete a contact permanently
118
+ intercom.contacts.delete(contact)
119
+
120
+ # Deletes an archived contact permanently
121
+ intercom.contacts.delete_archived_contact(contact.id)
122
+
123
+ # List all contacts
124
+ contacts = intercom.contacts.all
125
+ contacts.each { |contact| p contact.name }
126
+
127
+ # Search for contacts by email
128
+ contacts = intercom.contacts.search(
129
+ "query": {
130
+ "field": 'email',
131
+ "operator": '=',
132
+ "value": 'some_contact@example.com'
133
+ }
134
+ )
135
+ contacts.each {|c| p c.email}
136
+ # For full detail on possible queries, please refer to the API documentation:
137
+ # https://developers.intercom.com/intercom-api-reference/reference
138
+
139
+ # Merge a lead into an existing user
140
+ lead = intercom.contacts.create(email: "some_contact2@example.com", role: "lead")
141
+ intercom.contacts.merge(lead, intercom.contacts.find(id: "5db2e80ab1b92243d2188cfe"))
142
+
143
+ # Add a tag to a contact
144
+ tag = intercom.tags.find(id: "123")
145
+ contact.add_tag(id: tag.id)
146
+
147
+ # Remove a tag
148
+ contact.remove_tag(id: tag.id)
149
+
150
+ # List tags for a contact
151
+ contact.tags.each {|t| p t.name}
152
+
153
+ # Create a note on a contact
154
+ contact.create_note(body: "<p>Text for the note</p>")
155
+
156
+ # List notes for a contact
157
+ contact.notes.each {|n| p n.body}
158
+
159
+ # List segments for a contact
160
+ contact.segments.each {|segment| p segment.name}
161
+
162
+ # Add a contact to a company
163
+ company = intercom.companies.find(id: "123")
164
+ contact.add_company(id: company.id)
165
+
166
+ # Remove a contact from a company
167
+ contact.remove_company(id: company.id)
168
+
169
+ # List companies for a contact
170
+ contact.companies.each {|c| p c.name}
171
+
172
+ # attach a subscription_types on a contact
173
+ contact.create_subscription_types(id: subscription_type.id)
174
+
175
+ # List subscription_types for a contact
176
+ contact.subscription_types.each {|n| p n.id}
177
+
178
+ # Remove subscription_types
179
+ contact.remove_subscription_type({ "id": subscription_type.id })
180
+
131
181
  ```
132
182
 
133
- #### Teams
183
+ #### Visitors
184
+
134
185
  ```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 }
186
+ # Get and update a visitor
187
+ visitor = intercom.visitors.find(id: "5dd570e7b1b922452676af23")
188
+ visitor.name = "New name"
189
+ intercom.visitors.save(visitor)
190
+
191
+ # Convert a visitor into a lead
192
+ intercom.visitors.convert(visitor)
193
+
194
+ # Convert a visitor into a user
195
+ user = intercom.contacts.find(id: "5db2e7f5b1b92243d2188cb3")
196
+ intercom.visitors.convert(visitor, user)
139
197
  ```
140
198
 
141
199
  #### Companies
200
+
142
201
  ```ruby
143
- # Add a user to one or more companies
144
- user = intercom.users.find(email: "bob@example.com")
145
- user.companies = [{company_id: 6, name: "Intercom"}, {company_id: 9, name: "Test Company"}]
146
- intercom.users.save(user)
147
- # You can also pass custom attributes within a company as you do this
148
- user.companies = [{id: 6, name: "Intercom", custom_attributes: {referral_source: "Google"} } ]
149
- intercom.users.save(user)
150
202
  # Find a company by company_id
151
203
  company = intercom.companies.find(company_id: "44")
204
+
152
205
  # Find a company by name
153
206
  company = intercom.companies.find(name: "Some company")
207
+
154
208
  # Find a company by id
155
209
  company = intercom.companies.find(id: "41e66f0313708347cb0000d0")
210
+
156
211
  # Update a company
157
212
  company.name = 'Updated company name'
158
213
  intercom.companies.save(company)
214
+
215
+ # Delete a company
216
+ intercom.companies.delete(company)
217
+
159
218
  # Iterate over all companies
160
219
  intercom.companies.all.each {|company| puts %Q(#{company.name} - #{company.custom_attributes["referral_source"]}) }
161
220
  intercom.companies.all.map {|company| company.name }
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)
221
+
166
222
  # Get a large list of companies using scroll
167
223
  intercom.companies.scroll.each { |comp| puts comp.name}
168
224
  # Please see users scroll for more details of how to use scroll
169
225
  ```
170
226
 
227
+ #### Data Attributes
228
+
229
+ Data Attributes are a type of metadata used to describe your customer and company models. These include standard and custom attributes.
230
+
231
+ ```ruby
232
+ # Create a new custom data attribute
233
+ intercom.data_attributes.create({ name: "test_attribute", model: "contact", data_type: "string" })
234
+
235
+ # List all data attributes
236
+ attributes = intercom.data_attributes.all
237
+ attributes.each { |attribute| p attribute.name }
238
+
239
+ # Update an attribute
240
+ attribute = intercom.data_attributes.all.first
241
+ attribute.label = "New label"
242
+ intercom.data_attributes.save(attribute)
243
+
244
+ # Archive an attribute
245
+ attribute.archived = true
246
+ intercom.data_attributes.save(attribute)
247
+
248
+ # Find all customer attributes including archived
249
+ customer_attributes_incl_archived = intercom.data_attributes.find_all({"model": "contact", "include_archived": true})
250
+ customer_attributes_incl_archived.each { |attr| p attr.name }
251
+ ```
252
+
253
+ #### Events
254
+
255
+ ```ruby
256
+ intercom.events.create(
257
+ event_name: "invited-friend",
258
+ created_at: Time.now.to_i,
259
+ email: user.email,
260
+ metadata: {
261
+ "invitee_email" => "pi@example.org",
262
+ invite_code: "ADDAFRIEND",
263
+ "found_date" => 12909364407
264
+ }
265
+ )
266
+
267
+ # Alternatively, use "user_id" in case your app allows multiple accounts having the same email
268
+ intercom.events.create(
269
+ event_name: "invited-friend",
270
+ created_at: Time.now.to_i,
271
+ user_id: user.uuid,
272
+ )
273
+
274
+ # Retrieve event list for user with id:'123abc'
275
+ intercom.events.find_all("type" => "user", "intercom_user_id" => "123abc")
276
+
277
+ # Retrieve the event summary for user with id: 'abc' this will return an event object with the following characteristics:
278
+ # name - name of the event
279
+ # first - time when event first occured.
280
+ # last - time when event last occured
281
+ # count - number of times the event occured
282
+ # description - description of the event
283
+ events = intercom.events.find_all(type: 'user',intercom_user_id: 'abc',summary: true)
284
+ ```
285
+
286
+ Metadata Objects support a few simple types that Intercom can present on your behalf
287
+
288
+ ```ruby
289
+ intercom.events.create(
290
+ event_name: "placed-order",
291
+ email: current_user.email,
292
+ created_at: 1403001013,
293
+ metadata: {
294
+ order_date: Time.now.to_i,
295
+ stripe_invoice: 'inv_3434343434',
296
+ order_number: {
297
+ value: '3434-3434',
298
+ url: 'https://example.org/orders/3434-3434'
299
+ },
300
+ price: {
301
+ currency: 'usd',
302
+ amount: 2999
303
+ }
304
+ }
305
+ )
306
+ ```
307
+
308
+ The metadata key values in the example are treated as follows:
309
+
310
+ - order_date: a Date (key ends with '_date')
311
+ - stripe_invoice: The identifier of the Stripe invoice (has a 'stripe_invoice' key)
312
+ - order_number: a Rich Link (value contains 'url' and 'value' keys)
313
+ - price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)
314
+
315
+ *NB:* This version of the gem reserves the field name `type` in Event data.
316
+
171
317
  #### Tags
318
+
172
319
  ```ruby
173
- # Tag users
174
- tag = intercom.tags.tag(name: 'blue', users: [{email: "test1@example.com"}])
175
- # Untag users
176
- intercom.tags.untag(name: 'blue', users: [{user_id: "42ea2f1b93891f6a99000427"}])
177
320
  # Iterate over all tags
178
321
  intercom.tags.all.each {|tag| "#{tag.id} - #{tag.name}" }
179
322
  intercom.tags.all.map {|tag| tag.name }
323
+
180
324
  # Tag companies
181
325
  tag = intercom.tags.tag(name: 'blue', companies: [{company_id: "42ea2f1b93891f6a99000427"}])
326
+
327
+ # Untag Companies
328
+ tag = intercom.tags.untag(name: 'blue', companies: [{ company_id: "42ea2f1b93891f6a99000427" }])
329
+
330
+
331
+ # Delete Tags
332
+
333
+ # Note : If there any depedent objects for the tag we are trying to delete, then an error TagHasDependentObjects will be thrown.
334
+ tag = intercom.tags.find(id:"123")
335
+ intercom.tags.delete(tag)
336
+ ```
337
+
338
+ #### Notes
339
+
340
+ ```ruby
341
+ # Find a note by id
342
+ note = intercom.notes.find(id: "123")
182
343
  ```
183
344
 
184
345
  #### Segments
346
+
185
347
  ```ruby
186
348
  # Find a segment
187
349
  segment = intercom.segments.find(id: segment_id)
350
+
188
351
  # Iterate over all segments
189
352
  intercom.segments.all.each {|segment| puts "id: #{segment.id} name: #{segment.name}"}
190
353
  ```
191
354
 
192
- #### Notes
193
- ```ruby
194
- # Find a note by id
195
- note = intercom.notes.find(id: note)
196
- # Create a note for a user
197
- note = intercom.notes.create(body: "<p>Text for the note</p>", email: 'joe@example.com')
198
- # Iterate over all notes for a user via their email address
199
- intercom.notes.find_all(email: 'joe@example.com').each {|note| puts note.body}
200
- # Iterate over all notes for a user via their user_id
201
- intercom.notes.find_all(user_id: '123').each {|note| puts note.body}
202
- ```
203
-
204
355
  #### Conversations
356
+
205
357
  ```ruby
206
358
  # Iterate over all conversations for your app
207
359
  intercom.conversations.all.each { |convo| ... }
208
360
 
361
+ # The below method of finding conversations by using the find_all method work only for API versions 2.5 and below
362
+
209
363
  # FINDING CONVERSATIONS FOR AN ADMIN
210
364
  # Iterate over all conversations (open and closed) assigned to an admin
211
365
  intercom.conversations.find_all(type: 'admin', id: '7').each {|convo| ... }
@@ -234,12 +388,21 @@ conversation = intercom.conversations.find(id: '1')
234
388
 
235
389
  # INTERACTING WITH THE PARTS OF A CONVERSATION
236
390
  # Getting the subject of a part (only applies to email-based conversations)
237
- conversation.rendered_message.subject
391
+ conversation.source.subject
392
+
238
393
  # Get the part_type of the first part
239
- conversation.conversation_parts[0].part_type
394
+ conversation.conversation_parts.first.part_type
395
+
240
396
  # Get the body of the second part
241
397
  conversation.conversation_parts[1].body
242
398
 
399
+ # Get statistics related to the conversation
400
+ conversation.statistics.time_to_admin_reply
401
+ conversation.statistics.last_assignment_at
402
+
403
+ # Get information on the sla applied to a conversation
404
+ conversation.sla_applied.sla_name
405
+
243
406
  # REPLYING TO CONVERSATIONS
244
407
  # User (identified by email) replies with a comment
245
408
  intercom.conversations.reply(id: conversation.id, type: 'user', email: 'joe@example.com', message_type: 'comment', body: 'foo')
@@ -282,16 +445,56 @@ intercom.conversations.reply(id: conversation.id, type: 'admin', assignee_id: as
282
445
 
283
446
  # MARKING A CONVERSATION AS READ
284
447
  intercom.conversations.mark_read(conversation.id)
448
+
449
+ # RUN ASSIGNMENT RULES
450
+ intercom.conversations.run_assignment_rules(conversation.id)
451
+
452
+ # Search for conversations
453
+ # For full detail on possible queries, please refer to the API documentation:
454
+ # https://developers.intercom.com/intercom-api-reference/reference
455
+
456
+ # Search for open conversations sorted by the created_at date
457
+ conversations = intercom.conversations.search(
458
+ query: {
459
+ field: "open",
460
+ operator: "=",
461
+ value: true
462
+ },
463
+ sort_field: "created_at",
464
+ sort_order: "descending"
465
+ )
466
+ conversations.each {|c| p c.id}
467
+
468
+ # Tagging for conversations
469
+ tag = intercom.tags.find(id: "2")
470
+ conversation = intercom.conversations.find(id: "1")
471
+
472
+ # An Admin ID is required to add or remove tag on a conversation
473
+ admin = intercom.admins.find(id: "1")
474
+
475
+ # Add a tag to a conversation
476
+ conversation.add_tag(id: tag.id, admin_id: admin.id)
477
+
478
+ # Remove a tag from a conversation
479
+ conversation.remove_tag(id: tag.id, admin_id: admin.id)
480
+
481
+ # Add a contact to a conversation
482
+ conversation.add_contact(admin_id: admin.id, customer: { intercom_user_id: contact.id })
483
+
484
+ # Remove a contact from a conversation
485
+ conversation.remove_contact(id: contact.id, admin_id: admin.id)
285
486
  ```
286
487
 
287
488
  #### Full loading of an embedded entity
489
+
288
490
  ```ruby
289
- # Given a conversation with a partial user, load the full user. This can be
491
+ # Given a conversation with a partial contact, load the full contact. This can be
290
492
  # done for any entity
291
- intercom.users.load(conversation.user)
493
+ intercom.contacts.load(conversation.contacts.first)
292
494
  ```
293
495
 
294
496
  #### Sending messages
497
+
295
498
  ```ruby
296
499
 
297
500
  # InApp message from admin to user
@@ -355,127 +558,36 @@ intercom.messages.create({
355
558
  },
356
559
  body: "halp"
357
560
  })
358
- ```
359
-
360
- #### Events
361
- ```ruby
362
- intercom.events.create(
363
- event_name: "invited-friend",
364
- created_at: Time.now.to_i,
365
- email: user.email,
366
- metadata: {
367
- "invitee_email" => "pi@example.org",
368
- invite_code: "ADDAFRIEND",
369
- "found_date" => 12909364407
370
- }
371
- )
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
-
380
- # Retrieve event list for user with id:'123abc'
381
- intercom.events.find_all("type" => "user", "intercom_user_id" => "123abc")
382
561
 
383
- ```
562
+ #From version 2.6 the type contact is not supported and you would have to use leads to send messages to a lead.
384
563
 
385
- Metadata Objects support a few simple types that Intercom can present on your behalf
386
-
387
- ```ruby
388
- intercom.events.create(
389
- event_name: "placed-order",
390
- email: current_user.email,
391
- created_at: 1403001013,
392
- metadata: {
393
- order_date: Time.now.to_i,
394
- stripe_invoice: 'inv_3434343434',
395
- order_number: {
396
- value: '3434-3434',
397
- url: 'https://example.org/orders/3434-3434'
398
- },
399
- price: {
400
- currency: 'usd',
401
- amount: 2999
402
- }
403
- }
404
- )
564
+ intercom.messages.create({
565
+ from: {
566
+ type: "lead",
567
+ id: "536e5643as316c83104c400671"
568
+ },
569
+ body: "halp"
570
+ })
405
571
  ```
406
572
 
407
- The metadata key values in the example are treated as follows-
408
- - order_date: a Date (key ends with '_date')
409
- - stripe_invoice: The identifier of the Stripe invoice (has a 'stripe_invoice' key)
410
- - order_number: a Rich Link (value contains 'url' and 'value' keys)
411
- - price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)
412
-
413
- *NB:* This version of the gem reserves the field name `type` in Event data.
414
-
415
- #### Contacts
416
-
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)
573
+ #### Admins
419
574
 
420
575
  ```ruby
421
- # Create a contact
422
- contact = intercom.contacts.create(email: "some_contact@example.com")
423
-
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)
431
- contact.custom_attributes['foo'] = 'bar'
432
- intercom.contacts.save(contact)
433
-
434
- # Find contacts by email
435
- contacts = intercom.contacts.find_all(email: "some_contact@example.com")
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
-
458
- # Convert a contact into a 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)
465
-
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
576
+ # Find access token owner (only with Personal Access Token and OAuth)
577
+ intercom.admins.me
578
+ # Find an admin by id
579
+ intercom.admins.find(id: admin_id)
580
+ # Iterate over all admins
581
+ intercom.admins.all.each {|admin| puts admin.email }
469
582
  ```
470
583
 
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).
584
+ #### Teams
474
585
 
475
586
  ```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 }
587
+ # Find a team by id
588
+ intercom.teams.find(id: team_id)
589
+ # Iterate over all teams
590
+ intercom.teams.all.each {|team| puts team.name }
479
591
  ```
480
592
 
481
593
  #### Counts
@@ -507,6 +619,142 @@ intercom.subscriptions.delete(subscription)
507
619
  intercom.subscriptions.all
508
620
  ```
509
621
 
622
+
623
+ #### Subscription Types
624
+
625
+ List all the subscription types that a contact can opt in to
626
+
627
+ ```ruby
628
+
629
+ # fetch a subscription
630
+ intercom.subscription_types.find(id: "1")
631
+
632
+ intercom.subscription_types.all
633
+ ```
634
+
635
+ #### Articles
636
+
637
+ ```ruby
638
+ # Create an article
639
+ article = intercom.articles.create(title: "New Article", author_id: "123456")
640
+
641
+ # Create an article with translations
642
+ article = intercom.articles.create(title: "New Article",
643
+ author_id: "123456",
644
+ translated_content: {fr: {title: "Nouvel Article"}, es: {title: "Nuevo artículo"}})
645
+
646
+ # Fetch an article
647
+ intercom.articles.find(id: "123456")
648
+
649
+ # List all articles
650
+ articles = intercom.articles.all
651
+ articles.each { |article| p article.title }
652
+
653
+ # Update an article
654
+ article.title = "Article Updated!"
655
+ intercom.articles.save(article)
656
+
657
+ # Update an article's existing translation
658
+ article.translated_content.en.title = "English Updated!"
659
+ intercom.articles.save(article)
660
+
661
+ # Update an article by adding a new translation
662
+ article.translated_content.es = {title: "Artículo en español"}
663
+ intercom.articles.save(article)
664
+
665
+ # Delete an article
666
+ intercom.articles.delete(article)
667
+ ```
668
+
669
+ #### Collections
670
+
671
+ ```ruby
672
+ # Create a collection
673
+ collection = intercom.collections.create(name: "New Collection")
674
+
675
+ # Create a collection with translations
676
+ collection = intercom.collections.create(name: "New Collection",
677
+ translated_content: {fr: {name: "Nouvelle collection"}, es: {name: "Nueva colección"}})
678
+
679
+ # Fetch a collection
680
+ intercom.collections.find(id: "123456")
681
+
682
+ # List all collections
683
+ collections = intercom.collections.all
684
+ collections.each { |collection| p collection.name }
685
+
686
+ # Update a collection
687
+ collection.name = "Collection updated!"
688
+ intercom.collections.save(collection)
689
+
690
+ # Update a collection's existing translation
691
+ collection.translated_content.en.name = "English Updated!"
692
+ intercom.collections.save(collection)
693
+
694
+ # Update a collection by adding a new translation
695
+ collection.translated_content.es = {name: "Colección en español", description: "Descripción en español"}
696
+ intercom.collections.save(collection)
697
+
698
+ # Delete an collection
699
+ intercom.collections.delete(collection)
700
+ ```
701
+
702
+ #### Sections
703
+
704
+ ```ruby
705
+ # Create a section
706
+ section = intercom.sections.create(name: "New Section", parent_id: "123456")
707
+
708
+ # Create a section with translations
709
+ section = intercom.sections.create(name: "New Section",
710
+ translated_content: {fr: {name: "Nouvelle section"}, es: {name: "Nueva sección"}})
711
+
712
+ # Fetch a section
713
+ intercom.sections.find(id: "123456")
714
+
715
+ # List all sections
716
+ sections = intercom.sections.all
717
+ sections.each { |section| p section.name }
718
+
719
+ # Update a section
720
+ section.name = "Section updated!"
721
+ intercom.sections.save(section)
722
+
723
+ # Update a section's existing translation
724
+ section.translated_content.en.name = "English Updated!"
725
+ intercom.collections.save(section)
726
+
727
+ # Update a section by adding a new translation
728
+ section.translated_content.es = {name: "Sección en español"}
729
+ intercom.collections.save(section)
730
+
731
+ # Delete an section
732
+ intercom.sections.delete(section)
733
+ ```
734
+
735
+ #### Phone Call Redirect (switch)
736
+
737
+ ```ruby
738
+ # Create a redirect
739
+ redirect = intercom.phone_call_redirect.create(phone_number: "+353871234567")
740
+
741
+ ```
742
+
743
+ #### Data Content Export
744
+
745
+ ```ruby
746
+ # Create a data export
747
+ export = intercom.export_content.create(created_at_after: 1667566801, created_at_before: 1668085202)
748
+
749
+
750
+ #View a data export
751
+ export = intercom.export_content.find(id: 'k0e27ohsyvh8ef3m')
752
+
753
+ # Cancel a data export
754
+ export = intercom.export_content.cancel('k0e27ohsyvh8ef3m')
755
+
756
+ ```
757
+
510
758
  ### Errors
511
759
 
512
760
  There are different styles for error handling - some people prefer exceptions; some prefer nil and check; some prefer error objects/codes. Balancing these preferences alongside our wish to provide an idiomatic gem has brought us to use the current mechanism of throwing specific exceptions. Our approach in the client is to propagate errors and signal our failure loudly so that erroneous data does not get propagated through our customers' systems - in other words, if you see a `Intercom::ServiceUnavailableError` you know where the problem is.
@@ -527,6 +775,7 @@ Intercom::RateLimitExceeded
527
775
  Intercom::AttributeNotSetError # Raised when you try to call a getter that does not exist on an object
528
776
  Intercom::MultipleMatchingUsersError
529
777
  Intercom::HttpError # Raised when response object is unexpectedly nil
778
+ Intercom::GatewayTimeoutError
530
779
  ```
531
780
 
532
781
  ### Rate Limiting
@@ -541,7 +790,7 @@ intercom.rate_limit_details
541
790
  You can handle the rate limits yourself but a simple option is to use the handle_rate_limit flag.
542
791
  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
792
 
544
- ```
793
+ ```ruby
545
794
  intercom = Intercom::Client.new(token: ENV['AT'], handle_rate_limit: true)
546
795
  ```
547
796
 
@@ -567,13 +816,13 @@ intercom = Intercom::Client.new(token: ENV['AT'], handle_rate_limit: true)
567
816
 
568
817
  ```bash
569
818
  # all tests
570
- bundle exec spec
819
+ bundle exec rake spec
571
820
 
572
821
  # unit tests
573
- bundle exec spec:unit
822
+ bundle exec rake spec:unit
574
823
 
575
824
  # integration tests
576
- bundle exec spec:integration
825
+ bundle exec rake spec:integration
577
826
 
578
827
  # single test file
579
828
  bundle exec m spec/unit/intercom/job_spec.rb