yext-api 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +100 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +10 -0
  9. data/Gemfile.lock +187 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +206 -0
  12. data/Rakefile +30 -0
  13. data/app/assets/config/yext_api_manifest.js +2 -0
  14. data/app/assets/images/yext/api/.keep +0 -0
  15. data/app/assets/javascripts/yext/api/application.js +13 -0
  16. data/app/assets/stylesheets/yext/api/application.css +15 -0
  17. data/app/controllers/yext/api/application_controller.rb +12 -0
  18. data/app/docs/notes.txt +45 -0
  19. data/app/helpers/yext/api/application_helper.rb +11 -0
  20. data/app/jobs/yext/api/application_job.rb +8 -0
  21. data/app/mailers/yext/api/application_mailer.rb +11 -0
  22. data/app/models/yext/api/application_record.rb +10 -0
  23. data/app/views/layouts/yext/api/application.html.erb +14 -0
  24. data/bin/console +16 -0
  25. data/bin/rails +16 -0
  26. data/bin/setup +8 -0
  27. data/config/initializers/spyke.rb +3 -0
  28. data/config/routes.rb +4 -0
  29. data/lib/config/api.yml +1100 -0
  30. data/lib/tasks/yext/api_tasks.rake +6 -0
  31. data/lib/yext/api.rb +33 -0
  32. data/lib/yext/api/administrative_api.rb +12 -0
  33. data/lib/yext/api/administrative_api/account.rb +62 -0
  34. data/lib/yext/api/administrative_api/add_request.rb +34 -0
  35. data/lib/yext/api/administrative_api/service.rb +38 -0
  36. data/lib/yext/api/concerns/account_child.rb +92 -0
  37. data/lib/yext/api/concerns/account_relations.rb +25 -0
  38. data/lib/yext/api/concerns/api_finder.rb +61 -0
  39. data/lib/yext/api/concerns/default_scopes.rb +37 -0
  40. data/lib/yext/api/concerns/enum_all.rb +18 -0
  41. data/lib/yext/api/concerns/faraday_connection.rb +45 -0
  42. data/lib/yext/api/concerns/rate_limits.rb +31 -0
  43. data/lib/yext/api/engine.rb +13 -0
  44. data/lib/yext/api/enumerations/validation.rb +16 -0
  45. data/lib/yext/api/knowledge_api.rb +12 -0
  46. data/lib/yext/api/knowledge_api/account_settings/account.rb +33 -0
  47. data/lib/yext/api/knowledge_api/health_check/health.rb +25 -0
  48. data/lib/yext/api/knowledge_api/knowledge_manager/category.rb +25 -0
  49. data/lib/yext/api/knowledge_api/knowledge_manager/location.rb +59 -0
  50. data/lib/yext/api/live_api.rb +12 -0
  51. data/lib/yext/api/live_api/location.rb +37 -0
  52. data/lib/yext/api/utils/api_base.rb +13 -0
  53. data/lib/yext/api/utils/api_rate_limits.rb +36 -0
  54. data/lib/yext/api/utils/configuration.rb +97 -0
  55. data/lib/yext/api/utils/default_parameters.rb +57 -0
  56. data/lib/yext/api/utils/response_parser.rb +84 -0
  57. data/lib/yext/api/version.rb +7 -0
  58. data/lib/yext/include_rails.rb +31 -0
  59. data/yext-api.gemspec +51 -0
  60. metadata +271 -0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Concerns
6
+ # This module adds attributes to a module for saving and setting the rate limits returned
7
+ # from the Yext API.
8
+ module RateLimits
9
+ attr_reader :rate_limit_remaining,
10
+ :rate_limit_limit,
11
+ :rate_limit_reset_at,
12
+ :last_status,
13
+ :last_meta
14
+
15
+ def last_status=(last_status)
16
+ @last_status = last_status
17
+ end
18
+
19
+ def last_meta=(last_meta)
20
+ @last_meta = last_meta
21
+ end
22
+
23
+ def update_rates(remaining: 1_000, limit: 1_000, reset_at: Time.now)
24
+ @rate_limit_limit = limit
25
+ @rate_limit_remaining = remaining
26
+ @rate_limit_reset_at = reset_at
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ # The base engine class for the API.
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace Yext::Api
8
+
9
+ # Add a load path for this specific Engine
10
+ config.autoload_paths << File.expand_path("../../../../lib", __FILE__)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Enumerations
6
+ # An enumeration class to contain the allowable values for the validation option on
7
+ # API calls.
8
+ class Validation
9
+ include Yext::Api::Concerns::EnumAll
10
+
11
+ STRICT = "strict"
12
+ LENIENT = "lenient"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ # http://developer.yext.com/docs/api-reference
6
+ #
7
+ # Yext Knowledge API
8
+ module KnowledgeApi
9
+ extend Yext::Api::Concerns::RateLimits
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module KnowledgeApi
6
+ module AccountSettings
7
+ # :administrative_api:
8
+ # :account_settings:
9
+ # :account:
10
+ # :actions:
11
+ # - :action: :index
12
+ # :method: :get
13
+ # :endpoint: https://api.yext.com/v2/accounts
14
+ # :path_regex: v2/accounts
15
+ # :default_version: 20161012
16
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/listAccounts
17
+ # :comment: List all accounts that you have access to. Unless you are in Partner Portal mode, this will only be your own account.
18
+ # :sandbox_only: false
19
+ # - :action: :show
20
+ # :method: :get
21
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}
22
+ # :path_regex: v2/accounts/\w+
23
+ # :default_version: 20161012
24
+ # :documentation: http://developer.yext.com/docs/administrative-api/#operation/getAccount
25
+ # :comment: Get details for an account.
26
+ # :sandbox_only: false
27
+ class Account < Yext::Api::Utils::ApiBase
28
+ include Yext::Api::Concerns::AccountRelations
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module KnowledgeApi
6
+ module HealthCheck
7
+ # :knowledge_api:
8
+ # :health_check:
9
+ # :health:
10
+ # :actions:
11
+ # - :action: :index
12
+ # :method: :get
13
+ # :endpoint: https://api.yext.com/v2/healthy
14
+ # :path_regex: v2/healthy
15
+ # :default_version: 20161012
16
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/healthCheck
17
+ # :comment: The Health Check endpoint allows you to monitor the status of Yext's systems.
18
+ # :sandbox_only: false
19
+ class Health < Yext::Api::Utils::ApiBase
20
+ uri("healthy")
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module KnowledgeApi
6
+ module KnowledgeManager
7
+ # :knowledge_api:
8
+ # :knowledge_manager:
9
+ # :category:
10
+ # :actions:
11
+ # - :action: :index
12
+ # :method: :get
13
+ # :endpoint: https://api.yext.com/v2/categories
14
+ # :default_version: 20161012
15
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/getBusinessCategories
16
+ # :comment: Get available Categories.
17
+ # :sandbox_only: false
18
+ #
19
+ # Class for fetching categories
20
+ class Category < Yext::Api::Utils::ApiBase
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TODO: Complete and test. Untested initial framework class.
4
+ module Yext
5
+ module Api
6
+ module KnowledgeApi
7
+ module KnowledgeManager
8
+ # :knowledge_api:
9
+ # :knowledge_manager:
10
+ # :Location:
11
+ # - :action: :index
12
+ # :method: :get
13
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/locations
14
+ # :path_regex: v2/accounts/[^/]+?/locations
15
+ # :default_version: 20161012
16
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/getLocations
17
+ # :comment: Get multiple Locations (primary profiles only).
18
+ # :sandbox_only: false
19
+ # - :action: :create
20
+ # :method: :post
21
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/locations
22
+ # :path_regex: v2/accounts/[^/]+?/locations
23
+ # :default_version: 20161012
24
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/createLocation
25
+ # :comment: Create a new Location.
26
+ # :sandbox_only: false
27
+ # - :action: :search
28
+ # :method: :get
29
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/locationsearch
30
+ # :path_regex: v2/accounts/[^/]+?/locationsearch
31
+ # :default_version: 20161012
32
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/searchLocations
33
+ # :comment: Get multiple Locations (primary profiles only) that match provided filters.
34
+ # :sandbox_only: false
35
+ # - :action: :show
36
+ # :method: :get
37
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/locations/{locationId}
38
+ # :path_regex: v2/accounts/[^/]+?/locations/[^/]+??
39
+ # :default_version: 20161012
40
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/getLocation
41
+ # :comment: Gets the primary profile for a single Location.
42
+ # :sandbox_only: false
43
+ # - :action: :update
44
+ # :method: :put
45
+ # :endpoint: https://api.yext.com/v2/accounts/{accountId}/locations/{locationId}
46
+ # :path_regex: v2/accounts/[^/]+?/locations/[^/]+??
47
+ # :default_version: 20161012
48
+ # :documentation: http://developer.yext.com/docs/api-reference/#operation/updateLocation
49
+ # :comment: Updates the primary profile for a Location.
50
+ # :sandbox_only: false
51
+ class Location < Yext::Api::Utils::ApiBase
52
+ include Yext::Api::Concerns::AccountChild
53
+
54
+ # TODO: Custom endpoints
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ # http://developer.yext.com/docs/api-reference
6
+ #
7
+ # Yext Knowledge API
8
+ module LiveApi
9
+ extend Yext::Api::Concerns::RateLimits
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module LiveApi
6
+ # :live_api:
7
+ # :objects:
8
+ # :location:
9
+ # :has_many: language_profile
10
+ # :has_many: location_schema
11
+ # :actions:
12
+ # - :action: :index
13
+ # :method: :get
14
+ # :endpoint: https://liveapi.yext.com/v2/accounts/{accountId}/locations
15
+ # :path_regex: https://liveapi.yext.com/v2/accounts/[^/]+?/locations
16
+ # :default_version: 20161012
17
+ # :documentation: http://developer.yext.com/docs/live-api/#operation/locationsList
18
+ # :comment: >
19
+ # Get multiple Locations (primary profile only). Filters are evaluated against all language
20
+ # profiles as well as the primary profile.
21
+ # :sandbox_only: false
22
+ # - :action: :show
23
+ # :method: :get
24
+ # :endpoint: https://liveapi.yext.com/v2/accounts/{accountId}/locations/{locationId}
25
+ # :path_regex: https://liveapi.yext.com/v2/accounts/[^/]+?/locations/[^/]+??
26
+ # :default_version: 20161012
27
+ # :documentation: http://developer.yext.com/docs/live-api/#operation/getLocation
28
+ # :comment: Gets the primary profile for a single Location.
29
+ # :sandbox_only: false
30
+ class Location < Yext::Api::Utils::ApiBase
31
+ include Yext::Api::Concerns::AccountChild
32
+
33
+ live_api
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Utils
6
+ # The base class for the Yext API components.
7
+ class ApiBase < Spyke::Base
8
+ include Yext::Api::Concerns::FaradayConnection
9
+ include Yext::Api::Concerns::DefaultScopes
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Utils
6
+ # Faraday Middleware for extracting API limits from call responses.
7
+ class ApiRateLimits < Faraday::Response::Middleware
8
+ include Yext::Api::Concerns::ApiFinder
9
+
10
+ def call(env)
11
+ @app.call(env).on_complete do |environment|
12
+ save_rates(environment, find_api(env[:url], env[:method].to_s))
13
+
14
+ env.response
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def save_rates(environment, api_module)
21
+ return if api_module.blank?
22
+
23
+ api_module.last_status = environment[:status]
24
+
25
+ response_headers = environment[:response_headers]
26
+
27
+ return unless response_headers.key?("rate-limit-remaining")
28
+
29
+ api_module.update_rates(remaining: response_headers["rate-limit-remaining"].to_i,
30
+ limit: response_headers["rate-limit-limit"].to_i,
31
+ reset_at: Time.at(response_headers["rate-limit-reset"].to_i))
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Utils
6
+ # A configuration class for global configurations for interfacing with the Yext API.
7
+ #
8
+ # The class is a Singleton class to simplify accessing the configuration.
9
+ #
10
+ # Documentation for how the various configurations are used within Yext can be found here:
11
+ # http://developer.yext.com/docs/administrative-api/#section/Policies-and-Conventions
12
+ #
13
+ # Initialization:
14
+ # Some values within the
15
+ #
16
+ # The configurations:
17
+ #
18
+ # account_id
19
+ # *required*
20
+ # default: "me"
21
+ # The ID of the account which you are interfacing with.
22
+ #
23
+ # If the default value of "me" is used, the account_id will default to the account which owns the
24
+ # api_key.
25
+ #
26
+ # api_key
27
+ # *required*
28
+ # The API key for the Yext Application which is being used to submit the request through.
29
+ #
30
+ # api_version
31
+ # The version of the Yext API that the request would like to use for any given API call.
32
+ #
33
+ # If left as nil, the gem will try to use the most up-to-date known version of all APIs whenever
34
+ # possible, and future updates will adjust the defaults for each call to the most recent known
35
+ # version of the API.
36
+ #
37
+ # To keep your application stable, you should set this value to a static known value (such as
38
+ # the date the project using the Yext API first started development).
39
+ #
40
+ # The Yext API will accept a default of "20161012" to use the initially released v2 API.
41
+ #
42
+ # validation_level
43
+ # The validation level to use for a request. Yext defaults this to "strict". You can set this to
44
+ # "lenient" to allow more lenient error and warning handling on your requests.
45
+ #
46
+ # Validation should be a value from Yext::Api::Enumerations::Validation
47
+ #
48
+ # yext_username
49
+ # The username of a Yext User that the call is being made on the behalf of. This will affect the
50
+ # logging of who made a change.
51
+ #
52
+ # yext_user_id
53
+ # The id of a Yext User that the call is being made on the behalf of. This will affect the
54
+ # logging of who made a change.
55
+ #
56
+ # sandbox
57
+ # Boolean that indicates if the gem should use the production or sandbox URL.
58
+ class Configuration
59
+ include Singleton
60
+
61
+ attr_accessor :account_id,
62
+ :api_key,
63
+ :api_version,
64
+ :yext_username,
65
+ :yext_user_id,
66
+ :sandbox
67
+ attr_reader :validation_level
68
+
69
+ def initialize
70
+ read_from_environment_variables
71
+ end
72
+
73
+ def validation_level=(value)
74
+ if (value.present? || value == false) &&
75
+ !Yext::Api::Enumerations::Validation.all.include?(value)
76
+ raise ArgumentError, "validation must be one of: #{Yext::Api::Enumerations::Validation.all.join(',')}"
77
+ end
78
+
79
+ @validation_level = value
80
+ end
81
+
82
+ private
83
+
84
+ def read_from_environment_variables
85
+ @sandbox = !Rails.env.production?
86
+
87
+ @account_id = ENV["YEXT_ACCOUNT_ID"]
88
+ @api_key = ENV["YEXT_API_KEY"]
89
+ @api_version = ENV["YEXT_API_VERSION"]
90
+ @validation_level = ENV["YEXT_VALIDATION_LEVEL"]
91
+ @yext_username = ENV["YEXT_USERNAME"]
92
+ @yext_user_id = ENV["YEXT_USER_ID"]
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yext
4
+ module Api
5
+ module Utils
6
+ # Faraday Middleware for adding Configuration default values to API calls as needed.
7
+ #
8
+ # Most options can be set via scopes and the soped values will be kept if they are used.
9
+ #
10
+ # The following configuration options are defaulted:
11
+ # validation_level: Added to query parameters if not already there and is not nil
12
+ # api_key: Added to query parameters if not already there
13
+ # api_version: Added to qeury parameters if not already there
14
+ # account_id: Inserted into the path if the path includes the Account default URI and no
15
+ # account_id was specified.
16
+ class DefaultParameters < Faraday::Response::Middleware
17
+ attr_reader :configuration
18
+
19
+ def call(request_env)
20
+ @configuration = Yext::Api.configuration
21
+ url = request_env[:url]
22
+ params = Rack::Utils.parse_nested_query(url.query).with_indifferent_access
23
+
24
+ add_username_headers(request_env, configuration, params)
25
+ add_default_query_params(configuration, params)
26
+ save_query_params(url, params)
27
+
28
+ @app.call(request_env)
29
+ end
30
+
31
+ private
32
+
33
+ def add_default_query_params(configuration, params)
34
+ params.reverse_merge!(api_key: configuration.api_key,
35
+ v: configuration.api_version || "20161012")
36
+
37
+ params[:validation] ||= configuration.validation_level if configuration.validation_level.present?
38
+ end
39
+
40
+ def save_query_params(url, params)
41
+ url.query = params.to_query
42
+ end
43
+
44
+ def add_username_headers(request_env, configuration, params)
45
+ username = params.delete(:yext_username) || configuration.yext_username
46
+ user_id = params.delete(:yext_user_id) || configuration.yext_user_id
47
+
48
+ return unless %w[put post patch delete].include?(request_env[:method].to_s)
49
+
50
+ request_headers = request_env[:request_headers]
51
+ request_headers["Yext-Username"] = username if username.present?
52
+ request_headers["Yext-User-Id"] = user_id if user_id.present?
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end