yext-api 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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