class Eventflit::Client
Attributes
Public Class Methods
Loads the configuration from an url in the environment
# File lib/eventflit/client.rb, line 13 def self.from_env(key = 'EVENTFLIT_URL') url = ENV[key] || raise(ConfigurationError, key) from_url(url) end
Loads the configuration from a url
# File lib/eventflit/client.rb, line 19 def self.from_url(url) client = new client.url = url client end
# File lib/eventflit/client.rb, line 25 def initialize(options = {}) default_options = { :scheme => 'http', :port => 80, } merged_options = default_options.merge(options) if options.has_key?(:host) merged_options[:host] = options[:host] elsif options.has_key?(:cluster) merged_options[:host] = "api-#{options[:cluster]}.eventflit.com" else merged_options[:host] = "service.eventflit.com" end # TODO: Change host name when finalized merged_options[:notification_host] = options.fetch(:notification_host, "push.eventflit.com") merged_options[:notification_scheme] = options.fetch(:notification_scheme, "https") @scheme, @host, @port, @app_id, @key, @secret, @notification_host, @notification_scheme = merged_options.values_at( :scheme, :host, :port, :app_id, :key, :secret, :notification_host, :notification_scheme ) @http_proxy = nil self.http_proxy = options[:http_proxy] if options[:http_proxy] # Default timeouts @connect_timeout = 5 @send_timeout = 5 @receive_timeout = 5 @keep_alive_timeout = 30 end
Public Instance Methods
Generate the expected response for an authentication endpoint. See docs.eventflit.com/authenticating_users for details.
@example Private channels
render :json => Eventflit.authenticate('private-my_channel', params[:socket_id])
@example Presence channels
render :json => Eventflit.authenticate('presence-my_channel', params[:socket_id], { :user_id => current_user.id, # => required :user_info => { # => optional - for example :name => current_user.name, :email => current_user.email } })
@param socket_id [String] @param custom_data [Hash] used for example by private channels
@return [Hash]
@raise [Eventflit::Error] if channel_name or socket_id are invalid
@private Custom data is sent to server as JSON-encoded string
# File lib/eventflit/client.rb, line 357 def authenticate(channel_name, socket_id, custom_data = nil) channel_instance = channel(channel_name) channel_instance.authenticate(socket_id, custom_data) end
@private Returns the authentication token for the client
# File lib/eventflit/client.rb, line 63 def authentication_token raise ConfigurationError, :key unless @key raise ConfigurationError, :secret unless @secret Pusher::Signature::Token.new(@key, @secret) end
Return a convenience channel object by name that delegates operations on a channel. No API request is made.
@example
Eventflit['my-channel']
@return [Channel] @raise [Eventflit::Error] if the channel name is invalid.
Channel names should be less than 200 characters, and should not contain anything other than letters, numbers, or the characters "_\-=@,.;"
# File lib/eventflit/client.rb, line 213 def channel(channel_name) Channel.new(nil, channel_name, self) end
Request
info for a specific channel
@param channel_name [String] Channel
name (max 200 characters) @param params [Hash] Hash of parameters for the API - see REST API docs
@return [Hash] See Eventflit
API docs
@raise [Eventflit::Error] Unsuccessful response - see the error message @raise [Eventflit::HTTPError] Error
raised inside http client. The original error is wrapped in error.original_error
# File lib/eventflit/client.rb, line 246 def channel_info(channel_name, params = {}) get("/channels/#{channel_name}", params) end
Request
info for users of a presence channel
@param channel_name [String] Channel
name (max 200 characters) @param params [Hash] Hash of parameters for the API - see REST API docs
@return [Hash] See Eventflit
API docs
@raise [Eventflit::Error] Unsuccessful response - see the error message @raise [Eventflit::HTTPError] Error
raised inside http client. The original error is wrapped in error.original_error
# File lib/eventflit/client.rb, line 262 def channel_users(channel_name, params = {}) get("/channels/#{channel_name}/users", params) end
Request
a list of occupied channels from the API
GET /apps//channels
@param params [Hash] Hash of parameters for the API - see REST API docs
@return [Hash] See Eventflit
API docs
@raise [Eventflit::Error] Unsuccessful response - see the error message @raise [Eventflit::HTTPError] Error
raised inside http client. The original error is wrapped in error.original_error
# File lib/eventflit/client.rb, line 230 def channels(params = {}) get('/channels', params) end
# File lib/eventflit/client.rb, line 125 def cluster=(cluster) @host = "api-#{cluster}.eventflit.com" end
@private Construct an em-http-request http client
# File lib/eventflit/client.rb, line 377 def em_http_client(uri) begin unless defined?(EventMachine) && EventMachine.reactor_running? raise Error, "In order to use async calling you must be running inside an eventmachine loop" end require 'em-http' unless defined?(EventMachine::HttpRequest) connection_opts = { :connect_timeout => @connect_timeout, :inactivity_timeout => @receive_timeout, } if defined?(@proxy) proxy_opts = { :host => @proxy[:host], :port => @proxy[:port] } if @proxy[:user] proxy_opts[:authorization] = [@proxy[:user], @proxy[:password]] end connection_opts[:proxy] = proxy_opts end EventMachine::HttpRequest.new(uri, connection_opts) end end
Configure whether Eventflit
API calls should be made over SSL (default false)
@example
Eventflit.encrypted = true
# File lib/eventflit/client.rb, line 115 def encrypted=(boolean) @scheme = boolean ? 'https' : 'http' # Configure port if it hasn't already been configured @port = boolean ? 443 : 80 end
# File lib/eventflit/client.rb, line 121 def encrypted? @scheme == 'https' end
GET arbitrary REST API resource using a synchronous http client. All request signing is handled automatically.
@example
begin Eventflit.get('/channels', filter_by_prefix: 'private-') rescue Eventflit::Error => e # Handle error end
@param path [String] Path excluding /apps/APP_ID @param params [Hash] API params (see docs.eventflit.com/rest_api)
@return [Hash] See Eventflit
API docs
@raise [Eventflit::Error] Unsuccessful response - see the error message @raise [Eventflit::HTTPError] Error
raised inside http client. The original error is wrapped in error.original_error
# File lib/eventflit/client.rb, line 159 def get(path, params = {}) resource(path).get(params) end
GET arbitrary REST API resource using an asynchronous http client. All request signing is handled automatically.
When the eventmachine reactor is running, the em-http-request gem is used; otherwise an async request is made using httpclient. See README for details and examples.
@param path [String] Path excluding /apps/APP_ID @param params [Hash] API params (see docs.eventflit.com/rest_api)
@return Either an EM::DefaultDeferrable or a HTTPClient::Connection
# File lib/eventflit/client.rb, line 175 def get_async(path, params = {}) resource(path).get_async(params) end
# File lib/eventflit/client.rb, line 96 def http_proxy=(http_proxy) @http_proxy = http_proxy uri = URI.parse(http_proxy) @proxy = { :scheme => uri.scheme, :host => uri.host, :port => uri.port, :user => uri.user, :password => uri.password } @http_proxy end
# File lib/eventflit/client.rb, line 314 def notification_client @notification_client ||= NativeNotification::Client.new(@app_id, @notification_host, @notification_scheme, self) end
Send a push notification
POST /apps//notifications
@param interests [Array] An array of interests @param message [String] Message to send @param options [Hash] Additional platform specific options
@return [Hash]
# File lib/eventflit/client.rb, line 329 def notify(interests, data = {}) notification_client.notify(interests, data) end
POST arbitrary REST API resource using a synchronous http client. Works identially to get method, but posts params as JSON in post body.
# File lib/eventflit/client.rb, line 181 def post(path, params = {}) resource(path).post(params) end
POST arbitrary REST API resource using an asynchronous http client. Works identially to get_async
method, but posts params as JSON in post body.
# File lib/eventflit/client.rb, line 188 def post_async(path, params = {}) resource(path).post_async(params) end
INTERACT WITH THE API ##
# File lib/eventflit/client.rb, line 137 def resource(path) Resource.new(self, path) end
@private Construct a net/http http client
# File lib/eventflit/client.rb, line 363 def sync_http_client @client ||= begin require 'httpclient' HTTPClient.new(@http_proxy).tap do |c| c.connect_timeout = @connect_timeout c.send_timeout = @send_timeout c.receive_timeout = @receive_timeout c.keep_alive_timeout = @keep_alive_timeout end end end
Convenience method to set all timeouts to the same value (in seconds). For more control, use the individual writers.
# File lib/eventflit/client.rb, line 131 def timeout=(value) @connect_timeout, @send_timeout, @receive_timeout = value, value, value end
Trigger an event on one or more channels
POST /apps//events
@param channels [String or Array] 1-10 channel names @param event_name [String] @param data [Object] Event data to be triggered in javascript.
Objects other than strings will be converted to JSON
@param params [Hash] Additional parameters to send to api, e.g socket_id
@return [Hash] See Eventflit
API docs
@raise [Eventflit::Error] Unsuccessful response - see the error message @raise [Eventflit::HTTPError] Error
raised inside http client. The original error is wrapped in error.original_error
# File lib/eventflit/client.rb, line 281 def trigger(channels, event_name, data, params = {}) post('/events', trigger_params(channels, event_name, data, params)) end
Trigger an event on one or more channels asynchronously. For parameters see trigger
# File lib/eventflit/client.rb, line 303 def trigger_async(channels, event_name, data, params = {}) post_async('/events', trigger_params(channels, event_name, data, params)) end
Trigger multiple events at the same time
POST /apps//batch_events
@param events [Array] List of events to publish
@return [Hash] See Eventflit
API docs
@raise [Eventflit::Error] Unsuccessful response - see the error message @raise [Eventflit::HTTPError] Error
raised inside http client. The original error is wrapped in error.original_error
# File lib/eventflit/client.rb, line 296 def trigger_batch(*events) post('/batch_events', trigger_batch_params(events.flatten)) end
Trigger multiple events asynchronously. For parameters see trigger_batch
# File lib/eventflit/client.rb, line 310 def trigger_batch_async(*events) post_async('/batch_events', trigger_batch_params(events.flatten)) end
@private Builds a url for this app, optionally appending a path
# File lib/eventflit/client.rb, line 70 def url(path = nil) raise ConfigurationError, :app_id unless @app_id URI::Generic.build({ :scheme => @scheme, :host => @host, :port => @port, :path => "/apps/#{@app_id}#{path}" }) end
Configure Eventflit
connection by providing a url rather than specifying scheme, key, secret, and app_id
separately.
@example
Eventflit.url = http://KEY:SECRET@service.eventflit.com/apps/APP_ID
# File lib/eventflit/client.rb, line 86 def url=(url) uri = URI.parse(url) @scheme = uri.scheme @app_id = uri.path.split('/').last @key = uri.user @secret = uri.password @host = uri.host @port = uri.port end
Convenience method for creating a new WebHook
instance for validating and extracting info from a received WebHook
@param request [Rack::Request] Either a Rack::Request or a Hash containing :key, :signature, :body, and optionally :content_type.
# File lib/eventflit/client.rb, line 199 def webhook(request) WebHook.new(request, self) end
Private Instance Methods
# File lib/eventflit/client.rb, line 433 def configured? host && scheme && key && secret && app_id end
JSON-encode the data if it's not a string
# File lib/eventflit/client.rb, line 428 def encode_data(data) return data if data.is_a? String MultiJson.encode(data) end
# File lib/eventflit/client.rb, line 417 def trigger_batch_params(events) { batch: events.map do |event| event.dup.tap do |e| e[:data] = encode_data(e[:data]) end end } end
# File lib/eventflit/client.rb, line 406 def trigger_params(channels, event_name, data, params) channels = Array(channels).map(&:to_s) raise Eventflit::Error, "Too many channels (#{channels.length}), max 10" if channels.length > 10 params.merge({ name: event_name, channels: channels, data: encode_data(data), }) end