class Rack::Deduce::Ingest

Constants

EVENT_URL
TIMEOUT
URL
VERHASH
VERSION

Attributes

apikey[RW]
site_id[RW]
ssl[RW]
testmode[RW]

Public Class Methods

event(email, ip, event, additional = {}, options = {}) click to toggle source

@param [String] email The user's email address @param [String] ip The user's ip address @param [String] event The event type @param [Hash] additional Additional data to send @param [Hash] options @return [String] on error, returns an error message; or nothing on success

# File lib/rack/deduce/ingest.rb, line 131
def event(email, ip, event, additional = {}, options = {})
  return if limited?
  return "invalid email" unless email_valid? email

  event_data = additional.dup
  event_data[:email] = email  # fixup will hash the email
  event_data[:ip]    = ip
  event_data[:event] = event

  events [event_data], options
end
events(evts, options = {}) click to toggle source

@param [Array] event data @param [Hash] options @return [String] on error, returns an error message; or nothing on success

# File lib/rack/deduce/ingest.rb, line 86
def events(evts, options = {})
  return if limited?

  site_id = @site_id
  apikey  = @apikey
  timeout = options[:timeout] || (TIMEOUT + evts.length / 10)

  post_data  = { site: site_id, apikey: apikey, vers: VERHASH }
  post_data[:backfill] = true if options[:backfill]
  post_data[:testmode] = true if options[:testmode] || @testmode
  post_data[:events]   = evts.map{ |e| fixup_event( e.dup ) }

  uri  = URI(options[:url] || EVENT_URL)
  http = Net::HTTP.new(uri.host, uri.port)

  http.use_ssl = (uri.scheme == 'https')
  http.open_timeout = timeout
  http.read_timeout = timeout
  http.ssl_timeout  = timeout

  hreq = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
  hreq.body = post_data.to_json

  p post_data.to_json

  begin
    res = http.request(hreq)
    if res.code != '200'
      raise "#{res.code} - #{res.body}"
    end
  rescue => e
    adjust_fail
    return e
  end
  adjust_ok
  # return nil on success, else return the error
  return nil
end
html(email, options = {}) click to toggle source
# File lib/rack/deduce/ingest.rb, line 40
        def html(email, options = {})

          site_id = options[:site_id] || @site_id
          use_ssl = @ssl
          use_ssl = options[:ssl] if options.include? :ssl

          user_data = {site: site_id, vers: VERHASH}
          user_data[:testmode] = true if options[:testmode] || @testmode

          if email_valid?(email)
            email = email.strip
            email_lc = email.downcase
            email_uc = email.upcase
            user_data[:ehls1] = Digest::SHA1.hexdigest(email_lc)
            user_data[:ehus1] = Digest::SHA1.hexdigest(email_uc)
            user_data[:ehlm5] = Digest::MD5.hexdigest(email_lc)
            user_data[:ehum5] = Digest::MD5.hexdigest(email_uc)
            user_data[:ehls2] = Digest::SHA256.hexdigest(email_lc)
            user_data[:ehus2] = Digest::SHA256.hexdigest(email_uc)
          end

          url = options[:url]

          if !url
            if use_ssl.nil?
              url = URL
            elsif use_ssl
              url = 'https:' + URL
            else
              url = 'http:'  + URL
            end
          end

          html = <<EOS
<script type="text/javascript">
var dd_info = #{JSON.pretty_generate(user_data)};
</script>
<script type="text/javascript" src="#{url}" async></script>
EOS

          return html
        end
init(app, site_id, apikey, options = {}) click to toggle source

@param [String] site_id The site ID provided to you by Deduce @param [String] apikey The apikey provided to you by Deduce @param [Hash] options @option options [Boolean] :ssl (true) Use SSL?

# File lib/rack/deduce/ingest.rb, line 30
def init(app, site_id, apikey, options = {})
  @app = app

  self.site_id      = site_id
  self.apikey       = apikey
  self.ssl          = options[:ssl]
  self.testmode     = options[:testmode]
  self.ssl          = ssl
end
new(app, site_id, apikey, options = {}) click to toggle source

@param [String] site_id The site ID provided to you by Deduce @param [String] apikey The apikey provided to you by Deduce @param [Hash] options @option options [Boolean] :ssl (true) Use SSL?

# File lib/rack/deduce/ingest.rb, line 205
def initialize(app, site_id, apikey, options = {})
  self.class.init(app, site_id, apikey, options)
  self.class
end

Private Class Methods

adjust_fail() click to toggle source
# File lib/rack/deduce/ingest.rb, line 185
def adjust_fail
  @limit = (9 * @limit + 100.0) / 10
  @limit = 100.0 if @limit > 100.0
end
adjust_ok() click to toggle source

if the event post is failing - slow down

# File lib/rack/deduce/ingest.rb, line 181
def adjust_ok
  @limit -= 5.0
  @limit = 0.0  if @limit < 0.0
end
email_valid?(email) click to toggle source
# File lib/rack/deduce/ingest.rb, line 146
def email_valid?(email)
  return unless email
  return if email.nil? || email.empty?
  return email.match /.+@.+/
end
fixup_event(evt) click to toggle source
# File lib/rack/deduce/ingest.rb, line 152
def fixup_event(evt)
  # send the hash of the email, not the actual email
  email = evt[:email]

  if email_valid? email
    email = email.strip.downcase
    evt[:ehls1] = Digest::SHA1.hexdigest(email)
    unless evt.has_key? :email_provider
      # pass in an empty value for email_provider to not send
      evt[:email_provider] = email.split(/@/)[1]
    end
    evt.delete :email
  end

  if email_valid? evt[:email_prev]
    evt[:ehls1_prev] = Digest::SHA1.hexdigest(evt[:email_prev].strip.downcase)
    evt.delete :email_prev
  end

  # hash + remove any CC
  if evt[:cc]
    cc = evt[:cc].gsub /[^0-9]/, ''
    evt[:ccs1]       = Digest::SHA1.hexdigest(cc)
    evt.delete :cc
  end
  return evt
end
limited?() click to toggle source
# File lib/rack/deduce/ingest.rb, line 189
def limited?
  now = Time.now
  @limit ||= 0.0
  @lastt ||= now
  dt = now - @lastt
  @lastt = now
  @limit *= 0.999 ** dt
  Random.rand(100.0) < @limit
end