Module: DashFu
- Defined in:
- lib/dash_fu.rb
Overview
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
Class Attribute Summary collapse
-
.api_key ⇒ Object
Set the API key with: DashFu.api_key = “<your API key>”.
-
.host ⇒ Object
DashFu.host is set by default, this is only useful for testing.
-
.port ⇒ Object
DashFu.host is set by default, this is only useful for testing.
Class Method Summary collapse
-
.active(uid) ⇒ Object
Records that a user has been active in the app.
-
.close ⇒ Object
Close connection.
-
.created(uid) ⇒ Object
Records that a new user account has been created (associate them with cohort).
-
.log(*args) ⇒ Object
Logs an activity.
-
.push(uid, event) ⇒ Object
Push update for the specified user ID and event.
Class Attribute Details
.api_key ⇒ Object
Set the API key with:
DashFu.api_key = "<your API key>"
47 48 49 |
# File 'lib/dash_fu.rb', line 47 def api_key @api_key end |
.host ⇒ Object
DashFu.host is set by default, this is only useful for testing.
43 44 45 |
# File 'lib/dash_fu.rb', line 43 def host @host end |
.port ⇒ Object
DashFu.host is set by default, this is only useful for testing.
43 44 45 |
# File 'lib/dash_fu.rb', line 43 def port @port end |
Class Method Details
.active(uid) ⇒ Object
Records that a user has been active in the app.
142 143 144 |
# File 'lib/dash_fu.rb', line 142 def active(uid) push uid, "active" end |
.close ⇒ Object
Close connection. If you like crossing your t’s you can call this when the app shutsdown.
154 155 156 157 158 159 160 |
# File 'lib/dash_fu.rb', line 154 def close @mutex.synchronize do socket, @socket = @socket, nil socket.close if socket end rescue Exception end |
.created(uid) ⇒ Object
Records that a new user account has been created (associate them with cohort).
148 149 150 |
# File 'lib/dash_fu.rb', line 148 def created(uid) push uid, "created" end |
.log(*args) ⇒ Object
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.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# 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, = 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: } 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(uid, event) ⇒ Object
Push update for the specified user ID and event. Or you can use active/created.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# 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 |