require 'PushRadar/version' require 'PushRadar/Targeting' require 'PushRadar/APIClient' require 'json' module PushRadar # A realtime push notifications API service for the web, featuring advanced targeting class Radar # ------------------------------ # Initialisation & configuration # ------------------------------ # Creates a new instance of PushRadar with the specified API secret def initialize(api_secret) # Initialize data @data = {} # Reset the targeting options reset_targeting # Check that the API secret is a string unless api_secret.is_a?(String) raise 'The API secret must be a string value.' end # Trim the API secret api_secret.strip! # If we are running unit tests, set the unit test mode flag and skip the PushRadar API client initialisation @is_unit_test_mode = (api_secret == 'test-secret') # Check that the API secret starts with sk_ unless api_secret.start_with?('sk_') raise 'API secret invalid. You can view your PushRadar API secret at https://dashboard.pushradar.com/api' end # Make a new instance of a PushRadar API client with the specified API secret @api_client = APIClient.new(api_secret) end # ------------------------------ # Browser targeting # ------------------------------ # Targets the notification to clients currently using the given browser def target_browser(browser) # Add the browser to the list of target browsers @targeting.target_browser browser # Allow method chaining self end # Targets the notification to clients currently using any of the given browsers def target_browsers(*browsers) # Target each browser browsers.each {|x| target_browser x } # Allow method chaining self end # ------------------------------ # Country targeting # ------------------------------ # Targets the notification to clients currently located in the given country def target_country(country_code) # Add the country to the list of target countries @targeting.target_country country_code # Allow method chaining self end # Targets the notification to clients currently located in any of the given countries def target_countries(*country_codes) # Target each country country_codes.each {|x| target_country x } # Allow method chaining self end # ------------------------------ # Continent targeting # ------------------------------ # Targets the notification to clients currently located in Asia def target_asia # Target the continent @targeting.target_continent('AS') # Allow method chaining self end # Targets the notification to clients currently located in Africa def target_africa # Target the continent @targeting.target_continent('AF') # Allow method chaining self end # Targets the notification to clients currently located in Antarctica def target_antarctica # Target the continent @targeting.target_continent('AN') # Allow method chaining self end # Targets the notification to clients currently located in Europe def target_europe # Target the continent @targeting.target_continent('EU') # Allow method chaining self end # Targets the notification to clients currently located in North America def target_north_america # Target the continent @targeting.target_continent('NA') # Allow method chaining self end # Targets the notification to clients currently located in South America def target_south_america # Target the continent @targeting.target_continent('SA') # Allow method chaining self end # Targets the notification to clients currently located in Oceania def target_oceania # Target the continent @targeting.target_continent('OC') # Allow method chaining self end # ------------------------------ # IP address targeting # ------------------------------ # Targets the notification to clients with the given IP address def target_ip(ip_address) # Add the IP address to the list of target IP addresses @targeting.target_ip ip_address # Allow method chaining self end # Targets the notification to clients with any of the given IP addresses def target_ips(*ip_addresses) # Target each IP address ip_addresses.each {|x| target_ip x } # Allow method chaining self end # ------------------------------ # Action targeting # ------------------------------ # Targets the notification to clients who have taken the given action def target_action(action_identifier) # Add the action to the list of target actions @targeting.target_action action_identifier # Allow method chaining self end # Targets the notification to clients who have taken any of the given actions def target_actions(*action_identifiers) # Target each action action_identifiers.each {|x| target_action x } # Allow method chaining self end # Targets the notification to clients who have not taken the given action def target_not_action(action_identifier) # Add the action to the list of target "not" actions @targeting.target_not_action action_identifier # Allow method chaining self end # Targets the notification to clients who have not taken any of the given actions def target_not_actions(*action_identifiers) # Target each action action_identifiers.each {|x| target_not_action x } # Allow method chaining self end # ------------------------------ # User targeting # ------------------------------ # Targets the notification to a specific user (identifier by their user ID) def target_user(user_id) # Target the user @targeting.target_user user_id # Allow method chaining self end # Targets the notification to specific users (identifier by their user IDs) def target_users(user_ids) # Target the user IDs user_ids.each {|x| target_user x } # Allow method chaining self end # ------------------------------ # Adding data # ------------------------------ # Adds a data item to the list of data items def add_data_item(key, value) # Make sure the key is not empty if key == '' raise 'The key provided cannot be empty.' end # Add the data item unless @data.keys.include?(key) @data[key] = value end # Allow method chaining self end # Adds multiple data items to the list of data items def add_data_items(data = {}) # Add the data items data.keys.each {|x| add_data_item x, data[x] } # Allow method chaining self end # ------------------------------ # Broadcast method # ------------------------------ # Broadcasts data on the channel specified def broadcast(channel, data = {}) # If we are running unit tests, throw an exception if @is_unit_test_mode raise 'Unit testing of the broadcast() method is not supported.' end # Trim the channel name channel.strip! # Check whether data has been provided if data.length == 0 && @data.length == 0 raise 'There is no data to broadcast.' end # Check whether the channel name contains spaces if channel.include? ' ' raise "The channel name cannot contain spaces. By convention, channel names are alphanumerical and lowercase, with optional dashes (e.g. 'test-channel')." end # Use the stored data if the data parameter is empty if data.length == 0 data = @data end # Initialize the hash of data to send to the server data_to_send = { channel: channel, notification: data.to_json, target_user_ids: @targeting.instance_variable_get('@target_user_ids').to_json, target_actions: @targeting.instance_variable_get('@target_actions').to_json, target_not_actions: @targeting.instance_variable_get('@target_not_actions').to_json, target_continents: @targeting.instance_variable_get('@target_continents').to_json, target_countries: @targeting.instance_variable_get('@target_countries').to_json, target_ips: @targeting.instance_variable_get('@target_ips').to_json, target_browsers: @targeting.instance_variable_get('@target_browsers').to_json } # Broadcast the notification @api_client.post('/broadcast', data_to_send) # Reset the targeting options reset_targeting end # Resets the targeting options def reset_targeting @targeting = Targeting.new end # Set which methods are private private :reset_targeting end end