Class: Edi::Amazon::FeedMessageSender
- Inherits:
-
BaseEdiService
- Object
- BaseService
- BaseEdiService
- Edi::Amazon::FeedMessageSender
- Defined in:
- app/services/edi/amazon/feed_message_sender.rb
Direct Known Subclasses
InventoryMessageSender, ListingMessageFeedSender, ListingMessageSender, PriceMessageSender
Constant Summary
Constants included from Edi::AddressAbbreviator
Edi::AddressAbbreviator::MAX_LENGTH
Instance Attribute Summary
Attributes inherited from BaseEdiService
Instance Method Summary collapse
- #ecl_in_queue ⇒ Object
- #instantiate_transporter(transporter, transporter_profile = nil, options = {}) ⇒ Object
-
#process(edi_communication_logs = nil) ⇒ Object
res_feed_id = res[:feedId].
Methods inherited from BaseEdiService
#duplicate_po_already_notified?, #initialize, #mark_duplicate_po_as_notified, #report_order_creation_issues, #safe_process_edi_communication_log
Methods included from Edi::AddressAbbreviator
#abbreviate_street, #collect_street_originals, #record_address_abbreviation_notes
Methods inherited from BaseService
#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger
Constructor Details
This class inherits a constructor from Edi::BaseEdiService
Instance Method Details
#ecl_in_queue ⇒ Object
130 131 132 133 134 135 |
# File 'app/services/edi/amazon/feed_message_sender.rb', line 130 def ecl_in_queue EdiCommunicationLog.requiring_processing .where(partner: orchestrator.partner) .where(category: feed_category) .order(:created_at) end |
#instantiate_transporter(transporter, transporter_profile = nil, options = {}) ⇒ Object
137 138 139 140 141 142 143 144 145 146 |
# File 'app/services/edi/amazon/feed_message_sender.rb', line 137 def instantiate_transporter(transporter, transporter_profile = nil, = {}) case transporter when :http_seller_api Transport::HttpSellerApiConnection.new({ profile: transporter_profile }.merge()) when :http_api_upload Transport::HttpApiUploadConnection.new({ profile: transporter_profile }.merge()) else raise "Unknown transporter: #{transporter}" end end |
#process(edi_communication_logs = nil) ⇒ Object
res_feed_id = res[:feedId]
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'app/services/edi/amazon/feed_message_sender.rb', line 66 def process(edi_communication_logs = nil) feed_transport = instantiate_transporter(orchestrator.transporter, orchestrator.transporter_profile) edi_communication_logs ||= ecl_in_queue [edi_communication_logs].flatten.each do |ecl| logger.info "Sending feed data to #{orchestrator.partner}" # STEP 1 Create Feed Document # VERY IMPORTANT contentType must match Content-Type header in the subsequent upload PUT request exactly! ct = if ecl.data_type == 'xml' 'text/xml; charset=UTF-8' else 'application/json' end data = %({'contentType':'#{ct}'}) res = feed_transport.send_data(data, "#{orchestrator.}/documents", 'POST') ecl.notes = "HTTP CODE: #{res[:http_result]&.code}, HTTP BODY: #{res[:http_result]&.body}, HTTP METHOD: 'POST', Timestamp: #{Time.current.to_datetime.to_fs(:crm_default)}" logger.info "Result: HTTP CODE: #{res[:http_result]&.code}, HTTP BODY: #{res[:http_result]&.body}" if res[:success] && (data = res[:http_result]&.body.to_s).present? json_hash = JSON.parse(data).with_indifferent_access url = json_hash[:url] res_feed_document_id = json_hash[:feedDocumentId] # STEP 2 & 3 Contruct and Upload Feed Document from the signed feed document upload url returned, no auth needed # VERY IMPORTANT Content-Type header must match contentType in the previous Create Feed Document request exactly! feed_document_uploader = instantiate_transporter(:http_api_upload, nil, { headers: { 'Content-Type': ct } }) res = feed_document_uploader.send_data(ecl.data, url, 'POST') ecl.notes += " | HTTP CODE: #{res[:http_result]&.code}, HTTP BODY: #{res[:http_result]&.body}, Timestamp: #{Time.current.to_datetime.to_fs(:crm_default)}" if res[:success] # STEP 4 Create Feed data = %( { "feedType":"#{feed_type}", "marketplaceIds": ["#{orchestrator.marketplace}"], "inputFeedDocumentId": "#{res_feed_document_id}" } ) res = feed_transport.send_data(data, "#{orchestrator.}/feeds", 'POST') ecl.notes += " | HTTP CODE: #{res[:http_result]&.code}, HTTP BODY: #{res[:http_result]&.body}, Timestamp: #{Time.current.to_datetime.to_fs(:crm_default)}" logger.info "Result: HTTP CODE: #{res[:http_result]&.code}, HTTP BODY: #{res[:http_result]&.body}" if res[:success] && (data = res[:http_result]&.body.to_s).present? json_hash = JSON.parse(data).with_indifferent_access res_feed_id = json_hash[:feedId] ecl.transaction_id = res_feed_id ecl.transmit_datetime = Time.current ecl.start_process! else ecl.error end else ecl.error end else ecl.error end rescue HTTP::RateLimitExceededError => e retry_after_seconds = e.retry_after.to_i.positive? ? e.retry_after.to_i : 1.hour.to_i transmit_after_time = Time.current + retry_after_seconds ecl.update_columns(transmit_after: transmit_after_time) logger.warn "Amazon SP-API rate limited for ECL #{ecl.id} (#{feed_category}/#{orchestrator.partner}). " \ "Scheduled retry via transmit_after: #{transmit_after_time.iso8601} " \ "(#{retry_after_seconds}s from now). #{e.}" end edi_communication_logs end |