Working with events

Understanding your users

So far in this series we've focused on importing and configuring our user data on the Intercom platform.

Earlier, we created new users and added data to these profiles. This data represented the facts we know about our users such as when they signed up, when they were last seen, what they purchased last and so on. In this way it represents static data or facts on your users.

In this tutorial we're going to look at ways to understand your users through their behavior and the actions they take - called events. You can think of this as the dynamic data for your users - it's constantly changing as your users move through your site or use your app. They will use features, purchase items or execute any other numbers of actions specific to your environment. You can find more information on events and some example use cases here.

Creating basic events

To start with, let's submit a basic event and then view it in your web app. You can find more information on the events API here in the API docs.

We need to provide some information when submitting an event, such as the event name, the time it was created and a user_id or email to identify which user the event belongs to. For example:

intercom.events.create(
  :event_name => "wrote-fear-and-trembling", 
  :created_at => Time.now.to_i, 
  :email => "[email protected]")

Now let's create a simple method which allows us to easily submit events. One way to do this is to let users just pass in the relevant information for an event. We can the create the hash inside the method to submit with the event.

Create an event

require './intercom_client' #Need to init client
require './user_tasks' #Need to re-use the user tasks

class EventTasks < IntercomClient
  def initialize()
    #Override initialize in IntercomClient
  end

  def submit_event(event_name, submit_time, criteria)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)

    #create a hash to pass through to the event API
    event = {:event_name => event_name,
             :created_at => submit_time,
             :email => usr.email}

    @@intercom.events.create(event)
  end
end

We can then create a new event as follows:

> require './event_tasks'
=> true
> intercom = IntercomClient.new('<YOUR ACCESS TOKEN>')
=> #<IntercomClient:0x0000000113ae38>
> event = EventTasks.new()
=> #<EventTasks:0x000000010dd418>
> event.submit_event("wrote-fear-and-trembling", Time.now.to_i, "[email protected]")
=> nil

To view the event you can go to user profile for the relevant user and you should see the event on the right hand side similar to below:

434

Viewing an Event in the users profile

What happens if we send another event with the same name and a different timestamp?

> event.submit_event("wrote-fear-and-trembling", Time.now.to_i, "[email protected]")
=> nil

Again, let's check the user profile to see if there is a new event

464

Adding another event with a newer date

Similarly, if we submit a new event with a different event name:

> event.submit_event("wrote-either-or", Time.now.to_i, 10)
=> nil
473

Adding a new event

Creating events with metadata

Now that we have created some events, we have an idea about how they work and how you can view them in your app.

We can make these events richer by adding metadata to them. You can add up to five separate entries as part of the metadata you pass with an event. You can find some more info on what type of metadata attributes we support here].

For now, let's simply pass the metadata attributes in a hash. We can make the parameter optional in our submit_event method so that we can pass it in as needed. Your submit method should look like this now:

def submit_event(name, time, criteria, meta_data=false)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)

    #create a hash to pass through to the event API
    event = {:event_name => name,
             :created_at => time,
             :email => usr.email}

    #Check if we need to add metadata to the event
    if metadata
      event[:metadata] = meta_data
    end

    @@intercom.events.create(event)
  end
require './intercom_client'
require './user_tasks'

class EventTasks < IntercomClient
  def initialize()
    #Override initialize in IntercomClient
  end

  def submit_event(name, time, criteria, meta_data=false)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)

    #create a hash to pass through to the event API
    event = {:event_name => name,
             :created_at => time,
             :email => usr.email}

    #Check if we need to add metadata to the event
    if metadata
      event[:metadata] = meta_data
    end

    @@intercom.events.create(event)
  end
end

Let's create an event with some metadata. Remember, we have now added an optional parameter to the submit_event method so you will need to reference the parameter name when you pass it through in the method call:

> require './event_tasks'
=> true
> intercom = IntercomClient.new('<YOUR ACCESS TOKEN>')
=> #<IntercomClient:0x0000000311c558>
> event = EventTasks.new()
=> #<EventTasks:0x000000030c0b40>
> metadata = {"book-type" => "philosophy", :pages => 265, "publication_date" => -3808119527}
=> {"book-type"=>"philosophy", :pages=>265, "publication_date"=>-3808119527}
> event.submit_event("The Sickness Unto Death", Time.now.to_i, 12, meta_data=metadata)

Then you should be able to see the metadata when you expand the event in the user's profile:

464

The metadata objects can also have some specific data types such as links, monetary amounts and Stripe data. These are passed as part of the metadata attribute.

For your custom implementation you could create a simple wrapper around the submit_event method which formats your specific values into a metadata hash and then calls the submit_event to pass in this hash object. However, since this would be specific to your implementation we will not set this up in this tutorial.

Listing your events

Now that you have created some events, you may want to view events for a particular user. We can do this by listing all events for a particular user:

def list_events(criteria)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)
    @@intercom.get("/events", type:"user", user_id:usr.user_id)
  end
require './intercom_client'
require './user_tasks'

class EventTasks < IntercomClient
  def initialize()
    #Override initialize in IntercomClient
  end

  def submit_event(name, time, criteria, meta_data=false)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)

    #create a hash to pass through to the event API
    event = {:event_name => name,
             :created_at => time,
             :email => usr.email}

    #Check if we need to add metadata to the event
    if meta_data
      event[:metadata] = meta_data
    end

    @@intercom.events.create(event)
  end

  def list_events(criteria)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)
    @@intercom.get("/events", type:"user", user_id:usr.user_id)
  end
end
> require './event_tasks'
=> true
> intercom = IntercomClient.new('<YOUR ACCESS TOKEN>')
=> #<IntercomClient:0x00000001f451b8>
> event = EventTasks.new()
=> #<EventTasks:0x00000001efb888>
> events = event.list_events("[email protected]")
=> {"type"=>"event.list",
 "events"=>
  [{"type"=>"event",
    "id"=>"8edcf114-0e0c-11e6-b74b-4722c3fbb38f",
    "created_at"=>1461935778,
    "event_name"=>"the sickness unto death",
    "user_id"=>"12",
    "email"=>"[email protected]",
    "intercom_user_id"=>"572356ea29620415c0000002",
    "metadata"=>{"book-type"=>"philosophy", "pages"=>265, "publication_date"=>-3808119527}},
   {"type"=>"event",
    "id"=>"6b12d2d0-0e0c-11e6-a518-6d45532e04c8",
    "created_at"=>1461935718,
    "event_name"=>"wrote-either-or",
    "user_id"=>"12",
    "email"=>"[email protected]",
    "intercom_user_id"=>"572356ea29620415c0000002",
    "metadata"=>{}},
   {"type"=>"event",
    "id"=>"62275740-0e0c-11e6-8818-2d648797dc56",
    "created_at"=>1461935703,
    "event_name"=>"wrote-fear-and-trembling",
    "user_id"=>"12",
    "email"=>"[email protected]",
    "intercom_user_id"=>"572356ea29620415c0000002",
    "metadata"=>{}},
   {"type"=>"event",
    "id"=>"5fc2f496-0e0c-11e6-86ac-11880bfb2cd6",
    "created_at"=>1461935699,
    "event_name"=>"wrote-fear-and-trembling",
    "user_id"=>"12",
    "email"=>"[email protected]",
    "intercom_user_id"=>"572356ea29620415c0000002",
    "metadata"=>{}}],
 "pages"=>{"since"=>"https://api.intercom.io/events?intercom_user_id=572356ea29620415c0000002&type=user&since=1461935778061"}}

list_events will return you a Ruby Hash. This means you can parse through it as follows if you simply wanted to look at each element individually. You can find more information here which describes the return object in more detail.

> puts events["type"]
event.list
> puts events["events"]
{"type"=>"event", "id"=>"8edcf114-0e0c-11e6-b74b-4722c3fbb38f", "created_at"=>1461935778, "event_name"=>"the sickness unto death", "user_id"=>"12", "email"=>"[email protected]", "intercom_user_id"=>"572356ea29620415c0000002", "metadata"=>{"book-type"=>"philosophy", "pages"=>265, "publication_date"=>-3808119527}}
{"type"=>"event", "id"=>"6b12d2d0-0e0c-11e6-a518-6d45532e04c8", "created_at"=>1461935718, "event_name"=>"wrote-either-or", "user_id"=>"12", "email"=>"[email protected]", "intercom_user_id"=>"572356ea29620415c0000002", "metadata"=>{}}
{"type"=>"event", "id"=>"62275740-0e0c-11e6-8818-2d648797dc56", "created_at"=>1461935703, "event_name"=>"wrote-fear-and-trembling", "user_id"=>"12", "email"=>"[email protected]", "intercom_user_id"=>"572356ea29620415c0000002", "metadata"=>{}}
{"type"=>"event", "id"=>"5fc2f496-0e0c-11e6-86ac-11880bfb2cd6", "created_at"=>1461935699, "event_name"=>"wrote-fear-and-trembling", "user_id"=>"12", "email"=>"[email protected]", "intercom_user_id"=>"572356ea29620415c0000002", "metadata"=>{}}
> puts events["pages"]
{"since"=>"https://api.intercom.io/events?intercom_user_id=572356ea29620415c0000002&type=user&since=1461935778061"}
> events['events'].each {|event| puts event['event_name']}
metadata_test
test2
test
test
> events['events'].each {|event| puts event['metadata'] if event['metadata'].size > 0}
{"invitee_email"=>"[email protected]", "invite_code"=>"ADDAFRIEND", "found_date"=>12909364407}
)> events['events'].each {|event| event['metadata'].each {|key, val| puts "#{event['event_name']} #{key}:#{val}"} if event['metadata'].size > 0}
metadata_test invitee_email:[email protected]
metadata_test invite_code:ADDAFRIEND
metadata_test found_date:12909364407

Bulk creating events

There is also a bulk create action available to enable you to create a large number of events in one go. As with the metadata creation earlier, we will simply pass the information through to the bulk create job via an array. This will allow you to create your own lists to pass through as bulk jobs. You can also add to jobs which are already in progress, so we will include an optional parameter to pass though an active job id if needed.

def bulk_create(events, job=false)
    if job
      @@intercom.events.submit_bulk_job(create_items: events)
    else
      @@intercom.events.submit_bulk_job(create_items: events, job_id: job)
    end
  end
require './intercom_client'
require './user_tasks'

class EventTasks < IntercomClient
  def initialize()
    #Override initialize in IntercomClient
  end

  def submit_event(name, time, criteria, meta_data=false)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)

    #create a hash to pass through to the event API
    event = {:event_name => name,
             :created_at => time,
             :email => usr.email}

    #Check if we need to add metadata to the event
    if meta_data
      event[:metadata] = meta_data
    end

    @@intercom.events.create(event)
  end

  def list_events(criteria)
    #First check if the user exists,
    #It will throw an exception if it fails to find a user
    user = UserTasks.new()
    usr = user.find_user(criteria)
    @@intercom.get("/events", type:"user", user_id:usr.user_id)
  end

  def bulk_create(events, job=false)
    if job
      @@intercom.events.submit_bulk_job(create_items: events)
    else
      @@intercom.events.submit_bulk_job(create_items: events, job_id: job)
    end
  end
end

We can construct a sample array and pass it though to create multiple events in one submit:

> test =[{event_name: "purchased-book", created_at: 1438944980,user_id: "13",metadata: {order_date: 1438944980,stripe_invoice: "inv_3434343434"}}, {event_name: "invited-philosopher", created_at: 1438944979, user_id: "14",metadata: {invitee_email: "[email protected]",invite_code: "ADDPHILOSOPHER"} }]
=> [{:event_name=>"purchased-book", :created_at=>1438944980, :user_id=>"13", :metadata=>{:order_date=>1438944980, :stripe_invoice=>"inv_3434343434"}},
 {:event_name=>"invited-philosopher", :created_at=>1438944979, :user_id=>"14", :metadata=>{:invitee_email=>"[email protected]", :invite_code=>"ADDPHILOSOPHER"}}]
> event.bulk_create(test)
=> #<Intercom::Job:0x000000019d7438
> intercom.events.submit_bulk_job(create_items: test2, job_id: "job_1ae8fcf0_0c84_11e6_bbc5_674050eb5363")
=> #<Intercom::Job:0x00000003129c30