intercom 3.9.5 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +406 -236
  3. data/Rakefile +1 -1
  4. data/changes.txt +32 -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 +70 -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 +73 -0
  17. data/lib/intercom/client.rb +36 -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 +22 -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 +3 -0
  27. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  28. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  29. data/lib/intercom/lead.rb +21 -0
  30. data/lib/intercom/lib/dynamic_accessors.rb +9 -10
  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 +38 -42
  35. data/lib/intercom/search_collection_proxy.rb +30 -65
  36. data/lib/intercom/section.rb +23 -0
  37. data/lib/intercom/segment.rb +4 -0
  38. data/lib/intercom/service/article.rb +20 -0
  39. data/lib/intercom/service/base_service.rb +7 -0
  40. data/lib/intercom/service/collection.rb +24 -0
  41. data/lib/intercom/service/company.rb +2 -12
  42. data/lib/intercom/service/contact.rb +31 -10
  43. data/lib/intercom/service/conversation.rb +12 -3
  44. data/lib/intercom/service/data_attribute.rb +20 -0
  45. data/lib/intercom/service/lead.rb +41 -0
  46. data/lib/intercom/service/note.rb +4 -8
  47. data/lib/intercom/service/section.rb +7 -0
  48. data/lib/intercom/service/subscription.rb +2 -2
  49. data/lib/intercom/service/tag.rb +9 -9
  50. data/lib/intercom/service/visitor.rb +17 -8
  51. data/lib/intercom/tag.rb +4 -0
  52. data/lib/intercom/traits/api_resource.rb +44 -18
  53. data/lib/intercom/traits/dirty_tracking.rb +8 -1
  54. data/lib/intercom/user.rb +12 -3
  55. data/lib/intercom/utils.rb +13 -2
  56. data/lib/intercom/version.rb +1 -1
  57. data/lib/intercom/visitor.rb +0 -2
  58. data/lib/intercom.rb +33 -22
  59. data/spec/spec_helper.rb +843 -520
  60. data/spec/unit/intercom/admin_spec.rb +2 -2
  61. data/spec/unit/intercom/article_spec.rb +40 -0
  62. data/spec/unit/intercom/base_collection_proxy_spec.rb +47 -0
  63. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  64. data/spec/unit/intercom/client_spec.rb +25 -26
  65. data/spec/unit/intercom/collection_spec.rb +32 -0
  66. data/spec/unit/intercom/company_spec.rb +18 -14
  67. data/spec/unit/intercom/contact_spec.rb +385 -33
  68. data/spec/unit/intercom/conversation_spec.rb +55 -7
  69. data/spec/unit/intercom/count_spec.rb +4 -4
  70. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  71. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  72. data/spec/unit/intercom/event_spec.rb +9 -11
  73. data/spec/unit/intercom/job_spec.rb +24 -24
  74. data/spec/unit/intercom/lead_spec.rb +57 -0
  75. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  76. data/spec/unit/intercom/message_spec.rb +1 -1
  77. data/spec/unit/intercom/note_spec.rb +4 -10
  78. data/spec/unit/intercom/request_spec.rb +1 -1
  79. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  80. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  81. data/spec/unit/intercom/section_spec.rb +32 -0
  82. data/spec/unit/intercom/segment_spec.rb +2 -2
  83. data/spec/unit/intercom/subscription_spec.rb +5 -6
  84. data/spec/unit/intercom/tag_spec.rb +22 -14
  85. data/spec/unit/intercom/team_spec.rb +2 -2
  86. data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
  87. data/spec/unit/intercom/user_spec.rb +224 -226
  88. data/spec/unit/intercom/visitor_spec.rb +49 -0
  89. data/spec/unit/intercom_spec.rb +5 -3
  90. metadata +34 -8
  91. data/lib/intercom/customer.rb +0 -10
  92. data/lib/intercom/service/customer.rb +0 -14
  93. 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.2-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,160 +63,266 @@ 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
+ ```
64
86
 
65
87
  ### Examples
66
88
 
67
- #### Users
89
+ #### Contacts
68
90
 
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
- ```
91
+ 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
92
 
123
- #### Admins
124
93
  ```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 }
94
+ # Create a contact with "lead" role
95
+ contact = intercom.contacts.create(email: "some_contact2@example.com", role: "lead")
96
+
97
+ # Get a single contact using their intercom_id
98
+ intercom.contacts.find(id: contact.id)
99
+
100
+ # Update a contact
101
+ contact.name = "New name"
102
+ intercom.contacts.save(contact)
103
+
104
+ # Update a contact's role from "lead" to "user"
105
+ contact.role = "user"
106
+ intercom.contacts.save(contact)
107
+
108
+ # Archive a contact
109
+ intercom.contacts.archive(contact)
110
+
111
+ # Unarchive a contact
112
+ intercom.contacts.unarchive(contact)
113
+
114
+ # Delete a contact permanently
115
+ intercom.contacts.delete(contact)
116
+
117
+ # List all contacts
118
+ contacts = intercom.contacts.all
119
+ contacts.each { |contact| p contact.name }
120
+
121
+ # Search for contacts by email
122
+ contacts = intercom.contacts.search(
123
+ "query": {
124
+ "field": 'email',
125
+ "operator": '=',
126
+ "value": 'some_contact@example.com'
127
+ }
128
+ )
129
+ contacts.each {|c| p c.email}
130
+ # For full detail on possible queries, please refer to the API documentation:
131
+ # https://developers.intercom.com/intercom-api-reference/reference
132
+
133
+ # Merge a lead into an existing user
134
+ lead = intercom.contacts.create(email: "some_contact2@example.com", role: "lead")
135
+ intercom.contacts.merge(lead, intercom.contacts.find(id: "5db2e80ab1b92243d2188cfe"))
136
+
137
+ # Add a tag to a contact
138
+ tag = intercom.tags.find(id: "123")
139
+ contact.add_tag(id: tag.id)
140
+
141
+ # Remove a tag
142
+ contact.remove_tag(id: tag.id)
143
+
144
+ # List tags for a contact
145
+ contact.tags.each {|t| p t.name}
146
+
147
+ # Create a note on a contact
148
+ contact.create_note(body: "<p>Text for the note</p>")
149
+
150
+ # List notes for a contact
151
+ contact.notes.each {|n| p n.body}
152
+
153
+ # List segments for a contact
154
+ contact.segments.each {|segment| p segment.name}
155
+
156
+ # Add a contact to a company
157
+ company = intercom.companies.find(id: "123")
158
+ contact.add_company(id: company.id)
159
+
160
+ # Remove a contact from a company
161
+ contact.remove_company(id: company.id)
162
+
163
+ # List companies for a contact
164
+ contact.companies.each {|c| p c.name}
131
165
  ```
132
166
 
133
- #### Teams
167
+ #### Visitors
168
+
134
169
  ```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 }
170
+ # Get and update a visitor
171
+ visitor = intercom.visitors.find(id: "5dd570e7b1b922452676af23")
172
+ visitor.name = "New name"
173
+ intercom.visitors.save(visitor)
174
+
175
+ # Convert a visitor into a lead
176
+ intercom.visitors.convert(visitor)
177
+
178
+ # Convert a visitor into a user
179
+ user = intercom.contacts.find(id: "5db2e7f5b1b92243d2188cb3")
180
+ intercom.visitors.convert(visitor, user)
139
181
  ```
140
182
 
141
183
  #### Companies
184
+
142
185
  ```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
186
  # Find a company by company_id
151
187
  company = intercom.companies.find(company_id: "44")
188
+
152
189
  # Find a company by name
153
190
  company = intercom.companies.find(name: "Some company")
191
+
154
192
  # Find a company by id
155
193
  company = intercom.companies.find(id: "41e66f0313708347cb0000d0")
194
+
156
195
  # Update a company
157
196
  company.name = 'Updated company name'
158
197
  intercom.companies.save(company)
198
+
199
+ # Delete a company
200
+ intercom.companies.delete(company)
201
+
159
202
  # Iterate over all companies
160
203
  intercom.companies.all.each {|company| puts %Q(#{company.name} - #{company.custom_attributes["referral_source"]}) }
161
204
  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)
205
+
166
206
  # Get a large list of companies using scroll
167
207
  intercom.companies.scroll.each { |comp| puts comp.name}
168
208
  # Please see users scroll for more details of how to use scroll
169
209
  ```
170
210
 
211
+ #### Data Attributes
212
+
213
+ Data Attributes are a type of metadata used to describe your customer and company models. These include standard and custom attributes.
214
+
215
+ ```ruby
216
+ # Create a new custom data attribute
217
+ intercom.data_attributes.create({ name: "test_attribute", model: "contact", data_type: "string" })
218
+
219
+ # List all data attributes
220
+ attributes = intercom.data_attributes.all
221
+ attributes.each { |attribute| p attribute.name }
222
+
223
+ # Update an attribute
224
+ attribute = intercom.data_attributes.all.first
225
+ attribute.label = "New label"
226
+ intercom.data_attributes.save(attribute)
227
+
228
+ # Archive an attribute
229
+ attribute.archived = true
230
+ intercom.data_attributes.save(attribute)
231
+
232
+ # Find all customer attributes including archived
233
+ customer_attributes_incl_archived = intercom.data_attributes.find_all({"model": "contact", "include_archived": true})
234
+ customer_attributes_incl_archived.each { |attr| p attr.name }
235
+ ```
236
+
237
+ #### Events
238
+
239
+ ```ruby
240
+ intercom.events.create(
241
+ event_name: "invited-friend",
242
+ created_at: Time.now.to_i,
243
+ email: user.email,
244
+ metadata: {
245
+ "invitee_email" => "pi@example.org",
246
+ invite_code: "ADDAFRIEND",
247
+ "found_date" => 12909364407
248
+ }
249
+ )
250
+
251
+ # Alternatively, use "user_id" in case your app allows multiple accounts having the same email
252
+ intercom.events.create(
253
+ event_name: "invited-friend",
254
+ created_at: Time.now.to_i,
255
+ user_id: user.uuid,
256
+ )
257
+
258
+ # Retrieve event list for user with id:'123abc'
259
+ intercom.events.find_all("type" => "user", "intercom_user_id" => "123abc")
260
+ ```
261
+
262
+ Metadata Objects support a few simple types that Intercom can present on your behalf
263
+
264
+ ```ruby
265
+ intercom.events.create(
266
+ event_name: "placed-order",
267
+ email: current_user.email,
268
+ created_at: 1403001013,
269
+ metadata: {
270
+ order_date: Time.now.to_i,
271
+ stripe_invoice: 'inv_3434343434',
272
+ order_number: {
273
+ value: '3434-3434',
274
+ url: 'https://example.org/orders/3434-3434'
275
+ },
276
+ price: {
277
+ currency: 'usd',
278
+ amount: 2999
279
+ }
280
+ }
281
+ )
282
+ ```
283
+
284
+ The metadata key values in the example are treated as follows:
285
+
286
+ - order_date: a Date (key ends with '_date')
287
+ - stripe_invoice: The identifier of the Stripe invoice (has a 'stripe_invoice' key)
288
+ - order_number: a Rich Link (value contains 'url' and 'value' keys)
289
+ - price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)
290
+
291
+ *NB:* This version of the gem reserves the field name `type` in Event data.
292
+
171
293
  #### Tags
294
+
172
295
  ```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
296
  # Iterate over all tags
178
297
  intercom.tags.all.each {|tag| "#{tag.id} - #{tag.name}" }
179
298
  intercom.tags.all.map {|tag| tag.name }
299
+
180
300
  # Tag companies
181
301
  tag = intercom.tags.tag(name: 'blue', companies: [{company_id: "42ea2f1b93891f6a99000427"}])
302
+
303
+ # Untag Companies
304
+ tag = intercom.tags.untag(name: 'blue', companies: [{ company_id: "42ea2f1b93891f6a99000427" }])
305
+ ```
306
+
307
+ #### Notes
308
+
309
+ ```ruby
310
+ # Find a note by id
311
+ note = intercom.notes.find(id: "123")
182
312
  ```
183
313
 
184
314
  #### Segments
315
+
185
316
  ```ruby
186
317
  # Find a segment
187
318
  segment = intercom.segments.find(id: segment_id)
319
+
188
320
  # Iterate over all segments
189
321
  intercom.segments.all.each {|segment| puts "id: #{segment.id} name: #{segment.name}"}
190
322
  ```
191
323
 
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
324
  #### Conversations
325
+
205
326
  ```ruby
206
327
  # Iterate over all conversations for your app
207
328
  intercom.conversations.all.each { |convo| ... }
@@ -234,12 +355,21 @@ conversation = intercom.conversations.find(id: '1')
234
355
 
235
356
  # INTERACTING WITH THE PARTS OF A CONVERSATION
236
357
  # Getting the subject of a part (only applies to email-based conversations)
237
- conversation.rendered_message.subject
358
+ conversation.source.subject
359
+
238
360
  # Get the part_type of the first part
239
- conversation.conversation_parts[0].part_type
361
+ conversation.conversation_parts.first.part_type
362
+
240
363
  # Get the body of the second part
241
364
  conversation.conversation_parts[1].body
242
365
 
366
+ # Get statistics related to the conversation
367
+ conversation.statistics.time_to_admin_reply
368
+ conversation.statistics.last_assignment_at
369
+
370
+ # Get information on the sla applied to a conversation
371
+ conversation.sla_applied.sla_name
372
+
243
373
  # REPLYING TO CONVERSATIONS
244
374
  # User (identified by email) replies with a comment
245
375
  intercom.conversations.reply(id: conversation.id, type: 'user', email: 'joe@example.com', message_type: 'comment', body: 'foo')
@@ -282,16 +412,56 @@ intercom.conversations.reply(id: conversation.id, type: 'admin', assignee_id: as
282
412
 
283
413
  # MARKING A CONVERSATION AS READ
284
414
  intercom.conversations.mark_read(conversation.id)
415
+
416
+ # RUN ASSIGNMENT RULES
417
+ intercom.conversations.run_assignment_rules(conversation.id)
418
+
419
+ # Search for conversations
420
+ # For full detail on possible queries, please refer to the API documentation:
421
+ # https://developers.intercom.com/intercom-api-reference/reference
422
+
423
+ # Search for open conversations sorted by the created_at date
424
+ conversations = intercom.conversations.search(
425
+ query: {
426
+ field: "open",
427
+ operator: "=",
428
+ value: true
429
+ },
430
+ sort_field: "created_at",
431
+ sort_order: "descending"
432
+ )
433
+ conversations.each {|c| p c.id}
434
+
435
+ # Tagging for conversations
436
+ tag = intercom.tags.find(id: "2")
437
+ conversation = intercom.conversations.find(id: "1")
438
+
439
+ # An Admin ID is required to add or remove tag on a conversation
440
+ admin = intercom.admins.find(id: "1")
441
+
442
+ # Add a tag to a conversation
443
+ conversation.add_tag(id: tag.id, admin_id: admin.id)
444
+
445
+ # Remove a tag from a conversation
446
+ conversation.remove_tag(id: tag.id, admin_id: admin.id)
447
+
448
+ # Add a contact to a conversation
449
+ conversation.add_contact(admin_id: admin.id, customer: { intercom_user_id: contact.id })
450
+
451
+ # Remove a contact from a conversation
452
+ conversation.remove_contact(id: contact.id, admin_id: admin.id)
285
453
  ```
286
454
 
287
455
  #### Full loading of an embedded entity
456
+
288
457
  ```ruby
289
- # Given a conversation with a partial user, load the full user. This can be
458
+ # Given a conversation with a partial contact, load the full contact. This can be
290
459
  # done for any entity
291
- intercom.users.load(conversation.user)
460
+ intercom.contacts.load(conversation.contacts.first)
292
461
  ```
293
462
 
294
463
  #### Sending messages
464
+
295
465
  ```ruby
296
466
 
297
467
  # InApp message from admin to user
@@ -357,125 +527,24 @@ intercom.messages.create({
357
527
  })
358
528
  ```
359
529
 
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
-
383
- ```
384
-
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
- )
405
- ```
406
-
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)
530
+ #### Admins
419
531
 
420
532
  ```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
533
+ # Find access token owner (only with Personal Access Token and OAuth)
534
+ intercom.admins.me
535
+ # Find an admin by id
536
+ intercom.admins.find(id: admin_id)
537
+ # Iterate over all admins
538
+ intercom.admins.all.each {|admin| puts admin.email }
469
539
  ```
470
540
 
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).
541
+ #### Teams
474
542
 
475
543
  ```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 }
544
+ # Find a team by id
545
+ intercom.teams.find(id: team_id)
546
+ # Iterate over all teams
547
+ intercom.teams.all.each {|team| puts team.name }
479
548
  ```
480
549
 
481
550
  #### Counts
@@ -507,6 +576,106 @@ intercom.subscriptions.delete(subscription)
507
576
  intercom.subscriptions.all
508
577
  ```
509
578
 
579
+ #### Articles
580
+
581
+ ```ruby
582
+ # Create an article
583
+ article = intercom.articles.create(title: "New Article", author_id: "123456")
584
+
585
+ # Create an article with translations
586
+ article = intercom.articles.create(title: "New Article",
587
+ author_id: "123456",
588
+ translated_content: {fr: {title: "Nouvel Article"}, es: {title: "Nuevo artículo"}})
589
+
590
+ # Fetch an article
591
+ intercom.articles.find(id: "123456")
592
+
593
+ # List all articles
594
+ articles = intercom.articles.all
595
+ articles.each { |article| p article.title }
596
+
597
+ # Update an article
598
+ article.title = "Article Updated!"
599
+ intercom.articles.save(article)
600
+
601
+ # Update an article's existing translation
602
+ article.translated_content.en.title = "English Updated!"
603
+ intercom.articles.save(article)
604
+
605
+ # Update an article by adding a new translation
606
+ article.translated_content.es = {title: "Artículo en español"}
607
+ intercom.articles.save(article)
608
+
609
+ # Delete an article
610
+ intercom.articles.delete(article)
611
+ ```
612
+
613
+ #### Collections
614
+
615
+ ```ruby
616
+ # Create a collection
617
+ collection = intercom.collections.create(name: "New Collection")
618
+
619
+ # Create a collection with translations
620
+ collection = intercom.collections.create(name: "New Collection",
621
+ translated_content: {fr: {name: "Nouvelle collection"}, es: {name: "Nueva colección"}})
622
+
623
+ # Fetch a collection
624
+ intercom.collections.find(id: "123456")
625
+
626
+ # List all collections
627
+ collections = intercom.collections.all
628
+ collections.each { |collection| p collection.name }
629
+
630
+ # Update a collection
631
+ collection.name = "Collection updated!"
632
+ intercom.collections.save(collection)
633
+
634
+ # Update a collection's existing translation
635
+ collection.translated_content.en.name = "English Updated!"
636
+ intercom.collections.save(collection)
637
+
638
+ # Update a collection by adding a new translation
639
+ collection.translated_content.es = {name: "Colección en español", description: "Descripción en español"}
640
+ intercom.collections.save(collection)
641
+
642
+ # Delete an collection
643
+ intercom.collections.delete(collection)
644
+ ```
645
+
646
+ #### Sections
647
+
648
+ ```ruby
649
+ # Create a section
650
+ section = intercom.sections.create(name: "New Section", parent_id: "123456")
651
+
652
+ # Create a section with translations
653
+ section = intercom.sections.create(name: "New Section",
654
+ translated_content: {fr: {name: "Nouvelle section"}, es: {name: "Nueva sección"}})
655
+
656
+ # Fetch a section
657
+ intercom.sections.find(id: "123456")
658
+
659
+ # List all sections
660
+ sections = intercom.sections.all
661
+ sections.each { |section| p section.name }
662
+
663
+ # Update a section
664
+ section.name = "Section updated!"
665
+ intercom.sections.save(section)
666
+
667
+ # Update a section's existing translation
668
+ section.translated_content.en.name = "English Updated!"
669
+ intercom.collections.save(section)
670
+
671
+ # Update a section by adding a new translation
672
+ section.translated_content.es = {name: "Sección en español"}
673
+ intercom.collections.save(section)
674
+
675
+ # Delete an section
676
+ intercom.sections.delete(section)
677
+ ```
678
+
510
679
  ### Errors
511
680
 
512
681
  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 +696,7 @@ Intercom::RateLimitExceeded
527
696
  Intercom::AttributeNotSetError # Raised when you try to call a getter that does not exist on an object
528
697
  Intercom::MultipleMatchingUsersError
529
698
  Intercom::HttpError # Raised when response object is unexpectedly nil
699
+ Intercom::GatewayTimeoutError
530
700
  ```
531
701
 
532
702
  ### Rate Limiting
@@ -541,7 +711,7 @@ intercom.rate_limit_details
541
711
  You can handle the rate limits yourself but a simple option is to use the handle_rate_limit flag.
542
712
  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
713
 
544
- ```
714
+ ```ruby
545
715
  intercom = Intercom::Client.new(token: ENV['AT'], handle_rate_limit: true)
546
716
  ```
547
717
 
@@ -567,13 +737,13 @@ intercom = Intercom::Client.new(token: ENV['AT'], handle_rate_limit: true)
567
737
 
568
738
  ```bash
569
739
  # all tests
570
- bundle exec spec
740
+ bundle exec rake spec
571
741
 
572
742
  # unit tests
573
- bundle exec spec:unit
743
+ bundle exec rake spec:unit
574
744
 
575
745
  # integration tests
576
- bundle exec spec:integration
746
+ bundle exec rake spec:integration
577
747
 
578
748
  # single test file
579
749
  bundle exec m spec/unit/intercom/job_spec.rb