module DashFu
Use me to push data to Dash-fu in real time.
The only configuration you need is setting the API key in config/environments/production.rb:
DashFu.api_key = "<your API key>"
You only want to push data in production, so make sure the API key is only set in production environment. Calls to created/active with no API key are simply ignored.
You can send events by calling DashFu.push
with UID and event, or using the specialized created and active methods.
For example, to assign a user to a cohort, we’re going to notify Dash-fu whenever an acount gets created:
class User < ActiveRecord::Model after_create do DashFu.created id end end
In this example, we consider a user active whenever they post a status update, and notify Dash-fu accordingly:
class StatusUpdate < ActiveRecord::Model after_create do DashFu.active id end end
Attributes
Set the API key with:
DashFu.api_key = "<your API key>"
DashFu.host
is set by default, this is only useful for testing.
DashFu.host
is set by default, this is only useful for testing.
Public Class Methods
Records that a user has been active in the app.
# File lib/dash_fu.rb, line 142 def active(uid) push uid, "active" end
Close connection. If you like crossing your t’s you can call this when the app shutsdown.
# File lib/dash_fu.rb, line 154 def close @mutex.synchronize do socket, @socket = @socket, nil socket.close if socket end rescue Exception end
Records that a new user account has been created (associate them with cohort).
# File lib/dash_fu.rb, line 148 def created(uid) push uid, "created" end
Logs an activity. An activity has an actor (the user who performed the activity), the action performed (e.g. posted, commented) and the object of the action (e.g. the post).
You can call this method with actor, action and optional object (two or three arguments), or with a Hash with the keys actor, action, object and timestamp.
For example:
DashFu.log user, 'posted', post.title DashFu.log actor: user, action: 'posted', object: { content: post.title }
The actor argument is either the ID of a user, an object that responds to to_dashboard, or Hash with the following keys:
-
uid – User identifier (must be unique in application, required)
-
created – Date/time instance when user account was created
-
name – Display name
-
email – Email address
-
image – URL for profile photo
-
url – URL for profile
UID is required, all other properties are optional.
When using an object that responds to to_dashboard, the to_dashboard method must return a Hash with these keys.
The action argument is any string, e.g. ‘posted’, ‘commented’.
The object argument is either a string containing HTML markup, an object that respobds to to_dashboard, or Hash with the following keys:
-
content – HTML markup describing the object
HTML markup may use semantic styling elements such as b, em, p, blockquote. Styles and scripts are stripped, and only links to HTTP/S URLs are preserved.
When using an object that responds to to_dashboard, the to_dashboard method must return a Hash with these keys.
The timestamp argument is the date/time instance the activity occurred.
# File lib/dash_fu.rb, line 93 def log(*args) return unless @api_key # in test/dev mode, return quickly if args.length == 1 && args[0].respond_to?(:values_at) actor, action, object, timestamp = args[0].values_at(:actor, :action, :object, :timestamp) elsif args.length == 2 || args.length == 3 actor, action, object = *args else raise ArgumentError.new("Expected Hash or actor, action, (object)") end if actor.respond_to?(:to_dashboard) actor = actor.to_dashboard elsif String === actor actor = { uid: actor } end action = action.to_s if object.respond_to?(:to_dashboard) object = object.to_dashboard elsif String === object object = { content: object } end params = { actor: actor, action: action, object: object, timestamp: timestamp } json = MultiJson.encode(params) puts json if socket = @socket socket.sendmsg_nonblock "POST /v1/activity?api_key=#{@api_key} HTTP/1.1\r\nHost: #{@host}\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nContent-Length: #{json.length}\r\n\r\n#{json}", 0 socket.recv_nonblock 512 rescue nil else Thread.new do @mutex.synchronize do @socket ||= TCPSocket.open(@host, @port || 80) end log params end end rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT close retry rescue Errno::ECONNREFUSED, Errno::ENETUNREACH # No @socket so we'll try to connect next time end
Push update for the specified user ID and event. Or you can use active/created.
# File lib/dash_fu.rb, line 164 def push(uid, event) return unless @api_key if socket = @socket socket.sendmsg_nonblock "POST /v1/push?api_key=#{@api_key}&uid=#{uid}&event=#{event} HTTP/1.1\r\nHost: #{@host}\r\nConnection: keep-alive\r\nContent-Length: 0\r\n\r\n", 0 socket.recv_nonblock 512 rescue nil else Thread.new do @mutex.synchronize do @socket ||= TCPSocket.open(@host, @port || 80) end push uid, event end end rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ETIMEDOUT close retry rescue Errno::ECONNREFUSED, Errno::ENETUNREACH # No @socket so we'll try to connect next time end