muffin_man 1.0.2 → 1.3.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +22 -1
- data/lib/muffin_man/authorization/v1.rb +16 -0
- data/lib/muffin_man/finances/v0.rb +33 -0
- data/lib/muffin_man/lwa/auth_helper.rb +27 -0
- data/lib/muffin_man/reports/v20210630.rb +57 -8
- data/lib/muffin_man/solicitations/v1.rb +4 -2
- data/lib/muffin_man/sp_api_client.rb +54 -26
- data/lib/muffin_man/version.rb +1 -1
- data/lib/muffin_man.rb +3 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82c3118e9e61b82872329714fbfbaf80fd7613ff98ce126992f2ac3b834e3a51
|
4
|
+
data.tar.gz: 201afe55ba25967d8e519ff5f6a0ac9a66e452462cc4fe805ab2a34b61edec9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9411d153ce20efc02882b456a9b6be233cf88e691472d35bbca5b8890fc422395d5a925a66996c129a1a5835883ac66153415043a94e37ad2d9c6e7e3b17baf5
|
7
|
+
data.tar.gz: 7859bc864e708516ce37087a32791a1fbbae140af2307fbc8d7c530933517e1d914faf704151b7269c290853cfa3a44c741c552a8aadf06bf605cc5ba2745d28
|
data/.rubocop.yml
CHANGED
data/CODE_OF_CONDUCT.md
CHANGED
@@ -39,7 +39,7 @@ This Code of Conduct applies within all community spaces, and also applies when
|
|
39
39
|
|
40
40
|
## Enforcement
|
41
41
|
|
42
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at
|
42
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at opensource@pattern.com. All complaints will be reviewed and investigated promptly and fairly.
|
43
43
|
|
44
44
|
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
45
45
|
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://github.com/patterninc/muffin_man/actions)
|
4
4
|
|
5
|
-
MuffinMan is a ruby interface to the Amazon Selling Partner API. For more information on registering to use the Selling Partner API, see [Amazon's documentation](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md)
|
5
|
+
MuffinMan is a ruby interface to the Amazon Selling Partner API. For more information on registering to use the Selling Partner API, see [Amazon's documentation](https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md)
|
6
6
|
|
7
7
|
As of now, this gem only supports portions of the following APIs with more to come:
|
8
8
|
|
@@ -63,6 +63,27 @@ MuffinMan.configure do |config|
|
|
63
63
|
end
|
64
64
|
```
|
65
65
|
|
66
|
+
### Retrieiving the refresh token
|
67
|
+
|
68
|
+
To retrieve the refresh token from an LWA Website authorization workflow, you can use the LWA helper:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
# Get your auth code first, either through the Website oauth flow or Authorization API
|
72
|
+
credentials = {
|
73
|
+
client_id: CLIENT_ID,
|
74
|
+
client_secret: CLIENT_SECRET,
|
75
|
+
aws_access_key_id: AWS_ACCESS_KEY_ID,
|
76
|
+
aws_secret_access_key: AWS_SECRET_ACCESS_KEY,
|
77
|
+
sts_iam_role_arn: STS_IAM_ROLE_ARN, # Optional
|
78
|
+
scope: 'sellingpartnerapi::migration' # Grantless scope for MWS migration
|
79
|
+
}
|
80
|
+
client = MuffinMan::Authorization::V1.new(credentials)
|
81
|
+
resp = JSON.parse(client.get_authorization_code(seller_id, developer_id, mws_auth_token).body)
|
82
|
+
auth_code = resp['payload']['authorizationCode']
|
83
|
+
# Then query retrieve the refresh token to store
|
84
|
+
refresh_token = MuffinMan::Lwa::AuthHelper.get_refresh_token(CLIENT_ID, CLIENT_SECRET, auth_code)
|
85
|
+
```
|
86
|
+
|
66
87
|
## Contributing
|
67
88
|
|
68
89
|
Bug reports and pull requests are welcome on GitHub at https://github.com/patterninc/muffin_man. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/patterninc/muffin_man/blob/master/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module MuffinMan
|
2
|
+
module Authorization
|
3
|
+
class V1 < SpApiClient
|
4
|
+
def get_authorization_code(selling_partner_id, developer_id, mws_auth_token)
|
5
|
+
@query_params = {
|
6
|
+
"sellingPartnerId" => selling_partner_id,
|
7
|
+
"developerId" => developer_id,
|
8
|
+
"mwsAuthToken" => mws_auth_token
|
9
|
+
}
|
10
|
+
@request_type = "GET"
|
11
|
+
@local_var_path = "/authorization/v1/authorizationCode"
|
12
|
+
call_api
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MuffinMan
|
2
|
+
module Finances
|
3
|
+
class V0 < SpApiClient
|
4
|
+
def list_financial_event_groups(max_results_per_page = nil, financial_event_group_started_before = nil, financial_event_group_started_after = nil, next_token = nil)
|
5
|
+
@local_var_path = "/finances/v0/financialEventGroups"
|
6
|
+
@query_params = {}
|
7
|
+
@query_params["MaxResultsPerPage"] = max_results_per_page unless max_results_per_page.nil?
|
8
|
+
unless financial_event_group_started_before.nil?
|
9
|
+
@query_params["FinancialEventGroupStartedBefore"] =
|
10
|
+
financial_event_group_started_before
|
11
|
+
end
|
12
|
+
unless financial_event_group_started_after.nil?
|
13
|
+
@query_params["FinancialEventGroupStartedAfter"] =
|
14
|
+
financial_event_group_started_after
|
15
|
+
end
|
16
|
+
@query_params["NextToken"] = next_token unless next_token.nil?
|
17
|
+
@request_type = "GET"
|
18
|
+
call_api
|
19
|
+
end
|
20
|
+
|
21
|
+
def list_financial_events_by_group_id(event_group_id, max_results_per_page = nil, posted_after = nil, posted_before = nil, next_token = nil)
|
22
|
+
@local_var_path = "/finances/v0/financialEventGroups/#{event_group_id}/financialEvents"
|
23
|
+
@query_params = {}
|
24
|
+
@query_params["MaxResultsPerPage"] = max_results_per_page unless max_results_per_page.nil?
|
25
|
+
@query_params["PostedAfter"] = posted_after unless posted_after.nil?
|
26
|
+
@query_params["PostedBefore"] = posted_before unless posted_before.nil?
|
27
|
+
@query_params["NextToken"] = next_token unless next_token.nil?
|
28
|
+
@request_type = "GET"
|
29
|
+
call_api
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MuffinMan::Lwa
|
2
|
+
class AuthHelper
|
3
|
+
ACCESS_TOKEN_URL = "https://api.amazon.com/auth/o2/token".freeze
|
4
|
+
|
5
|
+
def self.get_refresh_token(client_id, client_secret, auth_code)
|
6
|
+
body = {
|
7
|
+
grant_type: "authorization_code",
|
8
|
+
code: auth_code,
|
9
|
+
client_id: client_id,
|
10
|
+
client_secret: client_secret
|
11
|
+
}
|
12
|
+
response = Typhoeus.post(
|
13
|
+
ACCESS_TOKEN_URL,
|
14
|
+
body: URI.encode_www_form(body),
|
15
|
+
headers: {
|
16
|
+
"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
|
17
|
+
}
|
18
|
+
)
|
19
|
+
if response.code != 200
|
20
|
+
error_body = JSON.parse(response.body)
|
21
|
+
error = "#{error_body["error"]}: #{error_body["error_description"]}"
|
22
|
+
raise MuffinMan::Error, error
|
23
|
+
end
|
24
|
+
JSON.parse(response.body)["refresh_token"]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,12 +1,40 @@
|
|
1
1
|
module MuffinMan
|
2
2
|
module Reports
|
3
3
|
class V20210630 < SpApiClient
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
SANDBOX_REPORT_TYPES = "FEE_DISCOUNTS_REPORT,GET_AFN_INVENTORY_DATA".freeze
|
5
|
+
SANDBOX_PROCESSING_STATUSES = "IN_QUEUE,IN_PROGRESS".freeze
|
6
|
+
SANDBOX_REPORT_TYPE = "GET_MERCHANT_LISTINGS_ALL_DATA".freeze
|
7
|
+
SANDBOX_START_TIME = "2019-12-10T20:11:24.000Z".freeze
|
8
|
+
SANDBOX_CANCEL_REPORT_ID = "ID".freeze
|
9
|
+
SANDBOX_MARKETPLACE_IDS = %w[
|
10
|
+
A1PA6795UKMFR9
|
11
|
+
ATVPDKIKX0DER
|
12
|
+
].freeze
|
13
|
+
SANDBOX_REPORT_ID = "ID323".freeze
|
14
|
+
SANDBOX_REPORT_DOCUMENT_ID = "0356cf79-b8b0-4226-b4b9-0ee058ea5760".freeze
|
15
|
+
|
16
|
+
GET_REPORTS_PARAMS = %w[
|
17
|
+
reportTypes
|
18
|
+
processingStatuses
|
19
|
+
marketplaceIds
|
20
|
+
pageSize
|
21
|
+
createdSince
|
22
|
+
createdUntil
|
23
|
+
nextToken
|
24
|
+
].freeze
|
25
|
+
|
26
|
+
def get_reports(params = {})
|
27
|
+
@local_var_path = "/reports/2021-06-30/reports"
|
28
|
+
if sandbox
|
29
|
+
params = {
|
30
|
+
"reportTypes" => SANDBOX_REPORT_TYPES,
|
31
|
+
"processingStatuses" => SANDBOX_PROCESSING_STATUSES
|
32
|
+
}
|
33
|
+
end
|
34
|
+
@query_params = params.slice(*GET_REPORTS_PARAMS)
|
35
|
+
@request_type = "GET"
|
36
|
+
call_api
|
37
|
+
end
|
10
38
|
|
11
39
|
def create_report(report_type, marketplace_ids, start_time = nil, end_time = nil, report_options = {})
|
12
40
|
report_type = sandbox ? SANDBOX_REPORT_TYPE : report_type
|
@@ -16,12 +44,33 @@ module MuffinMan
|
|
16
44
|
@local_var_path = "/reports/2021-06-30/reports"
|
17
45
|
@request_body = {
|
18
46
|
"reportType" => report_type,
|
19
|
-
"marketplaceIds" => marketplace_ids
|
47
|
+
"marketplaceIds" => marketplace_ids
|
20
48
|
}
|
21
49
|
@request_body["dataStartTime"] = start_time unless start_time.nil?
|
22
50
|
@request_body["dataEndTime"] = end_time unless end_time.nil?
|
23
51
|
@request_body["reportOptions"] = report_options unless report_options.empty?
|
24
|
-
@request_type =
|
52
|
+
@request_type = "POST"
|
53
|
+
call_api
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_report(report_id)
|
57
|
+
report_id = sandbox ? SANDBOX_REPORT_ID : report_id
|
58
|
+
@local_var_path = "/reports/2021-06-30/reports/#{report_id}"
|
59
|
+
@request_type = "GET"
|
60
|
+
call_api
|
61
|
+
end
|
62
|
+
|
63
|
+
def cancel_report(report_id)
|
64
|
+
report_id = sandbox ? SANDBOX_CANCEL_REPORT_ID : report_id
|
65
|
+
@local_var_path = "/reports/2021-06-30/reports/#{report_id}"
|
66
|
+
@request_type = "DELETE"
|
67
|
+
call_api
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_report_document(report_document_id)
|
71
|
+
report_document_id = sandbox ? SANDBOX_REPORT_DOCUMENT_ID : report_document_id
|
72
|
+
@local_var_path = "/reports/2021-06-30/documents/#{report_document_id}"
|
73
|
+
@request_type = "GET"
|
25
74
|
call_api
|
26
75
|
end
|
27
76
|
end
|
@@ -11,9 +11,11 @@ module MuffinMan
|
|
11
11
|
def create_product_review_and_seller_feedback_solicitation(amazon_order_id, marketplace_ids)
|
12
12
|
@amazon_order_id = sandbox ? SANDBOX_AMAZON_ORDER_ID : amazon_order_id
|
13
13
|
@marketplace_ids = sandbox ? SANDBOX_MARKETPLACE_IDS : marketplace_ids
|
14
|
-
@local_var_path =
|
14
|
+
@local_var_path = "/solicitations/v1/orders/{amazonOrderId}/solicitations/productReviewAndSellerFeedback".sub(
|
15
|
+
"{" + "amazonOrderId" + "}", @amazon_order_id
|
16
|
+
)
|
15
17
|
@query_params = { "marketplaceIds" => @marketplace_ids }
|
16
|
-
@request_type =
|
18
|
+
@request_type = "POST"
|
17
19
|
call_api
|
18
20
|
end
|
19
21
|
end
|
@@ -1,20 +1,21 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "aws-sigv4"
|
2
|
+
require "uri"
|
3
|
+
require "aws-sdk-core"
|
4
|
+
require "typhoeus"
|
5
|
+
require "securerandom"
|
6
6
|
|
7
7
|
module MuffinMan
|
8
8
|
class SpApiClient
|
9
9
|
attr_reader :refresh_token, :client_id, :client_secret, :aws_access_key_id,
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
:aws_secret_access_key, :sts_iam_role_arn, :sandbox, :config, :region, :request_type,
|
11
|
+
:local_var_path, :query_params, :request_body, :scope
|
12
|
+
|
13
|
+
ACCESS_TOKEN_URL = "https://api.amazon.com/auth/o2/token".freeze
|
14
|
+
SERVICE_NAME = "execute-api".freeze
|
14
15
|
AWS_REGION_MAP = {
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
"na" => "us-east-1",
|
17
|
+
"eu" => "eu-west-1",
|
18
|
+
"fe" => "us-west-2"
|
18
19
|
}.freeze
|
19
20
|
|
20
21
|
def initialize(credentials, sandbox = false)
|
@@ -24,9 +25,10 @@ module MuffinMan
|
|
24
25
|
@aws_access_key_id = credentials[:aws_access_key_id]
|
25
26
|
@aws_secret_access_key = credentials[:aws_secret_access_key]
|
26
27
|
@sts_iam_role_arn = credentials[:sts_iam_role_arn]
|
27
|
-
@region = credentials[:region] ||
|
28
|
+
@region = credentials[:region] || "na"
|
29
|
+
@scope = credentials[:scope]
|
28
30
|
@sandbox = sandbox
|
29
|
-
Typhoeus::Config.user_agent =
|
31
|
+
Typhoeus::Config.user_agent = ""
|
30
32
|
@config = MuffinMan.configuration
|
31
33
|
end
|
32
34
|
|
@@ -38,9 +40,7 @@ module MuffinMan
|
|
38
40
|
|
39
41
|
def request_opts
|
40
42
|
opts = { headers: headers }
|
41
|
-
if request_body
|
42
|
-
opts[:body] = request_body.to_json
|
43
|
-
end
|
43
|
+
opts[:body] = request_body.to_json if request_body
|
44
44
|
opts
|
45
45
|
end
|
46
46
|
|
@@ -63,20 +63,21 @@ module MuffinMan
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def retrieve_lwa_access_token
|
66
|
-
return request_lwa_access_token[
|
66
|
+
return request_lwa_access_token["access_token"] unless defined?(config.get_access_token)
|
67
|
+
|
67
68
|
stored_token = config.get_access_token.call(client_id)
|
68
69
|
if stored_token.nil?
|
69
70
|
new_token = request_lwa_access_token
|
70
71
|
config.save_access_token.call(client_id, new_token) if defined?(config.save_access_token)
|
71
|
-
|
72
|
+
new_token["access_token"]
|
72
73
|
else
|
73
|
-
|
74
|
+
stored_token
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
77
78
|
def request_lwa_access_token
|
78
79
|
body = {
|
79
|
-
grant_type:
|
80
|
+
grant_type: "refresh_token",
|
80
81
|
refresh_token: refresh_token,
|
81
82
|
client_id: client_id,
|
82
83
|
client_secret: client_secret
|
@@ -85,7 +86,29 @@ module MuffinMan
|
|
85
86
|
ACCESS_TOKEN_URL,
|
86
87
|
body: URI.encode_www_form(body),
|
87
88
|
headers: {
|
88
|
-
|
89
|
+
"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
|
90
|
+
}
|
91
|
+
)
|
92
|
+
JSON.parse(response.body)
|
93
|
+
end
|
94
|
+
|
95
|
+
def retrieve_grantless_access_token
|
96
|
+
# No storage of this type for now
|
97
|
+
request_grantless_access_token["access_token"]
|
98
|
+
end
|
99
|
+
|
100
|
+
def request_grantless_access_token
|
101
|
+
body = {
|
102
|
+
grant_type: "client_credentials",
|
103
|
+
scope: scope,
|
104
|
+
client_id: client_id,
|
105
|
+
client_secret: client_secret
|
106
|
+
}
|
107
|
+
response = Typhoeus.post(
|
108
|
+
ACCESS_TOKEN_URL,
|
109
|
+
body: URI.encode_www_form(body),
|
110
|
+
headers: {
|
111
|
+
"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
|
89
112
|
}
|
90
113
|
)
|
91
114
|
JSON.parse(response.body)
|
@@ -117,17 +140,22 @@ module MuffinMan
|
|
117
140
|
end
|
118
141
|
|
119
142
|
def headers
|
143
|
+
access_token = scope ? retrieve_grantless_access_token : retrieve_lwa_access_token
|
120
144
|
headers = {
|
121
|
-
|
122
|
-
|
123
|
-
|
145
|
+
"x-amz-access-token" => access_token,
|
146
|
+
"user-agent" => "MuffinMan/#{VERSION} (Language=Ruby)",
|
147
|
+
"content-type" => "application/json"
|
124
148
|
}
|
125
149
|
signed_request.headers.merge(headers)
|
126
150
|
end
|
127
151
|
|
128
152
|
def derive_aws_region
|
129
153
|
@aws_region ||= AWS_REGION_MAP[region]
|
130
|
-
|
154
|
+
unless @aws_region
|
155
|
+
raise MuffinMan::Error,
|
156
|
+
"#{region} is not supported or does not exist. Region must be one of the following: #{AWS_REGION_MAP.keys.join(", ")}"
|
157
|
+
end
|
158
|
+
|
131
159
|
@aws_region
|
132
160
|
end
|
133
161
|
end
|
data/lib/muffin_man/version.rb
CHANGED
data/lib/muffin_man.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
require "muffin_man/version"
|
2
2
|
require "muffin_man/sp_api_client"
|
3
|
+
require "muffin_man/lwa/auth_helper"
|
3
4
|
require "muffin_man/solicitations/v1"
|
4
5
|
require "muffin_man/reports/v20210630"
|
5
6
|
require "muffin_man/catalog_items/v20201201"
|
7
|
+
require "muffin_man/finances/v0"
|
8
|
+
require "muffin_man/authorization/v1"
|
6
9
|
|
7
10
|
module MuffinMan
|
8
11
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: muffin_man
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gavin
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2022-02
|
13
|
+
date: 2022-05-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -123,7 +123,10 @@ files:
|
|
123
123
|
- bin/console
|
124
124
|
- bin/setup
|
125
125
|
- lib/muffin_man.rb
|
126
|
+
- lib/muffin_man/authorization/v1.rb
|
126
127
|
- lib/muffin_man/catalog_items/v20201201.rb
|
128
|
+
- lib/muffin_man/finances/v0.rb
|
129
|
+
- lib/muffin_man/lwa/auth_helper.rb
|
127
130
|
- lib/muffin_man/reports/v20210630.rb
|
128
131
|
- lib/muffin_man/solicitations/v1.rb
|
129
132
|
- lib/muffin_man/sp_api_client.rb
|