Class: Attune::Client

Inherits:
Object
  • Object
show all
Includes:
Configurable
Defined in:
lib/attune/client.rb

Constant Summary

Constants included from Configurable

Attune::Configurable::KEYS

Instance Attribute Summary

Attributes included from Configurable

#auth_token, #disabled, #endpoint, #exception_handler, #middleware, #timeout

Instance Method Summary collapse

Methods included from Configurable

#configure

Constructor Details

#initialize(options = {}) ⇒ Object

Initializes a new Client

Examples:

client = Attune::Client.new(
  endpoint: "http://example.com:8080/",
  timeout:  10
)

Parameters:

  • options (Hash) (defaults to: {})

    Options for connection (see Attune::Configurable)



29
30
31
32
33
# File 'lib/attune/client.rb', line 29

def initialize(options={})
  Attune::Configurable::KEYS.each do |key|
    send("#{key}=", options[key] || Attune::Default.send(key))
  end
end

Instance Method Details

#bind(id, customer_id) ⇒ Object

Binds an anonymous user to a customer id

Examples:

rankings = client.bind(
  '25892e17-80f6-415f-9c65-7395632f022',
  'cd171f7c-560d-4a62-8d65-16b87419a58'
)

Parameters:

  • id (String)

    The anonymous visitor to bind

  • customer_id (String)

    The customer id to bind

Raises:

  • (Faraday::Error::ClientError)

    if the request fails or exceeds the timeout

  • (AuthenticationException)

    if authorization header not accepted



195
196
197
198
# File 'lib/attune/client.rb', line 195

def bind(id, customer_id)
  put("bindings/anonymous=#{id}&customer=#{customer_id}")
  true
end

#create_anonymous(options) ⇒ Object

Create an anonymous tracked user

Examples:

Generate a new id (preferred)

anonymous_id = client.create_anonymous(
  user_agent: 'Mozilla/5.0'
)

Create using an existing id

client.create_anonymous(
  id: '0cddbc0-6114-11e3-949a-0800200c9a66',
  user_agent: 'Mozilla/5.0'
)

Parameters:

  • options (Hash)

Options Hash (options):

  • :id (String)

    optional. An id will be generated if this is not provided

  • :user_agent (String)

    The user agent for the application used by the anonymous users

Raises:

  • (ArgumentError)

    if user_agent is not provided

  • (Faraday::Error::ClientError)

    if the request fails or exceeds the timeout

  • (AuthenticationException)

    if authorization header not accepted



84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/attune/client.rb', line 84

def create_anonymous(options)
  raise ArgumentError, "user_agent required" unless options[:user_agent]
  if id = options[:id]
    put("anonymous/#{id}", {user_agent: options[:user_agent]})
    id
  else
    if response = post_json("anonymous", {user_agent: options[:user_agent]})
      response[:location][/\Aurn:id:([a-z0-9\-]+)\Z/, 1]
    else
      # Return a new UUID if there was an exception and we're in mock mode
      SecureRandom.uuid
    end
  end
end

#get_auth_token(client_id, client_secret) ⇒ Object

Request an auth token

Examples:

Generate a new auth token

token = client.get_auth_token("client id", "secret")

Parameters:

  • client_id (String)

    The client identifier.

  • client_secret (String)

    The secret key for the client.

Returns:

  • An auth token if credentials accepted

Raises:

  • (ArgumentError)

    if client_id or client_secret is not provided

  • (AuthenticationException)

    if client_id or client_secret are not accepted

  • (Faraday::Error::ClientError)

    if the request fails or exceeds the timeout



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/attune/client.rb', line 45

def get_auth_token(client_id, client_secret)
  raise ArgumentError, "client_id required" unless client_id
  raise ArgumentError, "client_secret required" unless client_secret

  response = post_form("oauth/token",
    client_id: client_id,
    client_secret: client_secret,
    grant_type: :client_credentials
  )
  if response
    body = JSON.parse(response.body)
    if body['error']
      raise AuthenticationException, body['error_description']
    end
    body['access_token']
  else
    # Return a new UUID if there was an exception and we're in mock mode
    SecureRandom.uuid
  end
end

#get_rankings(options) ⇒ Hash{Symbol => Hash, Array<String>}

Returns all entities from the specified collection in order of the user's preference

Examples:

rankings = client.get_rankings(
  id: '0cddbc0-6114-11e3-949a-0800200c9a66',
  view: 'b/mens-pants',
  collection: 'products',
  entities: %w[1001, 1002, 1003, 1004]
)

Parameters:

  • options (Hash)

Options Hash (options):

  • :id (String)

    The anonymous user id for whom to grab rankings

  • :view (String)

    The page or app URN on which the entities will be displayed

  • :collection (String)

    name of the collection of entities

  • :entities (Array<String>)

    entities to be ranked. These should be numeric strings or integers.

  • :ip (String)

    ip address of remote user. Used for geolocation (optional)

  • :customer (String)

    id of customer (optional)

Returns:

  • (Hash{Symbol => Hash, Array<String>})
    • :headers the attune headers indicating ranking performed
    • :entities entities in their ranked order

Raises:

  • (ArgumentError)

    if required parameters are missing

  • (Faraday::Error::ClientError)

    if the request fails or exceeds the timeout

  • (AuthenticationException)

    if authorization header not accepted



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/attune/client.rb', line 121

def get_rankings(options)
  qs = encoded_ranking_params(options)
  rankings = {}
  if response = get("rankings/#{qs}", customer: options.fetch(:customer, 'none'))
    rankings[:headers] = response.headers.select { |k,v| k =~ /^attune/ }
    rankings[:entities] = JSON.parse(response.body)['ranking']
  else
    # In mock mode: return the entities in the order passed in
    rankings[:headers] = {"attune-cell"=>"mock", "attune-ranking"=>"mock"}
    rankings[:entities] = options[:entities]
  end
  rankings
end

#multi_get_rankings(multi_options) ⇒ Hash{Symbol => Hash, Array<Array<String>>}

Get multiple rankings in one call

Examples:

rankings = client.multi_get_rankings([
  {
    id: '0cddbc0-6114-11e3-949a-0800200c9a66',
    view: 'b/mens-pants',
    collection: 'products',
    entities: %w[1001, 1002, 1003, 1004]
  },
  {
    id: '0cddbc0-6114-11e3-949a-0800200c9a66',
    view: 'b/mens-pants',
    collection: 'products',
    entities: %w[2001, 2002, 2003, 2004]
  }
])

Parameters:

  • multi_options (Array<Hash>)

    An array of options (see #get_rankings)

Returns:

  • (Hash{Symbol => Hash, Array<Array<String>>})
    • :headers the attune headers indicating ranking performed
    • :entities entities in their ranked order

Raises:

  • (Faraday::Error::ClientError)

    if the request fails or exceeds the timeout

  • (AuthenticationException)

    if authorization header not accepted



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/attune/client.rb', line 158

def multi_get_rankings(multi_options)
  requests = multi_options.map do |options|
    encoded_ranking_params(options)
  end
  rankings = {}
  if response = get("rankings", ids: requests)
    results = JSON.parse(response.body)['results']
    rankings[:headers] = response.headers.select { |k,v| k =~ /^attune/ }

    # Order of encoded paramaters may change, so we must parse them
    results = Hash[results.map do |request, result|
      [CGI.parse(request), result]
    end]
    rankings[:entities] = requests.map do |request|
      results[CGI.parse(request)]['ranking']
    end
  else
    # In mock mode: return the entities in the order passed in
    rankings[:headers] = {"attune-cell"=>"mock", "attune-ranking"=>"mock"}
    rankings[:entities] = multi_options.map do |options|
      options[:entities]
    end
  end
  rankings
end