intercom 3.5.10 → 4.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
```
|