Skip to content

Commit 13d7c47

Browse files
committed
Merge pull request #63 from intercom/user-event-release
Add user events
2 parents 3f8c345 + ed3bbd8 commit 13d7c47

File tree

9 files changed

+230
-3
lines changed

9 files changed

+230
-3
lines changed

changes.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
0.2.0
2+
- Add UserEvents.
3+
14
0.1.19
25
- Update DELETE request to fix issue.
36

lib/intercom.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "intercom/note"
77
require "intercom/tag"
88
require "intercom/request"
9+
require "intercom/user_event"
910
require "json"
1011

1112
##

lib/intercom/request.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def execute(target_base_url=nil)
6262
response = http.request(net_http_method)
6363
raise_errors_on_failure(response)
6464
decoded = decode(response['content-encoding'], response.body)
65-
JSON.parse(decoded)
65+
JSON.parse(decoded) unless decoded.empty?
6666
end
6767
rescue Timeout::Error
6868
raise Intercom::ServiceUnavailableError

lib/intercom/user.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,16 @@ def companies=(companies)
335335
raise ArgumentError.new("Companies requires an array of hashes of companies") unless companies.is_a?(Array) && companies.all? {|company| company.is_a?(Hash)}
336336
@attributes["companies"] = companies.collect {|company| FlatStore.new(company) }
337337
end
338+
339+
##
340+
# Creates a UserEvent for the given User
341+
# @param {Hash} options, keys for :created (Unix timestamp) and :company_id (String)
342+
def log_event(event_name, options={})
343+
attributes = {:event_name => event_name, :user => self}
344+
attributes[:created] = options[:created] unless options[:created].nil?
345+
attributes[:company_id] = options[:company_id] unless options[:company_id].nil?
346+
UserEvent.create(attributes)
347+
end
338348

339349
protected
340350
def social_profiles=(social_profiles) #:nodoc:

lib/intercom/user_event.rb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
require 'intercom/requires_parameters'
2+
require 'intercom/hashable_object'
3+
4+
5+
module Intercom
6+
7+
##
8+
# Represents a User Event
9+
#
10+
# A user event consists of an event_name and a user the event applies to. The user is identified via email or id.
11+
# Additionally, a created timestamp is required.
12+
#
13+
# == Examples
14+
#
15+
# user_event = Intercom::UserEvent.create(:event_name => "post", :user => current_user, :created => Time.now)
16+
#
17+
# You can also create an user-event and save it like this:
18+
# user_event = Intercom::UserEvent.new
19+
# user_event.event_name = "publish-post"
20+
# user_event.user = current_user
21+
# user_event.created = Time.now
22+
# user_event.metadata = {
23+
# :title => 'Gravity Review',
24+
# :link => 'https://example.org/posts/22',
25+
# :comments => 'https://example.org/posts/22/comments'
26+
# }
27+
# user_event.save
28+
#
29+
# == Batch
30+
#
31+
# User events can be created in batches, and sent as one request. To do some, create user events
32+
# without calling .create, as follows:
33+
#
34+
# user_event = Intercom::UserEvent.new
35+
# user_event.event_name = "publish-post"
36+
# user_event.user = current_user
37+
#
38+
# Then pass them to the save_batch_events class method, along with an (optional) default user:
39+
#
40+
# Intercom::UserEvent.save_batch_events(events, default_user)
41+
#
42+
# Any events without a user will be assigned to the default_user.
43+
#
44+
# Note: if you do not supply a created time, the current time in UTC will be used. Events that have the same
45+
# user, name, and created time (to second granularity) may be treated as duplicates by the server.
46+
47+
class UserEvent
48+
extend RequiresParameters
49+
include HashableObject
50+
51+
attr_accessor :event_name, :user, :created_at # required
52+
attr_accessor :metadata, :type
53+
54+
def initialize(attributes={})
55+
from_hash(attributes)
56+
end
57+
58+
##
59+
# Creates a new User Event using params and saves it
60+
# @see #save
61+
def self.create(params)
62+
params[:created_at] ||= Time.now
63+
requires_parameters(params, %W(event_name user created_at))
64+
UserEvent.new(params).save
65+
end
66+
67+
##
68+
# Save the User Event
69+
def save
70+
raise ArgumentError.new("Missing User") if user.nil?
71+
UserEvent.save_batch_events([self])
72+
self
73+
end
74+
75+
##
76+
# Save a list of User Events, with an optional base_user
77+
def self.save_batch_events(events, base_user=nil)
78+
hash = { :type => 'event.list', :data => []}
79+
hash[:user] = { :user_id => base_user.user_id } if base_user
80+
events.each do |event|
81+
hash[:data] << event.event_hash
82+
end
83+
post_to_intercom(hash)
84+
end
85+
86+
def self.post_to_intercom(hash)
87+
Intercom.post('/events', hash)
88+
end
89+
90+
def user_hash
91+
{ :user_id => user.user_id }
92+
end
93+
94+
def event_hash
95+
event = { :event_name => event_name, :created => created_at.nil? ? Time.now.utc.to_i : created_at.to_i }
96+
event[:type] = type.nil? ? 'event' : type
97+
event[:user] = user_hash unless user.nil?
98+
event[:metadata] = metadata unless metadata.nil?
99+
event
100+
end
101+
end
102+
end

lib/intercom/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Intercom #:nodoc:
2-
VERSION = "0.1.19"
2+
VERSION = "0.2.0"
33
end

spec/integration/intercom_api_integration_spec.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,37 @@ def fixture(name)
6969
note.html.must_equal "<p>This is a note</p>"
7070
note.user.email.must_equal "[email protected]"
7171
end
72-
72+
73+
it "should create a user event" do
74+
FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
75+
user = Intercom::User.find(:email => "[email protected]")
76+
FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"])
77+
Intercom::UserEvent.create(:event_name => "signup", :created_at => 1391691571, :user => user).event_name.must_equal "signup"
78+
end
79+
80+
it "should create batch user events" do
81+
FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
82+
user = Intercom::User.find(:email => "[email protected]")
83+
84+
first_event = Intercom::UserEvent.new
85+
first_event.event_name = "first event"
86+
first_event.created_at = Time.now
87+
first_event.user = user
88+
89+
second_event = Intercom::UserEvent.new
90+
second_event.event_name = "second event"
91+
second_event.created_at = Time.now
92+
93+
FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"])
94+
Intercom::UserEvent.save_batch_events([first_event, second_event], user)
95+
end
96+
97+
it "should create a user event from a user" do
98+
FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
99+
user = Intercom::User.find(:email => "[email protected]")
100+
FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"])
101+
user.log_event("signup").event_name.must_equal "signup"
102+
end
73103

74104
it "should failover to good endpoint when first one is un-reachable" do
75105
FakeWeb.allow_net_connect = %r(127.0.0.7)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
require 'spec_helper'
2+
3+
describe "Intercom::UserEvent" do
4+
5+
let (:user) {Intercom::User.new("email" => "[email protected]", :user_id => "12345", :created_at => Time.now, :name => "Jim Bob")}
6+
let (:created_time) {Time.now - 300}
7+
8+
it "creates a user event" do
9+
Intercom.expects(:post).with("/events",
10+
{ :type => 'event.list',
11+
:data => [ {:event_name => "signup", :created => created_time.to_i, :type => 'event',
12+
:user => { :user_id => user.user_id}, :metadata => {:some => "data"}
13+
}]}).returns(:status => 200)
14+
15+
Intercom::UserEvent.create({ :event_name => "signup", :user => user, :created_at => created_time, :metadata => {:some => "data"} })
16+
end
17+
18+
it 'automatically adds a created time upon creation' do
19+
Intercom.expects(:post).with("/events",
20+
{ :type => 'event.list',
21+
:data => [ {:event_name => "sale of item", :created => Time.now.to_i, :type => 'event', :user => { :user_id => user.user_id}
22+
}]}).returns(:status => 200)
23+
24+
Intercom::UserEvent.create({ :event_name => "sale of item", :user => user })
25+
end
26+
27+
it "creates a user event with metadata" do
28+
Intercom.expects(:post).with("/events",
29+
{ :type => 'event.list',
30+
:data => [ {:event_name => "signup", :created => created_time.to_i, :type => 'event', :user => { :user_id => user.user_id}, :metadata => { :something => "here"}
31+
}]}).returns(:status => 200)
32+
Intercom::UserEvent.create({ :event_name => "signup", :user => user, :created_at => created_time, :metadata => { :something => "here"} })
33+
end
34+
35+
it 'fails when no user supplied' do
36+
user_event = Intercom::UserEvent.new
37+
user_event.event_name = "some event"
38+
user_event.created_at = Time.now
39+
proc { user_event.save }.must_raise ArgumentError, "Missing User"
40+
end
41+
42+
describe 'while batching events' do
43+
44+
let (:event1) do
45+
user_event = Intercom::UserEvent.new
46+
user_event.event_name = "first event"
47+
user_event.created_at = Time.now
48+
user_event.user = user
49+
user_event
50+
end
51+
52+
let (:event2) do
53+
user_event = Intercom::UserEvent.new
54+
user_event.event_name = "second event"
55+
user_event.created_at = Time.now
56+
user_event
57+
end
58+
59+
it 'creates batched events' do
60+
Intercom.expects(:post).with("/events",
61+
{ :type => 'event.list',
62+
:data => [
63+
{:event_name => "first event", :created => event1.created_at.to_i,
64+
:type => 'event', :user => {:user_id => user.user_id}},
65+
{:event_name => "second event", :created => event2.created_at.to_i,
66+
:type => 'event'},
67+
],
68+
:user => { :user_id => user.user_id}}).returns(:status => 200)
69+
Intercom::UserEvent.save_batch_events([event1, event2], user)
70+
end
71+
end
72+
end

spec/unit/intercom/user_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,13 @@
262262
first_company_as_hash["created_at"].must_equal time.to_i
263263
second_company_as_hash["created_at"].must_equal time.to_i
264264
end
265+
266+
it "logs user events" do
267+
user = Intercom::User.new("email" => "[email protected]", :user_id => "12345", :created_at => Time.now, :name => "Jim Bob")
268+
Intercom::UserEvent.expects(:create).with(:event_name => 'registration', :user => user)
269+
event = user.log_event('registration')
270+
271+
Intercom::UserEvent.expects(:create).with(:event_name => 'another', :user => user, :created => 1391691571, :company_id => "6")
272+
event = user.log_event("another", {:created => 1391691571, :company_id => "6"})
273+
end
265274
end

0 commit comments

Comments
 (0)