Skip to content

Commit a672399

Browse files
committed
Merge pull request #73 from intercom/BL/new-api-prerelease
Version 2.0.0
2 parents eae08e8 + 9f43266 commit a672399

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1764
-2045
lines changed

.travis.yml

-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
11
language: ruby
22
rvm:
3-
- 1.8.7
4-
- ree
5-
- 1.9.2
6-
- 1.9.3
73
- 2.0.0
8-
- jruby-18mode
9-
- jruby-19mode
10-
- rbx-18mode
11-
- rbx-19mode

Gemfile

+3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
source "http://rubygems.org"
2+
ruby "2.0.0"
23

34
gemspec
45

56
group :development, :test do
67
gem 'fakeweb', "~> 1.3"
8+
# gem 'm'
9+
# gem 'pry-byebug'
710
platforms :jruby do
811
gem 'json-jruby'
912
gem 'jruby-openssl'

README.md

+208-52
Original file line numberDiff line numberDiff line change
@@ -8,118 +8,266 @@ Ruby bindings for the Intercom API (https://api.intercom.io).
88

99
For generating Intercom javascript script tags for Rails, please see https://github.com/intercom/intercom-rails
1010

11+
## Upgrading information
12+
Version 2 of intercom-ruby is not backwards compatible with previous versions. Be sure to test this new version before deploying to production. One other change you will need to make as part of the upgrade is to set `Intercom.app_api_key` and not set `Intercom.api_key` (you can continue to use your existing API key).
13+
1114
## Installation
1215

1316
gem install intercom
1417

1518
Using bundler:
1619

17-
gem 'intercom'
20+
gem 'intercom', "~> 2.0"
1821

1922
## Basic Usage
2023

2124
### Configure your access credentials
2225

2326
```ruby
2427
Intercom.app_id = "my_app_id"
25-
Intercom.api_key = "my-super-crazy-api-key"
28+
Intercom.app_api_key = "my-super-crazy-api-key"
2629
```
2730

2831
### Resources
2932

30-
The API supports:
33+
Resources this API supports:
3134

32-
POST,PUT,GET https://api.intercom.io/v1/users
33-
POST,PUT,GET https://api.intercom.io/v1/users/messages
34-
POST https://api.intercom.io/v1/users/impressions
35-
POST https://api.intercom.io/v1/users/notes
35+
https://api.intercom.io/users
36+
https://api.intercom.io/companies
37+
https://api.intercom.io/tags
38+
https://api.intercom.io/notes
39+
https://api.intercom.io/segments
40+
https://api.intercom.io/events
41+
https://api.intercom.io/conversations
42+
https://api.intercom.io/messages
43+
https://api.intercom.io/counts
3644

3745
### Examples
3846

3947
#### Users
4048

4149
```ruby
42-
user = Intercom::User.find_by_email("[email protected]")
43-
user.custom_data["average_monthly_spend"] = 1234.56
44-
user.save
45-
user = Intercom::User.find_by_user_id("1")
50+
# Find user by email
51+
user = Intercom::User.find(:email => "[email protected]")
52+
# Find user by user_id
53+
user = Intercom::User.find(:user_id => "1")
54+
# Find user by id
55+
user = Intercom::User.find(:id => "1")
56+
# Create a user
4657
user = Intercom::User.create(:email => "[email protected]", :name => "Bob Smith")
47-
user = Intercom::User.new(params)
48-
user.save
49-
Intercom::User.all.count
50-
Intercom::User.all.each {|user| puts %Q(#{user.email} - #{user.custom_data["average_monthly_spend"]}) }
58+
# Update custom_attributes for a user
59+
user.custom_attributes["average_monthly_spend"] = 1234.56; user.save
60+
# Perform incrementing
61+
user.increment('karma'); user.save
62+
# Iterate over all users
63+
Intercom::User.all.each {|user| puts %Q(#{user.email} - #{user.custom_attributes["average_monthly_spend"]}) }
5164
Intercom::User.all.map {|user| user.email }
5265
```
5366

5467
#### Companies
5568
```ruby
56-
user = Intercom::User.find_by_email("[email protected]")
57-
user.company = {:id => 6, :name => "Intercom"}
58-
user.companies = [{:id => 6, :name => "Intercom"}, {:id => 9, :name => "Test Company"}]
69+
# Add a user to one or more companies
70+
user = Intercom::User.find(:email => "[email protected]")
71+
user.companies = [{:company_id => 6, :name => "Intercom"}, {:company_id => 9, :name => "Test Company"}]; user.save
72+
# You can also pass custom attributes within a company as you do this
73+
user.companies = [{:id => 6, :name => "Intercom", :custom_attributes => {:referral_source => "Google"} } ]; user.save
74+
# Find a company by company_id
75+
company = Intercom::Company.find(:company_id => "44")
76+
# Find a company by name
77+
company = Intercom::Company.find(:name => "Some company")
78+
# Find a company by id
79+
company = Intercom::Company.find(:id => "41e66f0313708347cb0000d0")
80+
# Update a company
81+
company.name = 'Updated company name'; company.save
82+
# Iterate over all companies
83+
Intercom::Company.all.each {|company| puts %Q(#{company.name} - #{company.custom_attributes["referral_source"]}) }
84+
Intercom::Company.all.map {|company| company.name }
85+
# Get a list of users in a company
86+
company.users
5987
```
6088

61-
You can also pass custom data within a company:
89+
#### Tags
90+
```ruby
91+
# Tag users
92+
tag = Intercom::Tag.tag_users('blue', ["42ea2f1b93891f6a99000427"])
93+
# Untag users
94+
Intercom::Tag.untag_users('blue', ["42ea2f1b93891f6a99000427"])
95+
# Iterate over all tags
96+
Intercom::Tag.all.each {|tag| "#{tag.id} - #{tag.name}" }
97+
Intercom::Tag.all.map {|tag| tag.name }
98+
# Iterate over all tags for user
99+
Intercom::Tag.find_all_for_user(:id => '53357ddc3c776629e0000029')
100+
Intercom::Tag.find_all_for_user(:email => '[email protected]')
101+
Intercom::Tag.find_all_for_user(:user_id => '3')
102+
# Tag companies
103+
tag = Intercom::Tag.tag_companies('red', ["42ea2f1b93891f6a99000427"])
104+
# Untag companies
105+
Intercom::Tag.untag_users('blue', ["42ea2f1b93891f6a99000427"])
106+
# Iterate over all tags for company
107+
Intercom::Tag.find_all_for_company(:id => '43357e2c3c77661e25000026')
108+
Intercom::Tag.find_all_for_company(:company_id => '6')
109+
```
62110

111+
#### Segments
63112
```ruby
64-
user.company = {:id => 6, :name => "Intercom", :referral_source => "Google"}
113+
# Find a segment
114+
segment = Intercom::Segment.find(:id => segment_id)
115+
# Update a segment
116+
segment.name = 'Updated name'; segment.save
117+
# Iterate over all segments
118+
Intercom::Segment.all.each {|segment| puts "id: #{segment.id} name: #{segment.name}"}
65119
```
66120

67-
#### Message Threads
121+
#### Notes
68122
```ruby
69-
Intercom::MessageThread.create(:email => "[email protected]", :body => "Example message from [email protected] to your application on Intercom.")
70-
Intercom::MessageThread.find(:email => "[email protected]", :thread_id => 123)
71-
Intercom::MessageThread.find_all(:email => "[email protected]")
72-
Intercom::MessageThread.mark_as_read(:email => "[email protected]", :thread_id => 123)
123+
# Find a note by id
124+
note = Intercom::Note.find(:id => note)
125+
# Create a note for a user
126+
note = Intercom::Note.create(:body => "<p>Text for the note</p>", :email => '[email protected]')
127+
# Iterate over all notes for a user via their email address
128+
Intercom::Note.find_all(:email => '[email protected]').each {|note| puts note.body}
129+
# Iterate over all notes for a user via their user_id
130+
Intercom::Note.find_all(:user_id => '123').each {|note| puts note.body}
73131
```
74132

75-
#### Impressions
133+
#### Conversations
76134
```ruby
77-
Intercom::Impression.create(:email => "[email protected]", :location => "/path/in/my/app", :user_ip => "1.2.3.4", :user_agent => "my-savage-iphone-app-0.1"
135+
# FINDING CONVERSATIONS FOR AN ADMIN
136+
# Iterate over all conversations (open and closed) assigned to an admin
137+
Intercom::Conversation.find_all(:type => 'admin', :id => '7').each do {|convo| ... }
138+
# Iterate over all open conversations assigned to an admin
139+
Intercom::Conversation.find_all(:type => 'admin', :id => 7, :open => true).each do {|convo| ... }
140+
# Iterate over closed conversations assigned to an admin
141+
Intercom::Conversation.find_all(:type => 'admin', :id => 7, :open => false).each do {|convo| ... }
142+
# Iterate over closed conversations for assigned an admin, before a certain moment in time
143+
Intercom::Conversation.find_all(:type => 'admin', :id => 7, :open => false, :before => 1374844930).each do {|convo| ... }
144+
145+
# FINDING CONVERSATIONS FOR A USER
146+
# Iterate over all conversations (read + unread, correct) with a user based on the users email
147+
Intercom::Conversation.find_all(:email => '[email protected]', :type => 'user').each do {|convo| ... }
148+
# Iterate over through all conversations (read + unread) with a user based on the users email
149+
Intercom::Conversation.find_all(:email => '[email protected]', :type => 'user', :unread => false).each do {|convo| ... }
150+
# Iterate over all unread conversations with a user based on the users email
151+
Intercom::Conversation.find_all(:email => '[email protected]', :type => 'user', :unread => true).each do {|convo| ... }
152+
153+
# FINDING A SINGLE CONVERSATION
154+
conversation = Intercom::Conversation.find(:id => '1')
155+
156+
# INTERACTING WITH THE PARTS OF A CONVERSATION
157+
# Getting the subject of a part (only applies to email-based conversations)
158+
conversation.rendered_message.subject
159+
# Get the part_type of the first part
160+
conversation.conversation_parts[0].part_type
161+
# Get the body of the second part
162+
conversation.conversation_parts[1].body
163+
164+
# REPLYING TO CONVERSATIONS
165+
# User (identified by email) replies with a comment
166+
conversation.reply(:type => 'user', :email => '[email protected]', :message_type => 'comment', :body => 'foo')
167+
# Admin (identified by email) replies with a comment
168+
conversation.reply(:type => 'admin', :email => '[email protected]', :message_type => 'comment', :body => 'bar')
78169
```
79170

80-
#### Notes
171+
#### Counts
81172
```ruby
82-
Intercom::Note.create(:email => "[email protected]", :body => "This is the text of the note")
173+
# Get Conversation per Admin
174+
conversation_counts_for_each_admin = Intercom::Count.conversation_counts_for_each_admin
175+
conversation_counts_for_each_admin.each{|count| puts "Admin: #{count.name} (id: #{count.id}) Open: #{count.open} Closed: #{count.closed}" }
176+
# Get User Tag Count Object
177+
Intercom::Count.user_counts_for_each_tag
178+
# Get User Segment Count Object
179+
Intercom::Count.user_counts_for_each_segment
180+
# Get Company Segment Count Object
181+
Intercom::Count.company_counts_for_each_segment
182+
# Get Company Tag Count Object
183+
Intercom::Count.company_counts_for_each_tag
184+
# Get Company User Count Object
185+
Intercom::Count.company_counts_for_each_user
186+
# Get total count of companies, users, segments or tags across app
187+
Intercom::Company.count
188+
Intercom::User.count
189+
Intercom::Segment.count
190+
Intercom::Tag.count
83191
```
84192

85-
#### Events
86-
The simplest way to create an event is directly on the user
193+
#### Full loading of and embedded entity
87194
```ruby
88-
user = Intercom::User.find_by_email("[email protected]")
89-
user.track_event("invited-friend")
195+
# Given a converation with a partial user, load the full user. This can be done for any entity
196+
conversation.user.load
90197
```
91198

92-
For more control create events through Intercom::Event
199+
#### Sending messages
93200
```ruby
94-
Intercom::Event.create(:event_name => "invited-friend", :user => user)
95201

96-
# With an explicit event creation date
97-
Intercom::Event.create(:event_name => "invited-friend", :user => user, :created_at => 1391691571)
202+
# InApp message from admin to user
203+
Intercom::Message.create({
204+
:message_type => 'inapp',
205+
:body => "What's up :)",
206+
:from => {
207+
:type => 'admin',
208+
:id => "1234"
209+
},
210+
:to => {
211+
:type => :user,
212+
:id => "5678"
213+
}
214+
})
98215

99-
# With metadata
100-
Intercom::Event.create(:event_name => "invited-friend", :user => user,
101-
metadata => {
102-
:invitee_email => '[email protected]',
103-
:invite_code => 'ADDAFRIEND'
216+
# Email message from admin to user
217+
Intercom::Message.create({
218+
:message_type => 'email',
219+
:subject => 'Hey there',
220+
:body => "What's up :)",
221+
:template => "plain", # or "personal",
222+
:from => {
223+
:type => "admin",
224+
:id => "1234"
225+
},
226+
:to => {
227+
:type => "user",
228+
:id => "536e564f316c83104c000020"
229+
}
230+
})
231+
232+
# Message from a user
233+
Intercom::Message.create({
234+
:from => {
235+
:type => "user",
236+
:id => "536e564f316c83104c000020"
237+
},
238+
:body => "halp"
239+
})
240+
```
241+
242+
#### Events
243+
```ruby
244+
Intercom::Event.create(
245+
:event_name => "invited-friend", :created_at => Time.now.to_i,
246+
:email => user.email,
247+
:metadata => {
248+
"invitee_email" => "[email protected]",
249+
:invite_code => "ADDAFRIEND",
250+
"found_date" => 12909364407
104251
}
105252
)
106253
```
107254

108-
Metadata Objects support a few simple types that Intercom can present on your behalf
255+
Metadata Objects support a few simple types that Intercom can present on your behalf
109256

110257
```ruby
111-
Intercom::Event.create(:event_name => "placed-order", :user => current_user,
112-
metadata => {
258+
Intercom::Event.create(:event_name => "placed-order", :email => current_user.email,
259+
:created_at => 1403001013
260+
:metadata => {
113261
:order_date => Time.now.to_i,
114-
:stripe_invoice => 'inv_3434343434',
115-
:order_number => {
116-
:value => '3434-3434',
117-
:url => 'https://example.org/orders/3434-3434'
262+
:stripe_invoice => 'inv_3434343434',
263+
:order_number => {
264+
:value => '3434-3434',
265+
:url => 'https://example.org/orders/3434-3434'
118266
},
119-
price: {
267+
price: {
120268
:currency => 'usd',
121-
:amount => 2999
122-
}
269+
:amount => 2999
270+
}
123271
}
124272
)
125273
```
@@ -131,9 +279,17 @@ The metadata key values in the example are treated as follows-
131279
- price: An Amount in US Dollars (value contains 'amount' and 'currency' keys)
132280

133281
### Errors
282+
You do not need to deal with the HTTP response from an API call directly. If there is an unsuccessful response then an error that is a subclass of Intercom:Error will be raised. If desired, you can get at the http_code of an Intercom::Error via it's `http_code` method.
283+
284+
The list of different error subclasses are listed below. As they all inherit off Intercom::Error you can choose to rescue Intercom::Error or
285+
else rescue the more specific error subclass.
286+
134287
```ruby
135288
Intercom::AuthenticationError
136289
Intercom::ServerError
137290
Intercom::ServiceUnavailableError
138291
Intercom::ResourceNotFound
292+
Intercom::BadRequestError
293+
Intercom::RateLimitExceeded
294+
Intercom::AttributeNotSetError # Raised when you try to call a getter that does not exist on an object
139295
```

changes.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2.0.0
2+
- Bumped to 2.0.0.
3+
14
1.0.0
25
- Bumped to a 1.0.0 version. No functional changes.
36

intercom.gemspec

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ require "intercom/version"
66
Gem::Specification.new do |spec|
77
spec.name = "intercom"
88
spec.version = Intercom::VERSION
9-
spec.authors = ["Ben McRedmond", "Ciaran Lee", "Darragh Curran", "Jeff Gardner", "Kyle Daigle", "Declan McGrath", "Jamie Osler"]
10-
9+
spec.authors = ["Ben McRedmond", "Ciaran Lee", "Darragh Curran", "Jeff Gardner", "Kyle Daigle", "Declan McGrath", "Jamie Osler", "Bob Long"]
10+
1111
spec.homepage = "https://www.intercom.io"
1212
spec.summary = %q{Ruby bindings for the Intercom API}
1313
spec.description = %Q{Intercom (https://www.intercom.io) is a customer relationship management and messaging tool for web app owners. This library wraps the api provided by Intercom. See http://docs.intercom.io/api for more details. }

lib/ext/hash.rb

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class Hash
2+
# Return a hash that includes everything but the given keys.
3+
def except(*keys)
4+
dup.except!(*keys)
5+
end
6+
7+
# Replaces the hash without the given keys.
8+
def except!(*keys)
9+
keys.each { |key| delete(key) }
10+
self
11+
end
12+
13+
# Return a hash that includes only the given keys.
14+
def slice(*keys)
15+
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
16+
keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
17+
end
18+
end

0 commit comments

Comments
 (0)