intercom 3.5.10 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.circleci/config.yml +35 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +5 -0
- data/Gemfile +1 -4
- data/README.md +418 -216
- data/RELEASING.md +9 -0
- data/Rakefile +1 -1
- data/changes.txt +141 -0
- data/intercom.gemspec +1 -2
- data/lib/intercom.rb +34 -19
- data/lib/intercom/api_operations/archive.rb +16 -0
- data/lib/intercom/api_operations/delete.rb +4 -1
- 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/request_hard_delete.rb +12 -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 +18 -0
- data/lib/intercom/article.rb +7 -0
- data/lib/intercom/base_collection_proxy.rb +72 -0
- data/lib/intercom/client.rb +66 -18
- 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 +44 -4
- 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/typed_json_deserializer.rb +42 -37
- data/lib/intercom/note.rb +4 -0
- data/lib/intercom/request.rb +162 -95
- data/lib/intercom/scroll_collection_proxy.rb +38 -42
- data/lib/intercom/search_collection_proxy.rb +47 -0
- 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 +13 -0
- data/lib/intercom/service/collection.rb +24 -0
- data/lib/intercom/service/company.rb +4 -2
- data/lib/intercom/service/contact.rb +29 -6
- data/lib/intercom/service/conversation.rb +23 -2
- data/lib/intercom/service/data_attribute.rb +20 -0
- data/lib/intercom/service/event.rb +12 -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/tag.rb +8 -8
- data/lib/intercom/service/team.rb +17 -0
- data/lib/intercom/service/user.rb +4 -2
- data/lib/intercom/service/visitor.rb +15 -6
- data/lib/intercom/tag.rb +4 -0
- data/lib/intercom/team.rb +7 -0
- data/lib/intercom/traits/api_resource.rb +48 -27
- 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/spec/spec_helper.rb +881 -436
- 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 +30 -0
- data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
- data/spec/unit/intercom/client_spec.rb +76 -9
- data/spec/unit/intercom/collection_spec.rb +32 -0
- data/spec/unit/intercom/company_spec.rb +29 -21
- data/spec/unit/intercom/contact_spec.rb +365 -29
- data/spec/unit/intercom/conversation_spec.rb +70 -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 +25 -8
- 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 +150 -9
- data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
- data/spec/unit/intercom/search_collection_proxy_spec.rb +60 -0
- 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 +21 -0
- data/spec/unit/intercom/traits/api_resource_spec.rb +129 -47
- data/spec/unit/intercom/user_spec.rb +227 -217
- data/spec/unit/intercom/visitor_spec.rb +49 -0
- data/spec/unit/intercom_spec.rb +5 -3
- metadata +63 -26
- data/.travis.yml +0 -6
- data/lib/intercom/extended_api_operations/users.rb +0 -16
- data/spec/unit/intercom/visitors_spec.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ebb883bd25fc8d132306baac3a22c43650701dbe42d42b95ada3819bc52cc2d6
|
4
|
+
data.tar.gz: 8d1158c4d79cf19916c6cc1d413c329588d1ff36b5741517e029415e0f992360
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a0ea848ac117043da9707f2f9689504abda06f34e218a077c0591216aa654c3e9ca73f9874f2255e7300cd3329c95ba6440232c30d58364877e7d358bf950d0
|
7
|
+
data.tar.gz: 95b5ffdd05e7332fcbd53061c08c380d8632bd9f11d09e3673da65ca25b4624377b409116292b41f626a0fc6b4ad3d1c5183e5315533d3b4f94fe285c74041a6
|
@@ -0,0 +1,35 @@
|
|
1
|
+
version: 2
|
2
|
+
jobs:
|
3
|
+
"Test against Ruby 2.4":
|
4
|
+
docker:
|
5
|
+
- image: circleci/ruby:2.4.9
|
6
|
+
working_directory: ~/intercom-ruby
|
7
|
+
steps:
|
8
|
+
- checkout
|
9
|
+
- run: bundle install
|
10
|
+
- run: bundle exec rake
|
11
|
+
"Test against Ruby 2.5":
|
12
|
+
docker:
|
13
|
+
- image: circleci/ruby:2.5.7
|
14
|
+
working_directory: ~/intercom-ruby
|
15
|
+
steps:
|
16
|
+
- checkout
|
17
|
+
- run: bundle install
|
18
|
+
- run: bundle exec rake
|
19
|
+
"Test against Ruby 2.6":
|
20
|
+
docker:
|
21
|
+
- image: circleci/ruby:2.6.5
|
22
|
+
working_directory: ~/intercom-ruby
|
23
|
+
steps:
|
24
|
+
- checkout
|
25
|
+
- run: bundle install
|
26
|
+
- run: bundle exec rake
|
27
|
+
|
28
|
+
workflows:
|
29
|
+
version: 2
|
30
|
+
build_and_test:
|
31
|
+
jobs:
|
32
|
+
- "Test against Ruby 2.4"
|
33
|
+
- "Test against Ruby 2.5"
|
34
|
+
- "Test against Ruby 2.6"
|
35
|
+
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -6,35 +6,39 @@ Ruby bindings for the Intercom API (https://developers.intercom.io/reference).
|
|
6
6
|
|
7
7
|
[Gem Documentation](http://rubydoc.info/github/intercom/intercom-ruby/master/frames)
|
8
8
|
|
9
|
-
For generating Intercom
|
9
|
+
For generating Intercom JavaScript script tags for Rails, please see https://github.com/intercom/intercom-rails.
|
10
10
|
|
11
11
|
## Upgrading information
|
12
12
|
|
13
|
-
Version
|
14
|
-
|
15
|
-
Version 3 moves away from a global setup approach to the use of an Intercom Client.
|
13
|
+
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
14
|
|
17
15
|
This version of the gem is compatible with `Ruby 2.1` and above.
|
18
16
|
|
19
17
|
## Installation
|
20
18
|
|
19
|
+
|
21
20
|
gem install intercom
|
22
21
|
|
23
22
|
Using bundler:
|
24
23
|
|
25
|
-
gem 'intercom', '~>
|
24
|
+
gem 'intercom', '~> 4.1'
|
26
25
|
|
27
26
|
## Basic Usage
|
28
27
|
|
29
28
|
### Configure your client
|
30
29
|
|
31
|
-
> If you already have a personal access token you can find it [here](https://app.intercom.io/a/apps/_/
|
30
|
+
> If you already have a personal access token you can find it [here](https://app.intercom.io/a/apps/_/developer-hub/). If you want to create or learn more about personal access tokens then you can find more info [here](https://developers.intercom.io/docs/personal-access-tokens).
|
32
31
|
|
33
32
|
```ruby
|
34
33
|
# With an OAuth or Personal Access token:
|
35
34
|
intercom = Intercom::Client.new(token: 'my_token')
|
36
35
|
```
|
37
36
|
|
37
|
+
```ruby
|
38
|
+
# With a versioned app:
|
39
|
+
intercom = Intercom::Client.new(token: 'my_token', api_version: '2.1')
|
40
|
+
```
|
41
|
+
|
38
42
|
If you are building a third party application you can get your access_tokens by [setting-up-oauth](https://developers.intercom.io/page/setting-up-oauth) for Intercom.
|
39
43
|
You can also use the [omniauth-intercom lib](https://github.com/intercom/omniauth-intercom) which is a middleware helping you to handle the authentication process with Intercom.
|
40
44
|
|
@@ -42,146 +46,258 @@ You can also use the [omniauth-intercom lib](https://github.com/intercom/omniaut
|
|
42
46
|
|
43
47
|
Resources this API supports:
|
44
48
|
|
45
|
-
https://api.intercom.io/users
|
46
49
|
https://api.intercom.io/contacts
|
50
|
+
https://api.intercom.io/visitors
|
47
51
|
https://api.intercom.io/companies
|
48
|
-
https://api.intercom.io/
|
52
|
+
https://api.intercom.io/data_attributes
|
53
|
+
https://api.intercom.io/events
|
49
54
|
https://api.intercom.io/tags
|
50
55
|
https://api.intercom.io/notes
|
51
56
|
https://api.intercom.io/segments
|
52
|
-
https://api.intercom.io/events
|
53
57
|
https://api.intercom.io/conversations
|
54
58
|
https://api.intercom.io/messages
|
59
|
+
https://api.intercom.io/admins
|
60
|
+
https://api.intercom.io/teams
|
61
|
+
https://api.intercom.io/counts
|
55
62
|
https://api.intercom.io/subscriptions
|
56
63
|
https://api.intercom.io/jobs
|
57
|
-
https://api.intercom.io/
|
64
|
+
https://api.intercom.io/articles
|
65
|
+
https://api.intercom.io/help_center/collections
|
66
|
+
https://api.intercom.io/help_center/sections
|
67
|
+
|
58
68
|
|
59
69
|
### Examples
|
60
70
|
|
61
|
-
####
|
71
|
+
#### Contacts
|
72
|
+
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.
|
62
73
|
|
63
74
|
```ruby
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
#
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
#
|
79
|
-
|
80
|
-
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
#
|
85
|
-
intercom.
|
86
|
-
|
87
|
-
# List
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
#
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
#
|
108
|
-
intercom.
|
109
|
-
|
110
|
-
|
111
|
-
#
|
112
|
-
|
75
|
+
# Create a contact with "lead" role
|
76
|
+
contact = intercom.contacts.create(email: "some_contact2@example.com", role: "lead")
|
77
|
+
|
78
|
+
# Get a single contact using their intercom_id
|
79
|
+
intercom.contacts.find(id: contact.id)
|
80
|
+
|
81
|
+
# Update a contact
|
82
|
+
contact.name = "New name"
|
83
|
+
intercom.contacts.save(contact)
|
84
|
+
|
85
|
+
# Update a contact's role from "lead" to "user"
|
86
|
+
contact.role = "user"
|
87
|
+
intercom.contacts.save(contact)
|
88
|
+
|
89
|
+
# Archive a contact
|
90
|
+
intercom.contacts.archive(contact)
|
91
|
+
|
92
|
+
# Unarchive a contact
|
93
|
+
intercom.contacts.unarchive(contact)
|
94
|
+
|
95
|
+
# Delete a contact permanently
|
96
|
+
intercom.contacts.delete(contact)
|
97
|
+
|
98
|
+
# List all contacts
|
99
|
+
contacts = intercom.contacts.all
|
100
|
+
contacts.each { |contact| p contact.name }
|
101
|
+
|
102
|
+
# Search for contacts by email
|
103
|
+
contacts = intercom.contacts.search(
|
104
|
+
"query": {
|
105
|
+
"field": 'email',
|
106
|
+
"operator": '=',
|
107
|
+
"value": 'some_contact@example.com'
|
108
|
+
}
|
109
|
+
)
|
110
|
+
contacts.each {|c| p c.email}
|
111
|
+
# For full detail on possible queries, please refer to the API documentation:
|
112
|
+
# https://developers.intercom.com/intercom-api-reference/reference
|
113
|
+
|
114
|
+
# Merge a lead into an existing user
|
115
|
+
lead = intercom.contacts.create(email: "some_contact2@example.com", role: "lead")
|
116
|
+
intercom.contacts.merge(lead, intercom.contacts.find(id: "5db2e80ab1b92243d2188cfe"))
|
117
|
+
|
118
|
+
# Add a tag to a contact
|
119
|
+
tag = intercom.tags.find(id: "123")
|
120
|
+
contact.add_tag(id: tag.id)
|
121
|
+
|
122
|
+
# Remove a tag
|
123
|
+
contact.remove_tag(id: tag.id)
|
124
|
+
|
125
|
+
# List tags for a contact
|
126
|
+
contact.tags.each {|t| p t.name}
|
127
|
+
|
128
|
+
# Create a note on a contact
|
129
|
+
contact.create_note(body: "<p>Text for the note</p>")
|
130
|
+
|
131
|
+
# List notes for a contact
|
132
|
+
contact.notes.each {|n| p n.body}
|
133
|
+
|
134
|
+
# List segments for a contact
|
135
|
+
contact.segments.each {|segment| p segment.name}
|
136
|
+
|
137
|
+
# Add a contact to a company
|
138
|
+
company = intercom.companies.find(id: "123")
|
139
|
+
contact.add_company(id: company.id)
|
140
|
+
|
141
|
+
# Remove a contact from a company
|
142
|
+
contact.remove_company(id: company.id)
|
143
|
+
|
144
|
+
# List companies for a contact
|
145
|
+
contact.companies.each {|c| p c.name}
|
113
146
|
```
|
114
147
|
|
115
|
-
####
|
148
|
+
#### Visitors
|
116
149
|
```ruby
|
117
|
-
#
|
118
|
-
intercom.
|
119
|
-
|
120
|
-
intercom.
|
121
|
-
|
122
|
-
|
150
|
+
# Get and update a visitor
|
151
|
+
visitor = intercom.visitors.find(id: "5dd570e7b1b922452676af23")
|
152
|
+
visitor.name = "New name"
|
153
|
+
intercom.visitors.save(visitor)
|
154
|
+
|
155
|
+
# Convert a visitor into a lead
|
156
|
+
intercom.visitors.convert(visitor)
|
157
|
+
|
158
|
+
# Convert a visitor into a user
|
159
|
+
user = intercom.contacts.find(id: "5db2e7f5b1b92243d2188cb3")
|
160
|
+
intercom.visitors.convert(visitor, user)
|
123
161
|
```
|
124
162
|
|
125
163
|
#### Companies
|
126
164
|
```ruby
|
127
|
-
# Add a user to one or more companies
|
128
|
-
user = intercom.users.find(email: "bob@example.com")
|
129
|
-
user.companies = [{company_id: 6, name: "Intercom"}, {company_id: 9, name: "Test Company"}]
|
130
|
-
intercom.users.save(user)
|
131
|
-
# You can also pass custom attributes within a company as you do this
|
132
|
-
user.companies = [{id: 6, name: "Intercom", custom_attributes: {referral_source: "Google"} } ]
|
133
|
-
intercom.users.save(user)
|
134
165
|
# Find a company by company_id
|
135
166
|
company = intercom.companies.find(company_id: "44")
|
167
|
+
|
136
168
|
# Find a company by name
|
137
169
|
company = intercom.companies.find(name: "Some company")
|
170
|
+
|
138
171
|
# Find a company by id
|
139
172
|
company = intercom.companies.find(id: "41e66f0313708347cb0000d0")
|
173
|
+
|
140
174
|
# Update a company
|
141
175
|
company.name = 'Updated company name'
|
142
176
|
intercom.companies.save(company)
|
177
|
+
|
178
|
+
# Delete a company
|
179
|
+
intercom.companies.delete(company)
|
180
|
+
|
143
181
|
# Iterate over all companies
|
144
182
|
intercom.companies.all.each {|company| puts %Q(#{company.name} - #{company.custom_attributes["referral_source"]}) }
|
145
183
|
intercom.companies.all.map {|company| company.name }
|
146
|
-
|
147
|
-
|
184
|
+
|
185
|
+
# Get a large list of companies using scroll
|
186
|
+
intercom.companies.scroll.each { |comp| puts comp.name}
|
187
|
+
# Please see users scroll for more details of how to use scroll
|
188
|
+
```
|
189
|
+
|
190
|
+
#### Data Attributes
|
191
|
+
Data Attributes are a type of metadata used to describe your customer and company models. These include standard and custom attributes.
|
192
|
+
```ruby
|
193
|
+
# Create a new custom data attribute
|
194
|
+
intercom.data_attributes.create({ name: "test_attribute", model: "contact", data_type: "string" })
|
195
|
+
|
196
|
+
# List all data attributes
|
197
|
+
attributes = intercom.data_attributes.all
|
198
|
+
attributes.each { |attribute| p attribute.name }
|
199
|
+
|
200
|
+
# Update an attribute
|
201
|
+
attribute = intercom.data_attributes.all.first
|
202
|
+
attribute.label = "New label"
|
203
|
+
intercom.data_attributes.save(attribute)
|
204
|
+
|
205
|
+
# Archive an attribute
|
206
|
+
attribute.archived = true
|
207
|
+
intercom.data_attributes.save(attribute)
|
208
|
+
|
209
|
+
# Find all customer attributes including archived
|
210
|
+
customer_attributes_incl_archived = intercom.data_attributes.find_all({"model": "contact", "include_archived": true})
|
211
|
+
customer_attributes_incl_archived.each { |attr| p attribute.name }
|
148
212
|
```
|
149
213
|
|
214
|
+
#### Events
|
215
|
+
```ruby
|
216
|
+
intercom.events.create(
|
217
|
+
event_name: "invited-friend",
|
218
|
+
created_at: Time.now.to_i,
|
219
|
+
email: user.email,
|
220
|
+
metadata: {
|
221
|
+
"invitee_email" => "pi@example.org",
|
222
|
+
invite_code: "ADDAFRIEND",
|
223
|
+
"found_date" => 12909364407
|
224
|
+
}
|
225
|
+
)
|
226
|
+
|
227
|
+
# Alternatively, use "user_id" in case your app allows multiple accounts having the same email
|
228
|
+
intercom.events.create(
|
229
|
+
event_name: "invited-friend",
|
230
|
+
created_at: Time.now.to_i,
|
231
|
+
user_id: user.uuid,
|
232
|
+
)
|
233
|
+
|
234
|
+
# Retrieve event list for user with id:'123abc'
|
235
|
+
intercom.events.find_all("type" => "user", "intercom_user_id" => "123abc")
|
236
|
+
```
|
237
|
+
|
238
|
+
Metadata Objects support a few simple types that Intercom can present on your behalf
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
intercom.events.create(
|
242
|
+
event_name: "placed-order",
|
243
|
+
email: current_user.email,
|
244
|
+
created_at: 1403001013,
|
245
|
+
metadata: {
|
246
|
+
order_date: Time.now.to_i,
|
247
|
+
stripe_invoice: 'inv_3434343434',
|
248
|
+
order_number: {
|
249
|
+
value: '3434-3434',
|
250
|
+
url: 'https://example.org/orders/3434-3434'
|
251
|
+
},
|
252
|
+
price: {
|
253
|
+
currency: 'usd',
|
254
|
+
amount: 2999
|
255
|
+
}
|
256
|
+
}
|
257
|
+
)
|
258
|
+
```
|
259
|
+
|
260
|
+
The metadata key values in the example are treated as follows-
|
261
|
+
- order_date: a Date (key ends with '_date')
|
262
|
+
- stripe_invoice: The identifier of the Stripe invoice (has a 'stripe_invoice' key)
|
263
|
+
- order_number: a Rich Link (value contains 'url' and 'value' keys)
|
264
|
+
- price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)
|
265
|
+
|
266
|
+
*NB:* This version of the gem reserves the field name `type` in Event data.
|
267
|
+
|
150
268
|
#### Tags
|
151
269
|
```ruby
|
152
|
-
# Tag users
|
153
|
-
tag = intercom.tags.tag(name: 'blue', users: [{email: "test1@example.com"}])
|
154
|
-
# Untag users
|
155
|
-
intercom.tags.untag(name: 'blue', users: [{user_id: "42ea2f1b93891f6a99000427"}])
|
156
270
|
# Iterate over all tags
|
157
271
|
intercom.tags.all.each {|tag| "#{tag.id} - #{tag.name}" }
|
158
272
|
intercom.tags.all.map {|tag| tag.name }
|
273
|
+
|
159
274
|
# Tag companies
|
160
|
-
tag = intercom.tags.tag(name: 'blue', companies: [{
|
275
|
+
tag = intercom.tags.tag(name: 'blue', companies: [{company_id: "42ea2f1b93891f6a99000427"}])
|
276
|
+
|
277
|
+
# Untag Companies
|
278
|
+
tag = intercom.tags.untag(name: 'blue', companies: [{ company_id: "42ea2f1b93891f6a99000427" }])
|
279
|
+
```
|
280
|
+
|
281
|
+
#### Notes
|
282
|
+
```ruby
|
283
|
+
# Find a note by id
|
284
|
+
note = intercom.notes.find(id: "123")
|
161
285
|
```
|
162
286
|
|
163
287
|
#### Segments
|
164
288
|
```ruby
|
165
289
|
# Find a segment
|
166
290
|
segment = intercom.segments.find(id: segment_id)
|
291
|
+
|
167
292
|
# Iterate over all segments
|
168
293
|
intercom.segments.all.each {|segment| puts "id: #{segment.id} name: #{segment.name}"}
|
169
294
|
```
|
170
295
|
|
171
|
-
#### Notes
|
172
|
-
```ruby
|
173
|
-
# Find a note by id
|
174
|
-
note = intercom.notes.find(id: note)
|
175
|
-
# Create a note for a user
|
176
|
-
note = intercom.notes.create(body: "<p>Text for the note</p>", email: 'joe@example.com')
|
177
|
-
# Iterate over all notes for a user via their email address
|
178
|
-
intercom.notes.find_all(email: 'joe@example.com').each {|note| puts note.body}
|
179
|
-
# Iterate over all notes for a user via their user_id
|
180
|
-
intercom.notes.find_all(user_id: '123').each {|note| puts note.body}
|
181
|
-
```
|
182
|
-
|
183
296
|
#### Conversations
|
184
297
|
```ruby
|
298
|
+
# Iterate over all conversations for your app
|
299
|
+
intercom.conversations.all.each { |convo| ... }
|
300
|
+
|
185
301
|
# FINDING CONVERSATIONS FOR AN ADMIN
|
186
302
|
# Iterate over all conversations (open and closed) assigned to an admin
|
187
303
|
intercom.conversations.find_all(type: 'admin', id: '7').each {|convo| ... }
|
@@ -189,7 +305,7 @@ intercom.conversations.find_all(type: 'admin', id: '7').each {|convo| ... }
|
|
189
305
|
intercom.conversations.find_all(type: 'admin', id: 7, open: true).each {|convo| ... }
|
190
306
|
# Iterate over closed conversations assigned to an admin
|
191
307
|
intercom.conversations.find_all(type: 'admin', id: 7, open: false).each {|convo| ... }
|
192
|
-
# Iterate over closed conversations
|
308
|
+
# Iterate over closed conversations which are assigned to an admin, and where updated_at is before a certain moment in time
|
193
309
|
intercom.conversations.find_all(type: 'admin', id: 7, open: false, before: 1374844930).each {|convo| ... }
|
194
310
|
|
195
311
|
# FINDING CONVERSATIONS FOR A USER
|
@@ -199,18 +315,32 @@ intercom.conversations.find_all(email: 'joe@example.com', type: 'user').each {|c
|
|
199
315
|
intercom.conversations.find_all(email: 'joe@example.com', type: 'user', unread: false).each {|convo| ... }
|
200
316
|
# Iterate over all unread conversations with a user based on the users email
|
201
317
|
intercom.conversations.find_all(email: 'joe@example.com', type: 'user', unread: true).each {|convo| ... }
|
318
|
+
# Iterate over all conversations for a user with their Intercom user ID
|
319
|
+
intercom.conversations.find_all(intercom_user_id: '536e564f316c83104c000020', type: 'user').each {|convo| ... }
|
320
|
+
# Iterate over all conversations for a lead
|
321
|
+
# NOTE: to iterate over a lead's conversations you MUST use their Intercom User ID and type User
|
322
|
+
intercom.conversations.find_all(intercom_user_id: lead.id, type: 'user').each {|convo| ... }
|
202
323
|
|
203
324
|
# FINDING A SINGLE CONVERSATION
|
204
325
|
conversation = intercom.conversations.find(id: '1')
|
205
326
|
|
206
327
|
# INTERACTING WITH THE PARTS OF A CONVERSATION
|
207
328
|
# Getting the subject of a part (only applies to email-based conversations)
|
208
|
-
conversation.
|
329
|
+
conversation.source.subject
|
330
|
+
|
209
331
|
# Get the part_type of the first part
|
210
|
-
conversation.conversation_parts
|
332
|
+
conversation.conversation_parts.first.part_type
|
333
|
+
|
211
334
|
# Get the body of the second part
|
212
335
|
conversation.conversation_parts[1].body
|
213
336
|
|
337
|
+
# Get statistics related to the conversation
|
338
|
+
conversation.statistics.time_to_admin_reply
|
339
|
+
conversation.statistics.last_assignment_at
|
340
|
+
|
341
|
+
# Get information on the sla applied to a conversation
|
342
|
+
conversation.sla_applied.sla_name
|
343
|
+
|
214
344
|
# REPLYING TO CONVERSATIONS
|
215
345
|
# User (identified by email) replies with a comment
|
216
346
|
intercom.conversations.reply(id: conversation.id, type: 'user', email: 'joe@example.com', message_type: 'comment', body: 'foo')
|
@@ -219,6 +349,9 @@ intercom.conversations.reply(id: conversation.id, type: 'admin', admin_id: '123'
|
|
219
349
|
# User (identified by email) replies with a comment and attachment
|
220
350
|
intercom.conversations.reply(id: conversation.id, type: 'user', email: 'joe@example.com', message_type: 'comment', body: 'foo', attachment_urls: ['http://www.example.com/attachment.jpg'])
|
221
351
|
|
352
|
+
#reply to a user's last conversation
|
353
|
+
intercom.conversations.reply_to_last(type: 'user', body: 'Thanks again', message_type: 'comment', user_id: '12345', admin_id: '123')
|
354
|
+
|
222
355
|
# Open
|
223
356
|
intercom.conversations.open(id: conversation.id, admin_id: '123')
|
224
357
|
|
@@ -226,26 +359,75 @@ intercom.conversations.open(id: conversation.id, admin_id: '123')
|
|
226
359
|
intercom.conversations.close(id: conversation.id, admin_id: '123')
|
227
360
|
|
228
361
|
# Assign
|
362
|
+
# Note: Conversations can be assigned to teams. However, the entity that performs the operation of assigning the conversation has to be an existing teammate.
|
363
|
+
# You can use `intercom.admins.all.each {|a| puts a.inspect if a.type == 'admin' }` to list all of your teammates.
|
229
364
|
intercom.conversations.assign(id: conversation.id, admin_id: '123', assignee_id: '124')
|
230
365
|
|
366
|
+
# Snooze
|
367
|
+
intercom.conversations.snooze(id: conversation.id, admin_id: '123', snoozed_until: 9999999999)
|
368
|
+
|
231
369
|
# Reply and Open
|
232
370
|
intercom.conversations.reply(id: conversation.id, type: 'admin', admin_id: '123', message_type: 'open', body: 'bar')
|
233
371
|
|
234
372
|
# Reply and Close
|
235
373
|
intercom.conversations.reply(id: conversation.id, type: 'admin', admin_id: '123', message_type: 'close', body: 'bar')
|
236
374
|
|
375
|
+
# Admin reply to last conversation
|
376
|
+
intercom.conversations.reply_to_last(intercom_user_id: '5678', type: 'admin', admin_id: '123', message_type: 'comment', body: 'bar')
|
377
|
+
|
378
|
+
# User reply to last conversation
|
379
|
+
intercom.conversations.reply_to_last(intercom_user_id: '5678', type: 'user', message_type: 'comment', body: 'bar')
|
380
|
+
|
237
381
|
# ASSIGNING CONVERSATIONS TO ADMINS
|
238
382
|
intercom.conversations.reply(id: conversation.id, type: 'admin', assignee_id: assignee_admin.id, admin_id: admin.id, message_type: 'assignment')
|
239
383
|
|
240
384
|
# MARKING A CONVERSATION AS READ
|
241
385
|
intercom.conversations.mark_read(conversation.id)
|
386
|
+
|
387
|
+
# RUN ASSIGNMENT RULES
|
388
|
+
intercom.conversations.run_assignment_rules(conversation.id)
|
389
|
+
|
390
|
+
# Search for conversations
|
391
|
+
# For full detail on possible queries, please refer to the API documentation:
|
392
|
+
# https://developers.intercom.com/intercom-api-reference/reference
|
393
|
+
|
394
|
+
# Search for open conversations sorted by the created_at date
|
395
|
+
conversations = intercom.conversations.search(
|
396
|
+
query: {
|
397
|
+
field: "open",
|
398
|
+
operator: "=",
|
399
|
+
value: true
|
400
|
+
},
|
401
|
+
sort_field: "created_at",
|
402
|
+
sort_order: "descending"
|
403
|
+
)
|
404
|
+
conversations.each {|c| p c.id}
|
405
|
+
|
406
|
+
# Tagging for conversations
|
407
|
+
tag = intercom.tags.find(id: "2")
|
408
|
+
conversation = intercom.conversations.find(id: "1")
|
409
|
+
|
410
|
+
# An Admin ID is required to add or remove tag on a conversation
|
411
|
+
admin = intercom.admins.find(id: "1")
|
412
|
+
|
413
|
+
# Add a tag to a conversation
|
414
|
+
conversation.add_tag(id: tag.id, admin_id: admin.id)
|
415
|
+
|
416
|
+
# Remove a tag from a conversation
|
417
|
+
conversation.remove_tag(id: tag.id, admin_id: admin.id)
|
418
|
+
|
419
|
+
# Add a contact to a conversation
|
420
|
+
conversation.add_contact(admin_id: admin.id, customer: { intercom_user_id: contact.id })
|
421
|
+
|
422
|
+
# Remove a contact from a conversation
|
423
|
+
conversation.remove_contact(id: contact.id, admin_id: admin.id)
|
242
424
|
```
|
243
425
|
|
244
426
|
#### Full loading of an embedded entity
|
245
427
|
```ruby
|
246
|
-
# Given a conversation with a partial
|
428
|
+
# Given a conversation with a partial contact, load the full contact. This can be
|
247
429
|
# done for any entity
|
248
|
-
intercom.
|
430
|
+
intercom.contacts.load(conversation.contacts.first)
|
249
431
|
```
|
250
432
|
|
251
433
|
#### Sending messages
|
@@ -314,156 +496,148 @@ intercom.messages.create({
|
|
314
496
|
})
|
315
497
|
```
|
316
498
|
|
317
|
-
####
|
499
|
+
#### Admins
|
318
500
|
```ruby
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
"found_date" => 12909364407
|
327
|
-
}
|
328
|
-
)
|
329
|
-
|
330
|
-
# Retrieve event list for user with id:'123abc'
|
331
|
-
intercom.events.find_all("type" => "user", "intercom_user_id" => "123abc")
|
501
|
+
# Find access token owner (only with Personal Access Token and OAuth)
|
502
|
+
intercom.admins.me
|
503
|
+
# Find an admin by id
|
504
|
+
intercom.admins.find(id: admin_id)
|
505
|
+
# Iterate over all admins
|
506
|
+
intercom.admins.all.each {|admin| puts admin.email }
|
507
|
+
```
|
332
508
|
|
509
|
+
#### Teams
|
510
|
+
```ruby
|
511
|
+
# Find a team by id
|
512
|
+
intercom.teams.find(id: team_id)
|
513
|
+
# Iterate over all teams
|
514
|
+
intercom.teams.all.each {|team| puts team.name }
|
333
515
|
```
|
334
516
|
|
335
|
-
|
517
|
+
#### Counts
|
336
518
|
|
337
519
|
```ruby
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
order_date: Time.now.to_i,
|
344
|
-
stripe_invoice: 'inv_3434343434',
|
345
|
-
order_number: {
|
346
|
-
value: '3434-3434',
|
347
|
-
url: 'https://example.org/orders/3434-3434'
|
348
|
-
},
|
349
|
-
price: {
|
350
|
-
currency: 'usd',
|
351
|
-
amount: 2999
|
352
|
-
}
|
353
|
-
}
|
354
|
-
)
|
520
|
+
# App-wide counts
|
521
|
+
intercom.counts.for_app
|
522
|
+
|
523
|
+
# Users in segment counts
|
524
|
+
intercom.counts.for_type(type: 'user', count: 'segment')
|
355
525
|
```
|
356
526
|
|
357
|
-
|
358
|
-
- order_date: a Date (key ends with '_date')
|
359
|
-
- stripe_invoice: The identifier of the Stripe invoice (has a 'stripe_invoice' key)
|
360
|
-
- order_number: a Rich Link (value contains 'url' and 'value' keys)
|
361
|
-
- price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)
|
527
|
+
#### Subscriptions
|
362
528
|
|
363
|
-
|
529
|
+
Subscribe to events in Intercom to receive webhooks.
|
364
530
|
|
365
|
-
Bulk operations.
|
366
531
|
```ruby
|
367
|
-
#
|
368
|
-
intercom.
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
user_id: "314159",
|
373
|
-
metadata: {
|
374
|
-
order_date: 1438944980,
|
375
|
-
stripe_invoice: "inv_3434343434"
|
376
|
-
}
|
377
|
-
},
|
378
|
-
{
|
379
|
-
event_name: "invited-friend",
|
380
|
-
created_at: 1438944979,
|
381
|
-
user_id: "314159",
|
382
|
-
metadata: {
|
383
|
-
invitee_email: "pi@example.org",
|
384
|
-
invite_code: "ADDAFRIEND"
|
385
|
-
}
|
386
|
-
}
|
387
|
-
])
|
388
|
-
|
389
|
-
|
390
|
-
# Submit bulk job, to add items to existing job
|
391
|
-
intercom.events.submit_bulk_job(create_items: [
|
392
|
-
{
|
393
|
-
event_name: "ordered-item",
|
394
|
-
created_at: 1438944980,
|
395
|
-
user_id: "314159",
|
396
|
-
metadata: {
|
397
|
-
order_date: 1438944980,
|
398
|
-
stripe_invoice: "inv_3434343434"
|
399
|
-
}
|
400
|
-
},
|
401
|
-
{
|
402
|
-
event_name: "invited-friend",
|
403
|
-
created_at: 1438944979,
|
404
|
-
user_id: "314159",
|
405
|
-
metadata: {
|
406
|
-
invitee_email: "pi@example.org",
|
407
|
-
invite_code: "ADDAFRIEND"
|
408
|
-
}
|
409
|
-
}
|
410
|
-
], job_id:'job_abcd1234')
|
411
|
-
```
|
532
|
+
# create a subscription
|
533
|
+
intercom.subscriptions.create(url: "http://example.com", topics: ["user.created"])
|
534
|
+
|
535
|
+
# fetch a subscription
|
536
|
+
intercom.subscriptions.find(id: "nsub_123456789")
|
412
537
|
|
413
|
-
|
538
|
+
# delete a subscription
|
539
|
+
subscription = intercom.subscriptions.find(id: "nsub_123456789")
|
540
|
+
intercom.subscriptions.delete(subscription)
|
414
541
|
|
415
|
-
|
542
|
+
# list subscriptions
|
543
|
+
intercom.subscriptions.all
|
544
|
+
```
|
416
545
|
|
546
|
+
#### Articles
|
417
547
|
```ruby
|
418
|
-
# Create
|
419
|
-
|
548
|
+
# Create an article
|
549
|
+
article = intercom.articles.create(title: "New Article", author_id: "123456")
|
420
550
|
|
421
|
-
#
|
422
|
-
|
423
|
-
|
551
|
+
# Create an article with translations
|
552
|
+
article = intercom.articles.create(title: "New Article",
|
553
|
+
author_id: "123456",
|
554
|
+
translated_content: {fr: {title: "Nouvel Article"}, es: {title: "Nuevo artículo"}})
|
424
555
|
|
425
|
-
#
|
426
|
-
|
556
|
+
# Fetch an article
|
557
|
+
intercom.articles.find(id: "123456")
|
427
558
|
|
428
|
-
#
|
429
|
-
intercom.
|
559
|
+
# List all articles
|
560
|
+
articles = intercom.articles.all
|
561
|
+
articles.each { |article| p article.title }
|
430
562
|
|
431
|
-
#
|
432
|
-
|
433
|
-
|
563
|
+
# Update an article
|
564
|
+
article.title = "Article Updated!"
|
565
|
+
intercom.articles.save(article)
|
434
566
|
|
435
|
-
|
567
|
+
# Update an article's existing translation
|
568
|
+
article.translated_content.en.title = "English Updated!"
|
569
|
+
intercom.articles.save(article)
|
436
570
|
|
437
|
-
|
438
|
-
|
439
|
-
intercom.
|
571
|
+
# Update an article by adding a new translation
|
572
|
+
article.translated_content.es = {title: "Artículo en español"}
|
573
|
+
intercom.articles.save(article)
|
440
574
|
|
441
|
-
#
|
442
|
-
intercom.
|
575
|
+
# Delete an article
|
576
|
+
intercom.articles.delete(article)
|
443
577
|
```
|
444
578
|
|
445
|
-
|
579
|
+
#### Collections
|
580
|
+
```ruby
|
581
|
+
# Create a collection
|
582
|
+
collection = intercom.collections.create(name: "New Collection")
|
446
583
|
|
447
|
-
|
584
|
+
# Create a collection with translations
|
585
|
+
collection = intercom.collections.create(name: "New Collection",
|
586
|
+
translated_content: {fr: {name: "Nouvelle collection"}, es: {name: "Nueva colección"}})
|
448
587
|
|
449
|
-
|
450
|
-
|
451
|
-
intercom.subscriptions.create(url: "http://example.com", topics: ["user.created"])
|
588
|
+
# Fetch a collection
|
589
|
+
intercom.collections.find(id: "123456")
|
452
590
|
|
453
|
-
#
|
454
|
-
intercom.
|
591
|
+
# List all collections
|
592
|
+
collections = intercom.collections.all
|
593
|
+
collections.each { |collection| p collection.name }
|
455
594
|
|
456
|
-
#
|
457
|
-
|
595
|
+
# Update a collection
|
596
|
+
collection.name = "Collection updated!"
|
597
|
+
intercom.collections.save(collection)
|
598
|
+
|
599
|
+
# Update a collection's existing translation
|
600
|
+
collection.translated_content.en.name = "English Updated!"
|
601
|
+
intercom.collections.save(collection)
|
602
|
+
|
603
|
+
# Update a collection by adding a new translation
|
604
|
+
collection.translated_content.es = {name: "Colección en español", description: "Descripción en español"}
|
605
|
+
intercom.collections.save(collection)
|
606
|
+
|
607
|
+
# Delete an collection
|
608
|
+
intercom.collections.delete(collection)
|
458
609
|
```
|
459
|
-
### Bulk jobs
|
460
610
|
|
611
|
+
#### Sections
|
461
612
|
```ruby
|
462
|
-
#
|
463
|
-
intercom.
|
613
|
+
# Create a section
|
614
|
+
section = intercom.sections.create(name: "New Section", parent_id: "123456")
|
615
|
+
|
616
|
+
# Create a section with translations
|
617
|
+
section = intercom.sections.create(name: "New Section",
|
618
|
+
translated_content: {fr: {name: "Nouvelle section"}, es: {name: "Nueva sección"}})
|
619
|
+
|
620
|
+
# Fetch a section
|
621
|
+
intercom.sections.find(id: "123456")
|
464
622
|
|
465
|
-
#
|
466
|
-
intercom.
|
623
|
+
# List all sections
|
624
|
+
sections = intercom.sections.all
|
625
|
+
sections.each { |section| p section.name }
|
626
|
+
|
627
|
+
# Update a section
|
628
|
+
section.name = "Section updated!"
|
629
|
+
intercom.sections.save(section)
|
630
|
+
|
631
|
+
# Update a section's existing translation
|
632
|
+
section.translated_content.en.name = "English Updated!"
|
633
|
+
intercom.collections.save(section)
|
634
|
+
|
635
|
+
# Update a section by adding a new translation
|
636
|
+
section.translated_content.es = {name: "Sección en español"}
|
637
|
+
intercom.collections.save(section)
|
638
|
+
|
639
|
+
# Delete an section
|
640
|
+
intercom.sections.delete(section)
|
467
641
|
```
|
468
642
|
|
469
643
|
### Errors
|
@@ -480,6 +654,7 @@ Intercom::ServerError
|
|
480
654
|
Intercom::ServiceUnavailableError
|
481
655
|
Intercom::ServiceConnectionError
|
482
656
|
Intercom::ResourceNotFound
|
657
|
+
Intercom::BlockedUserError
|
483
658
|
Intercom::BadRequestError
|
484
659
|
Intercom::RateLimitExceeded
|
485
660
|
Intercom::AttributeNotSetError # Raised when you try to call a getter that does not exist on an object
|
@@ -496,6 +671,12 @@ intercom.rate_limit_details
|
|
496
671
|
#=> {:limit=>180, :remaining=>179, :reset_at=>2014-10-07 14:58:00 +0100}
|
497
672
|
```
|
498
673
|
|
674
|
+
You can handle the rate limits yourself but a simple option is to use the handle_rate_limit flag.
|
675
|
+
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.
|
676
|
+
|
677
|
+
```
|
678
|
+
intercom = Intercom::Client.new(token: ENV['AT'], handle_rate_limit: true)
|
679
|
+
```
|
499
680
|
|
500
681
|
### Pull Requests
|
501
682
|
|
@@ -512,3 +693,24 @@ intercom.rate_limit_details
|
|
512
693
|
- **Send coherent history**. Make sure each individual commit in your pull
|
513
694
|
request is meaningful. If you had to make multiple intermediate commits while
|
514
695
|
developing, please squash them before sending them to us.
|
696
|
+
|
697
|
+
### Development
|
698
|
+
|
699
|
+
#### Running tests
|
700
|
+
|
701
|
+
```bash
|
702
|
+
# all tests
|
703
|
+
bundle exec spec
|
704
|
+
|
705
|
+
# unit tests
|
706
|
+
bundle exec spec:unit
|
707
|
+
|
708
|
+
# integration tests
|
709
|
+
bundle exec spec:integration
|
710
|
+
|
711
|
+
# single test file
|
712
|
+
bundle exec m spec/unit/intercom/job_spec.rb
|
713
|
+
|
714
|
+
# single test
|
715
|
+
bundle exec m spec/unit/intercom/job_spec.rb:49
|
716
|
+
```
|