Parallel POST requests to DB with Ruby/DataMapper - ruby

I'am trying to implement kind of a matchmaking REST service for the game.
My matchmaking table is simple as
ID (Serial)
Client_Name_1 (String)
Client_Name_2 (String)
Basic idea is that when client sends me his "Name" I check if there is a row with Client_Name_2 = NULL and update this row.
If there is no "NULL" rows I create new row with Client_Name_1 as recieved client "Name"
Here is the router code:
post '/api/start' do
#parsing a request with client name
body = JSON.parse request.body.read
#checking if there is a row to update
t = Match.first(:Client_Name_2 => nil)
#matchmaking client to existing game if found
if t != nil
t.update(
Client_Name_2: body['name']
)
response = {:playerIs => '2', :id => t['id']}
#creating new game if nowhere to matchmake
elsif
m = Match.create(
Client_Name_1: body['name']
)
Task.create(
Match_ID: m['id']
)
response = {:playerIs => '1', :id => m['id']}
end
status 201
response.to_json
end
The tricky part for me is that when this router called simultaneously at the very same second from several different clients, all of these requests get the same row id from
#checking if there is a row to update
t = Match.first(:Client_Name_2 => nil)
and this code updates the same row for each request.
Is there a simple solution for this or i will have to implement something like queue to handle such simultaneous requests consequentially?
I will really appreciate your advice.

Related

Always showed Intent to receive required on Xero Webhooks and not x-xero-signature header not matched

When a click on Intent to Receive then it always showed me same like Intent to Received required, not showed 200 OK.
Method for ensuring_security is:
def ensuring_security?
key = 'XERO_WEBHOOK_KEY'
payload = request.body.read
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest('sha256', key, payload))
begin
if calculated_hmac.strip() == request.headers['x-xero-signature']
true
else
false
end
rescue JSON::ParserError => e
false
end
end
The result is alweays false because the calculated_hmac.strip() is not equal to request.headers['x-xero-signature']. I think if the intent can't be 200 OK so if I will updation in Contacts or Invoices the webhook can not be received. So What should I do?
I want to show a result of 200 OK and after this will get a webhook if updation in invoices and contacts.

Always showed Intent to receive required on Xero Webhooks and not x-xero-signature header not matched [RUBY]

When a click on Intent to Receive then it always showed me same like Intent to Received required, not showed 200 OK.
Method for ensuring_security is:
def ensuring_security?
key = 'XERO_WEBHOOK_KEY'
payload = request.body.read
calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest('sha256', key, payload))
begin
if calculated_hmac.strip() == request.headers['x-xero-signature']
true
else
false
end
rescue JSON::ParserError => e
false
end
end
The result is alweays false because the calculated_hmac.strip() is not equal to request.headers['x-xero-signature']. I think if the intent can't be 200 OK so if I will updation in Contacts or Invoices the webhook can not be received. So What should I do?
I want to show a result of 200 OK and after this will get a webhook if updation in invoices and contacts.

How to detect the end_interaction signal using the dialogflow_cx python library?

I am using the DialogFlow CX python library for an agent integration. Once I send a request through detect_intent, I want to be able to check in the response for a flag that determines if the interaction with the agent has ended.
For this, I found a property within the ResponseMessage data type response called end_interaction. I tested this with one of my agents, and effectively once the interaction ends, I can see the end_interaction within the array of response messages:
# inspecting query_result.response_messages
[
text {
text: "Goodbye."
},
end_interaction {
}
]
Now, the problem is that I want to trigger some actions whenever we receive the signal, but since the end_interaction field is being sent empty whenever I try to check it returns me False:
# Both response messages from the example above return False under a bool
bool(query_result.response_messages[0].end_interaction) == False # text message response
bool(query_result.response_messages[1].end_interaction) == False # end_interaction signal
I have tried many things, such as checking with isinstance and hasattr, but they return True for all scenarios since the ResponseMessage data type always has an end_interaction attr.
Any help for finding how to detect and check for this signal is highly appreciated! Thanks!
To detect and check for the end_interaction field, you can use the following in your detect_intent:
any("end_interaction" in d for d in response.query_result.response_messages)
Please note that this will return True if the end_interaction field is found in the response_messages list and False if not. You can use this to determine if the interaction with the agent has ended.
Here is a python sample code of the detect_intent with the end_interaction field for your reference:
def detect_intent_texts(agent, session_id, texts, language_code):
session_path = f'{agent}/sessions/{session_id}'
print(f"Session path: {session_path}\n")
client_options = None
agent_components = AgentsClient.parse_agent_path(agent)
location_id = agent_components["location"]
if location_id != "global":
api_endpoint = f"{location_id}-dialogflow.googleapis.com:443"
print(f"API Endpoint: {api_endpoint}\n")
client_options = {"api_endpoint": api_endpoint}
session_client = SessionsClient(client_options=client_options)
for text in texts:
text_input = session.TextInput(text=text)
query_input = session.QueryInput(text=text_input, language_code=language_code)
request = session.DetectIntentRequest(
session=session_path, query_input=query_input
)
response = session_client.detect_intent(request=request)
print("=" * 20)
print(f"Query text: {response.query_result.text}")
response_messages = [
" ".join(msg.text.text) for msg in response.query_result.response_messages
]
print(f"Response Messages:\n {response.query_result.response_messages}")
print(f'End of interaction: {any("end_interaction" in d for d in response.query_result.response_messages)}')
Here is the result:

How to get the returns data like Returned Date,Merchant SKU,ASIN etc .,

I am newbie to MWS and working on returned items.
I have used Reports API .
$marketplaceIdArray = array("Id" => array('$MARKETPLACE_ID'));
$t1 = date("c", time()-437*24*60*60);
$t2 = date("c", time()-1*24*60*60);
// #TODO: set request. Action can be passed as
MarketplaceWebService_Model_ReportRequest
// object or array of parameters
$parameters = array (
'Merchant' => MERCHANT_ID,
'MarketplaceIdList' => $marketplaceIdArray,
'ReportType' => '_GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA_',
'ReportOptions' => 'ShowSalesChannel=true'
);
$request = new MarketplaceWebService_Model_RequestReportRequest($parameters);
$request = new MarketplaceWebService_Model_RequestReportRequest();
$request->setMarketplaceIdList($marketplaceIdArray);
$request->setStartDate($t1);
$request->setEndDate(t2);
$request->setMerchant(MERCHANT_ID);
$request->setReportType('_GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA_');
invokeRequestReport($service, $request);
the ouput was :
Service Response
RequestReportResponse
RequestReportResult
ReportRequestInfo
ReportRequestId
68409017536
ReportType
_GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA_
StartDate
2018-01-05T06:55:49Z
EndDate
2018-01-05T06:55:49Z
SubmittedDate
2018-01-05T06:55:49Z
ReportProcessingStatus
_SUBMITTED_
ResponseMetadata
RequestId
1ecdc803-b26c-47a2-af0e-e598a00d379d
ResponseHeaderMetadata: RequestId: 1ecdc803-b26c-47a2-af0e-e598a00d379d, ResponseContext: 0KH8lyC6JDI3d4zFp8/qpB5ZmQJx/IVxWhOq4BLHsmELEaNWGUBNKvPZpghwlK2Q1TjAQiX5bls=, Timestamp: 2018-01-05T06:55:49.488Z
but how to fetch the fields like product name, quality, reson,SKU , etc ...,
You have requested the report.
Now you can use that request ID to check when the report has finished running. (You can test it all here before writing the php code: https://mws.amazonservices.com/scratchpad/index.html )
Go to Reports and choose GetReportRequestList and type in your requestID. This will then tell you if the ReportProcessingStatus is done or still processing. When it is done you can then get the GeneratedReportId and request the GetReport using that id. That will then give you a CSV result with your returns for the given time period from the initial report request.
If all of that looks good then you will need to add steps in your PHP code to do all of that.
Once you have requested the report you will need to save the request id and periodically (depending on your order volume, maybe check every few seconds or every minute to see if the request is done. Then you would have something like this:
$reportId = $this->invokeGetReportList($service, $request);
$reportRequest = new MarketplaceWebService_Model_GetReportRequest();
$reportRequest->setMerchant(MERCHANT_ID);
$reportRequest->setReport(#fopen('php://memory', 'rw+'));
$reportRequest->setReportId($reportId);
$resultArray = $this->invokeGetReportAllOrderData($service, $reportRequest);

Cannot access SOAP xml nested id= attribute using Savon 2

In the soap response below (from SoapUI), under the parent SearchForReservationResponse tag, I am trying to pull out the values of Reservation id, Restaurant id and Location id with Savon 2.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<SearchForReservationResponse xmlns="http://schemas.livebookings.net/OneFormat/Aggregator/Internal/1/0/">
<Reservation id="34639536" status="Confirmed">
<DiningDateAndTime>2015-07-01T17:00:00</DiningDateAndTime>
<Restaurant id="25200">
<Name>Eat Food - UK Demo Website - Bookatable.com</Name>
<Location id="35839">
<Name>Bar</Name>
</Location>
</Restaurant>
<Size>2</Size>
<Created>2015-07-01T13:22:17.41</Created>
<SessionId>DINNER</SessionId>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<ConfirmationNumber>JWRW5HR5</ConfirmationNumber>
<AllowedToCancelOnline>true</AllowedToCancelOnline>
<RestaurantPhoneNumber type="Main">+44 7951300529</RestaurantPhoneNumber>
</Reservation>
</SearchForReservationResponse>
</soap:Body>
</soap:Envelope>
Below is my attempt for trying to access Reservation id. After a lot of googling I found that the new Savon 2 syntax uses #attrib, but I keep getting errors as I think I am not using this Ruby nested hash syntax correctly - I find it very confusing and am fairly new to Ruby. If you could help me out here it would be much appreciated!
require 'savon'
class SearchReservation
attr_reader :reservation_id
def client
client = Savon.client(wsdl: "http://example-wsdl-url", follow_redirects: :follow_redirects)
end
def main_method(confirm_number, email)
message = {'ConfirmationNumber' => "JWRW5HR5", 'EMail' => "jon#" }
response = client.call(:search_for_reservation, message: message)
data = response.body(:search_for_reservation_response => { #attrib => {:reservation => :id} })
if data
#reservation_id = data[:id]
end
end
end
search = SearchReservation.new
puts search.main_method("JWRW5HR5", "jon#")
N.B. the email value jon# doesn't have to be a valid email address (used just for testing purposes) - it returns a valid response in SoapUI.
My last syntax error trace in the terminal/console:
/~/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/savon-2.11.1/lib/savon/response.rb:36:in `body': wrong number of arguments (1 for 0) (ArgumentError)
from search.rb:13:in `main_method'
from search.rb:22:in `<main>'
My final solution pulling out all the values I need. Of note: even though dining_date_and_time was presented as xml when putting response.body, when it is extracted using #dining_date_and_time = data[:dining_date_and_time] the date and time values get printed cleanly. This is key once porting to a fully-fledged Rails app.
Despite all the discussion online about attributes, ids within an xml tag can be pulled by just ensuring you are far enough down the "tree" (ie. location id falls under location tag) and then specifying the key: in this case the api displays it as :#id for each nested case.
N.B, this only returns the last value called each time in console. But all values should be pulled in views once integrated into Rails. (Hopefully!)
require 'savon'
class SearchClass
def client
client = Savon.client(wsdl: "http://wsdl-example-url", follow_redirects: :follow_redirects)
end
def return_data(confirm_number, email)
message = {'ConfirmationNumber' => confirm_number, 'EMail' => email }
response = client.call(:search_for_reservation, message: message)
data = response.to_hash[:search_for_reservation_response][:reservation]
#reservation_id = data[:#id]
#dining_date_and_time = data[:dining_date_and_time]
#size = data[:size]
#session_id = data[:session_id]
#first_name = data[:first_name]
#last_name = data[:last_name]
#confirm_number = data[:confirmation_number]
#allowed_to_cancel_online = data[:allowed_to_cancel_online]
#restaurant_phone_number = data[:restaurant_phone_number]
data2 = response.to_hash[:search_for_reservation_response][:reservation][:restaurant]
#restaurant_id = data2[:#id]
#restaurant_name = data2[:name]
data3 = response.to_hash[:search_for_reservation_response][:reservation][:restaurant][:location]
#location_id = data3[:#id]
#location_name = data3[:name]
end
end
search = SearchClass.new
puts search.return_data("JWRW5HR5", "jon#")

Resources