intercom 3.9.5 → 4.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +406 -236
- data/Rakefile +1 -1
- data/changes.txt +32 -0
- data/lib/intercom/api_operations/archive.rb +2 -1
- data/lib/intercom/api_operations/delete.rb +16 -0
- data/lib/intercom/api_operations/find.rb +5 -2
- data/lib/intercom/api_operations/find_all.rb +4 -3
- data/lib/intercom/api_operations/list.rb +4 -1
- data/lib/intercom/api_operations/load.rb +4 -2
- data/lib/intercom/api_operations/nested_resource.rb +70 -0
- data/lib/intercom/api_operations/save.rb +6 -4
- data/lib/intercom/api_operations/scroll.rb +4 -5
- data/lib/intercom/api_operations/search.rb +3 -2
- data/lib/intercom/article.rb +7 -0
- data/lib/intercom/base_collection_proxy.rb +73 -0
- data/lib/intercom/client.rb +36 -25
- data/lib/intercom/client_collection_proxy.rb +17 -39
- data/lib/intercom/collection.rb +7 -0
- data/lib/intercom/company.rb +8 -0
- data/lib/intercom/contact.rb +22 -3
- data/lib/intercom/conversation.rb +5 -0
- data/lib/intercom/data_attribute.rb +7 -0
- data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
- data/lib/intercom/deprecated_resources.rb +13 -0
- data/lib/intercom/errors.rb +3 -0
- data/lib/intercom/extended_api_operations/segments.rb +3 -1
- data/lib/intercom/extended_api_operations/tags.rb +3 -1
- data/lib/intercom/lead.rb +21 -0
- data/lib/intercom/lib/dynamic_accessors.rb +9 -10
- data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
- data/lib/intercom/note.rb +4 -0
- data/lib/intercom/request.rb +37 -33
- data/lib/intercom/scroll_collection_proxy.rb +38 -42
- data/lib/intercom/search_collection_proxy.rb +30 -65
- data/lib/intercom/section.rb +23 -0
- data/lib/intercom/segment.rb +4 -0
- data/lib/intercom/service/article.rb +20 -0
- data/lib/intercom/service/base_service.rb +7 -0
- data/lib/intercom/service/collection.rb +24 -0
- data/lib/intercom/service/company.rb +2 -12
- data/lib/intercom/service/contact.rb +31 -10
- data/lib/intercom/service/conversation.rb +12 -3
- data/lib/intercom/service/data_attribute.rb +20 -0
- data/lib/intercom/service/lead.rb +41 -0
- data/lib/intercom/service/note.rb +4 -8
- data/lib/intercom/service/section.rb +7 -0
- data/lib/intercom/service/subscription.rb +2 -2
- data/lib/intercom/service/tag.rb +9 -9
- data/lib/intercom/service/visitor.rb +17 -8
- data/lib/intercom/tag.rb +4 -0
- data/lib/intercom/traits/api_resource.rb +44 -18
- data/lib/intercom/traits/dirty_tracking.rb +8 -1
- data/lib/intercom/user.rb +12 -3
- data/lib/intercom/utils.rb +13 -2
- data/lib/intercom/version.rb +1 -1
- data/lib/intercom/visitor.rb +0 -2
- data/lib/intercom.rb +33 -22
- data/spec/spec_helper.rb +843 -520
- data/spec/unit/intercom/admin_spec.rb +2 -2
- data/spec/unit/intercom/article_spec.rb +40 -0
- data/spec/unit/intercom/base_collection_proxy_spec.rb +47 -0
- data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
- data/spec/unit/intercom/client_spec.rb +25 -26
- data/spec/unit/intercom/collection_spec.rb +32 -0
- data/spec/unit/intercom/company_spec.rb +18 -14
- data/spec/unit/intercom/contact_spec.rb +385 -33
- data/spec/unit/intercom/conversation_spec.rb +55 -7
- data/spec/unit/intercom/count_spec.rb +4 -4
- data/spec/unit/intercom/data_attribute_spec.rb +40 -0
- data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
- data/spec/unit/intercom/event_spec.rb +9 -11
- data/spec/unit/intercom/job_spec.rb +24 -24
- data/spec/unit/intercom/lead_spec.rb +57 -0
- data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
- data/spec/unit/intercom/message_spec.rb +1 -1
- data/spec/unit/intercom/note_spec.rb +4 -10
- data/spec/unit/intercom/request_spec.rb +1 -1
- data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
- data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
- data/spec/unit/intercom/section_spec.rb +32 -0
- data/spec/unit/intercom/segment_spec.rb +2 -2
- data/spec/unit/intercom/subscription_spec.rb +5 -6
- data/spec/unit/intercom/tag_spec.rb +22 -14
- data/spec/unit/intercom/team_spec.rb +2 -2
- data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
- data/spec/unit/intercom/user_spec.rb +224 -226
- data/spec/unit/intercom/visitor_spec.rb +49 -0
- data/spec/unit/intercom_spec.rb +5 -3
- metadata +34 -8
- data/lib/intercom/customer.rb +0 -10
- data/lib/intercom/service/customer.rb +0 -14
- data/spec/unit/intercom/visitors_spec.rb +0 -61
data/README.md
CHANGED
@@ -1,29 +1,44 @@
|
|
1
1
|
# intercom-ruby
|
2
2
|
|
3
|
-
|
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
|
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
|
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
|
-
|
33
|
+
```bash
|
34
|
+
gem install intercom
|
35
|
+
```
|
23
36
|
|
24
37
|
Using bundler:
|
25
38
|
|
26
|
-
|
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: '
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
-
####
|
89
|
+
#### Contacts
|
68
90
|
|
69
|
-
|
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
|
-
#
|
126
|
-
intercom.
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
-
####
|
167
|
+
#### Visitors
|
168
|
+
|
134
169
|
```ruby
|
135
|
-
#
|
136
|
-
intercom.
|
137
|
-
|
138
|
-
intercom.
|
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
|
-
|
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.
|
358
|
+
conversation.source.subject
|
359
|
+
|
238
360
|
# Get the part_type of the first part
|
239
|
-
conversation.conversation_parts
|
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
|
458
|
+
# Given a conversation with a partial contact, load the full contact. This can be
|
290
459
|
# done for any entity
|
291
|
-
intercom.
|
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
|
-
####
|
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
|
-
#
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
#
|
426
|
-
|
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
|
-
####
|
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
|
-
#
|
477
|
-
|
478
|
-
|
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
|