Class: Edi::Amazon::FeedMessageSender
- Inherits:
-
BaseEdiService
- Object
- BaseService
- BaseEdiService
- Edi::Amazon::FeedMessageSender
- Defined in:
- app/services/edi/amazon/feed_message_sender.rb
Overview
Service object: feed message sender.
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
Attributes inherited from BaseService
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, #tagged_logger
Constructor Details
This class inherits a constructor from Edi::BaseEdiService
Instance Method Details
#ecl_in_queue ⇒ Object
134 135 136 137 138 139 |
# File 'app/services/edi/amazon/feed_message_sender.rb', line 134 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
141 142 143 144 145 146 147 148 149 150 |
# File 'app/services/edi/amazon/feed_message_sender.rb', line 141 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]
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 129 130 131 132 |
# File 'app/services/edi/amazon/feed_message_sender.rb', line 67 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]&.status}, 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]&.status}, 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') # Both transports are now Faraday-backed and expose #status: the # feed_document_uploader (HttpApiUploadConnection) and feed_transport # (HttpSellerApiConnection, migrated to faraday-retry). ecl.notes += " | HTTP CODE: #{res[:http_result]&.status}, 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]&.status}, HTTP BODY: #{res[:http_result]&.body}, Timestamp: #{Time.current.to_datetime.to_fs(:crm_default)}" logger.info "Result: HTTP CODE: #{res[:http_result]&.status}, 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 |