Skip to content

Commit

Permalink
Merge pull request #80 from patterninc/customer_feedback
Browse files Browse the repository at this point in the history
Customer feedback
  • Loading branch information
wlggraham authored Nov 7, 2024
2 parents ea5ae49 + a789d26 commit eb76142
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ MuffinMan is a ruby interface to the Amazon Selling Partner API. For more inform

As of now, this gem only supports portions of the following APIs with more to come:

- `Customer Feedback Insights API v2024-06-01 (BETA)`
- `Amazon Warehousing and Distribution API v2024-05-09`
- `Catalog Items API v2022-04-01`
- `Data Kiosk API v2023-11-15`
Expand Down
1 change: 1 addition & 0 deletions lib/muffin_man.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
require "muffin_man/vendor_orders/v1"
require "muffin_man/vendor_shipments/v1"
require "muffin_man/vendor_transaction_status/v1"
require "muffin_man/customer_feedback/v20240601"

module MuffinMan
class Error < StandardError; end
Expand Down
75 changes: 75 additions & 0 deletions lib/muffin_man/customer_feedback/v20240601.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

module MuffinMan
module CustomerFeedback
class V20240601 < SpApiClient
CUSTOMER_FEEDBACK_PATH = "/customerFeedback/2024-06-01"

def get_item_review_topics(asin, sort_type, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/items/#{asin}/reviews/topics"
@query_params = {
"marketplaceId" => marketplace_id,
"sortBy" => sort_type
}.merge(params)
@request_type = "GET"
call_api
end

def get_item_review_trends(asin, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/items/#{asin}/reviews/trends"
@query_params = {
"marketplaceId" => marketplace_id
}.merge(params)
@request_type = "GET"
call_api
end

def get_browse_node(asin, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/items/#{asin}/browseNode"
@query_params = {
"marketplaceId" => marketplace_id
}.merge(params)
@request_type = "GET"
call_api
end

def get_browse_node_review_topics(browse_node, sort_type, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/browseNodes/#{browse_node}/reviews/topics"
@query_params = {
"marketplaceId" => marketplace_id,
"sortBy" => sort_type
}.merge(params)
@request_type = "GET"
call_api
end

def get_browse_node_review_trends(browse_node, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/browseNodes/#{browse_node}/reviews/trends"
@query_params = {
"marketplaceId" => marketplace_id
}.merge(params)
@request_type = "GET"
call_api
end

def get_browse_node_return_topics(browse_node, sort_type, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/browseNodes/#{browse_node}/returns/topics"
@query_params = {
"marketplaceId" => marketplace_id,
"sortBy" => sort_type
}.merge(params)
@request_type = "GET"
call_api
end

def get_browse_node_return_trends(browse_node, marketplace_id, params = {})
@local_var_path = "#{CUSTOMER_FEEDBACK_PATH}/browseNodes/#{browse_node}/returns/trends"
@query_params = {
"marketplaceId" => marketplace_id
}.merge(params)
@request_type = "GET"
call_api
end
end
end
end
22 changes: 22 additions & 0 deletions spec/muffin_man/customer_feedback/v20240601_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

RSpec.describe MuffinMan::CustomerFeedback::V20240601 do
subject(:customer_feedback_client) { described_class.new(credentials) }

before do
stub_request_access_token
stub_get_item_review_topics_v20220601
end

let(:asin) { "B00G5L85S2" }
let(:sort_type) { "MENTIONS" }
let(:marketplace_id) { "ATVPDKIKX0DER" }

describe "get_item_review_topics" do
it "makes a request to get_item_review_topics" do
response = customer_feedback_client.get_item_review_topics(asin, sort_type, marketplace_id)
expect(response.response_code).to eq(200)
expect(JSON.parse(response.body)["asin"]).to eq(asin)
end
end
end
214 changes: 214 additions & 0 deletions spec/support/get_item_review_topics.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
{
"marketplaceId": "ATVPDKIKX0DER",
"itemName": "Philips Sonicare for Kids 7+ Genuine Replacement Toothbrush Heads, 2 Brush Heads, Turquoise and White, Standard, HX6042/94",
"dateRange": {
"endDate": "2024-10-18T00:00:00.000Z",
"startDate": "2024-04-18T00:00:00.000Z"
},
"countryCode": "US",
"topics": {
"negativeTopics": [
{
"childAsinMetrics": {
"mostMentions": {
"numberOfMentions": 1,
"asin": "B00G5L85S2"
},
"leastMentions": {
"numberOfMentions": 1,
"asin": "B00G5L85S2"
}
},
"browseNodeMetrics": {
"starRatingImpact": {
"allProducts": 0.02
},
"occurrencePercentage": {
"allProducts": 4.64
}
},
"asinMetrics": {
"starRatingImpact": -0.05,
"numberOfMentions": 1,
"occurrencePercentage": 100
},
"reviewSnippets": [
"The packaging is excessive for just two replacement heads",
"Only come in packs of two, excessive packaging",
"Only come in packs of two, excessive packaging"
],
"subtopics": [
{
"reviewSnippets": [
"Only come in packs of two, excessive packaging"
],
"metrics": {
"numberOfMentions": 1,
"occurrencePercentage": 100
},
"subtopic": "wrong packaging"
}
],
"topic": "Packaging Quality",
"parentAsinMetrics": {
"starRatingImpact": -0.05,
"numberOfMentions": 1,
"occurrencePercentage": 100
}
}
],
"positiveTopics": [
{
"childAsinMetrics": {
"mostMentions": {
"numberOfMentions": 2,
"asin": "B00G5L85S2"
},
"leastMentions": {
"numberOfMentions": 2,
"asin": "B00G5L85S2"
}
},
"browseNodeMetrics": {
"starRatingImpact": {
"allProducts": 0.53
},
"occurrencePercentage": {
"allProducts": 16.78
}
},
"asinMetrics": {
"starRatingImpact": 3.18,
"numberOfMentions": 2,
"occurrencePercentage": 33.33
},
"reviewSnippets": [
"Nice product",
"We love sonicare products",
"No complaints"
],
"subtopics": [
{
"reviewSnippets": [
"No complaints"
],
"metrics": {
"numberOfMentions": 1,
"occurrencePercentage": 50
},
"subtopic": "no complaints"
},
{
"reviewSnippets": [
"Nice product"
],
"metrics": {
"numberOfMentions": 1,
"occurrencePercentage": 50
},
"subtopic": "great idea"
}
],
"topic": "Customer Satisfaction",
"parentAsinMetrics": {
"starRatingImpact": 3.18,
"numberOfMentions": 2,
"occurrencePercentage": 33.33
}
},
{
"childAsinMetrics": {
"mostMentions": {
"numberOfMentions": 1,
"asin": "B00G5L85S2"
},
"leastMentions": {
"numberOfMentions": 1,
"asin": "B00G5L85S2"
}
},
"browseNodeMetrics": {
"starRatingImpact": {
"allProducts": 2.08
},
"occurrencePercentage": {
"allProducts": 22.29
}
},
"asinMetrics": {
"starRatingImpact": 1.19,
"numberOfMentions": 1,
"occurrencePercentage": 16.67
},
"reviewSnippets": [
"worth the extra money"
],
"subtopics": [
{
"reviewSnippets": [
"worth the extra money"
],
"metrics": {
"numberOfMentions": 1,
"occurrencePercentage": 100
},
"subtopic": "worth the money"
}
],
"topic": "Value For Money",
"parentAsinMetrics": {
"starRatingImpact": 1.19,
"numberOfMentions": 1,
"occurrencePercentage": 16.67
}
},
{
"childAsinMetrics": {
"mostMentions": {
"numberOfMentions": 1,
"asin": "B00G5L85S2"
},
"leastMentions": {
"numberOfMentions": 1,
"asin": "B00G5L85S2"
}
},
"browseNodeMetrics": {
"starRatingImpact": {
"allProducts": 0.11
},
"occurrencePercentage": {
"allProducts": 4.64
}
},
"asinMetrics": {
"starRatingImpact": 0.53,
"numberOfMentions": 1,
"occurrencePercentage": 16.67
},
"reviewSnippets": [
"Easy to use and good quality"
],
"subtopics": [
{
"reviewSnippets": [
"Easy to use and good quality"
],
"metrics": {
"numberOfMentions": 1,
"occurrencePercentage": 100
},
"subtopic": "easy to use"
}
],
"topic": "Ease Of Use",
"parentAsinMetrics": {
"starRatingImpact": 0.53,
"numberOfMentions": 1,
"occurrencePercentage": 16.67
}
}
]
},
"asin": "B00G5L85S2"
}
5 changes: 5 additions & 0 deletions spec/support/sp_api_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ def stub_search_catalog_items_by_identifier_v20220401
.to_return(status: 200, body: File.read("./spec/support/search_catalog_items_by_identifier_v20220401.json"), headers: {})
end

def stub_get_item_review_topics_v20220601
stub_request(:get, "https://#{hostname}/customerFeedback/2024-06-01/items/#{asin}/reviews/topics?marketplaceId=#{marketplace_id}&sortBy=#{sort_type}")
.to_return(status: 200, body: File.read("./spec/support/get_item_review_topics.json"), headers: {})
end

def stub_get_queries
stub_request(:get, "https://#{hostname}/dataKiosk/2023-11-15/queries")
.to_return(status: 200, body: File.read("./spec/support/get_queries.json"), headers: {})
Expand Down

0 comments on commit eb76142

Please sign in to comment.