php- how to do async. processing to add tasks in queue? - php

I have an SMS API that enables to send text messages. I want to use it to send SMSs in bulk.
User can enter upto 30,000 numbers at once and send SMSs. What I am using might be a really bad approach:
foreach ($targets as $target) {
sendSms($target,$text,$extra_parms):
}
It takes 10 minutes to process for 10,000 requests (SMSs) and it's too much. What I want is when a user should click 'Send' button, he should get a message like:
"Your SMS(s) have been added to queue to be sent"
And all the SMSs should be sent in background. How can I do that?
Thanks for the help.

Follow below Process:
Instead of directly calling API, Insert all the data into your
database.
Once numbers and text added in your DB, Show user message
"Your SMS(s) have been added to queue to be sent"
User Background process which will take data from DB and call asynchronous API requests using http://www.php.net/manual/en/function.curl-multi-exec.php
Update/Delete processed API records in database so next time you can fetch only data which are not processed.
Please note: Normal CURL request use synchronous and it wait for for response which make delay.

Create queue i.e. in database and put all your SMS actions there. Create separate script that will be sending SMSes (in batches, as whole whatever) and have it periodically started (i.e. using Curl) to deal with your queue.

That's what I use:
function fast_post($url,$data){
ignore_user_abort(true);
$ch = curl_init();
$defaults = array(
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_URL => $url,
CURLOPT_FRESH_CONNECT => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FORBID_REUSE => 1,
CURLOPT_TIMEOUT => 1,
CURLOPT_POSTFIELDS => http_build_query($data)
);
curl_setopt_array($ch, $defaults);
curl_exec($ch);
curl_close($ch);
}
Note that in this function $data is an array.

Related

Walmart MX Marketplace Acknowledge Order API Issue

I am working on Walmart integration to my own web application using PHP. When I tried to acknowledge my Mexico orders, I got an empty response. The data type of response is string with 0 length, error code 400. It looks like my credentials are good. Is "https://marketplace.walmartapis.com/v3/orders/{PurchaseOrderId}/acknowledge" a valid API url?
$url="https://marketplace.walmartapis.com/v3/orders/P108915403/acknowledge";
$ch = curl_init();
$qos = uniqid();
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_HEADER => false,
CURLOPT_POST =>1,
CURLOPT_HTTPHEADER => array(
"WM_SVC.NAME: Walmart Marketplace",
"WM_QOS.CORRELATION_ID: $qos",
"Authorization: Basic $authorization",
"WM_SEC.ACCESS_TOKEN:$token",
"Accept: application/json",
"Content-Type: application/json",
"WM_MARKET: mx",
),
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
var_dump($response);
Code Snippet
After putting it aside for a few months, today I picked it up and finally got it resolved luckily and got a 202 Accepted Response with empty content(Walmart's documentation says the response to a successful call contains the acknowledged order, but it actually contains nothing except for 202 Accepted code).
When I tried to acknowledge my Mexico orders, the response is actually not empty. The header contains error message: http code 400 Bad Request. I confirmed that it is due to wrong payload structure after testing.
So "https://marketplace.walmartapis.com/v3/orders/{PurchaseOrderId}/acknowledge" is a valid API URL and is the same as US API. The difference between them is that MX site needs a well-structured payload through POST while US site does not(US API only needs an empty payload through POST).
The key point to a successful call is the structure of the payload. The structure should be like the samples in the documentation.
Pay attention to the details of the structure. Refer to the picture for the structure of payload here.
The "orderLine" and "orderLineStatus" should be declared as ARRAY instead of single element. And this is the reason why I failed to call the acknowledge API before.
Looks like you are using an old API, which has been discontinued, the same has been communicated late December 2020.
We have improved our onboarding experience with following steps:
 
Create an account on Walmart IO platform - https://walmart.io by clicking on the user icon just before the search box.        
Login to the account and accept "Terms of Use"
Click on "Create Your Application" to create a new application and fill in appropriate details.        
Use this tutorial to generate two sets of public/private keys - https://walmart.io/key-tutorial       
* One set will be used for production.        
* Other set will be used for stage.
Upload both public keys using - https://walmart.io/key-upload?app_name=<your app name>      
Consumer ID will be generated for both sets for prod and stage which can be seen on the dashboard - https://walmart.io/userdashboard 
Click on "Request Access" for Checkout APIs at https://walmart.io/reference  and fill out the form. 
Once the access is approved, documentation will be available for integrating with Commerce API through Walmart I/O.
We will send out client secrets for stage and prod as soon as they’re ready.
 
Thanks,
Firdos
IOSupport

How to send sms via php when i have the API link

I have a link from the via which I can send sms. It works when I put it in the address bar and fill the required get params and press enter. But how can I load it in the middle of controller action (the framework is Yii2 if that matters) ? I tried with mail() but couldn't reach any result.
The link is like below:
http://sms.***********.com/httpApi/Send.aspx?phone=359.........&body=message&username=xxx&password=xxx
Can I make it with plain php or I have to it via javascript ? Thank you in advance!
cURL allows transfer of data across a wide variety of protocols, and is a very powerful system. It's widely used as a way to send data across websites, including things like API interaction and oAuth. cURL is unrestricted in what it can do, from the basic HTTP request, to the more complex FTP upload or interaction with an authentication enclosed HTTPS site. We'll be looking at the simple difference between sending a GET and POST request and dealing with the returned response, as well as highlighting some useful parameters.
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'YOUR API URL',
CURLOPT_USERAGENT => 'cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
The basic idea behind the cURL functions is that you initialize a cURL session using the curl_init(), then you can set all your options for the transfer via the curl_setopt(), then you can execute the session with the curl_exec() and then you finish off your session using the curl_close().
You should use сURL.
$query = http_build_query([
'phone' => '359.........',
'body' => 'message',
'username' => 'xxx',
'password' => 'xxx'
]);
$c = curl_init();
curl_setopt($c , CURLOPT_URL , 'http://sms.***********.com/httpApi/Send.aspx/?' . $query);
curl_exec($c);
curl_close($c);

How to use post method for xml data using php

I have a api which sends messages to the people ,and the api in the form of url ,which takes user login details and the phone number as input for the url .At a time a time I am able to send 10 sms ,but I want to implement it for bulk sms .
I am trying this code ,but it's working only for 10sms,if we are providing more than 10 mobile numbers it's not working ,can anyone suggest me what mistake I making in my code
Code:
$numbersarray=explode(",",$numbers); //stores numbers as array
/*XML API by Aditya*/
$numbers_xml_string=""; //stores XML string of numbers and message
foreach($numbersarray as $num){
$numbers_xml_string.="<Message><To>".$num."</To><Text>".$text."</Text></Message>";
}
//XML string to be encoded
$xmlstring="<SmsQueue><Account><User>".$user."</User><Password>".$password."</Password></Account><MessageData><SenderId>".$api_id."</SenderId><Gwid>1</Gwid><DataCoding>0</DataCoding></MessageData><Messages>".$numbers_xml_string."</Messages></SmsQueue>";
$xmlstring=urlencode($xmlstring);//encode the string
//prepare URL
$url="http://login.smsgatewayhub.com/xmlapi/pushsms.aspx?data=".$xmlstring;
echo "url".$url;
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($numbersarray),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($result);
There may be two reasons according to your sample code:
First you may only have permissions to send 10 SMS messages.
Second you can only send 10 messages every a certain time. In this case you should know what is the time you should wait and run your script each this time to send sms to the remaining numbers.

Salesforce creates record but responds with a 405

I've written a Wordpress Plug-in that interacts with Salesforce via the REST API. It successfully gets an Instance URL and an Authentication Token using a username/password.
I'm able to submit queries and create objects using wp_remote_post with GET and POST respectively.
However, when creating objects, though successfully created in the Salesforce instance, I get the following in response to my POST:
{"message":"HTTP Method 'POST' not allowed. Allowed are HEAD,GET,PATCH,DELETE","errorCode":"METHOD_NOT_ALLOWED"}
Using the same json body content from these requests, I am able to submit and create via the Salesforce Workbench with no problems at all. I get a proper response that looks like this:
{
"id" : "003E000000OubjkIAB",
"success" : true,
"errors" : [ ]
}
Is there something in the Headers that I'm sending that Salesforce only partially disagrees with? Here are some other arguments that are getting sent as a result of using wp_remote_post - http://codex.wordpress.org/HTTP_API#Other_Arguments
Here's the php code that's calling it:
$connInfo['access_token'] = get_transient('npsf_access_token');
$connInfo['instance_url'] = get_transient('npsf_instance_url');
$url = $connInfo['instance_url'] . $service;
$sfResponse = wp_remote_post($url, array(
'method' => $method,
'timeout' => 5,
'redirection' => 5,
'httpversion' => 1.0,
'blocking' => true,
'headers' => array("Authorization" => "OAuth ". $connInfo['access_token'], "Content-type" => "application/json"),
'body' => $content,
'cookies' => array()
)
);
The $content is being encoded via json_encode before it gets to this point.
Update:
It is specific to one of the extra CURL options being sent by the WP_Http_Curl class. I haven't yet narrowed down which one Salesforce is having a problem with.
The solution is disable redirection in the request. You have it as 5 (the default) -- it needs to be set to 0 for this to work.
The initial request works but Salesforce sends a location header as a part of the response (the URL of the newly created object). WordPress thinks it is being told that the URL moved and that it should try again at this new URL. The response you're seeing is the result of that second request to the actual object you just created. That URL doesn't accept POST requests apparently.
It's a bit odd for Salesforce to be sending such a header, but there's also some discussion going on on the WordPress side that WordPress shouldn't follow location headers for non-301/302 responses which would solve this.
Thanks for posting this by the way. You update made me start debugging WP_Http_Curl which made me realize it was actually making a second HTTP request.

Verifying a Paypal transaction via POST information

I'm at a complete loss. I think I might be getting "mis-informed", but I'll try explain my situation as best I can.
The Idea
We have a form for users to purchase credits. Type in credit number,
click pp button.
Upon click of button, a post is made to set the
transaction log information and set it as pending (works fine).
Upon valid post return it continues to submit the paypal form (works also).
The user is redirected to paypal page and makes payment (so far so good).
after payment made, they click the return and are directed toward the "success" page (still working).
upon reaching this page I take in post data from pp (uh oh, here's where it gets sticky)
verify the data is "true" pp data and update the transaction log (HOW!?)
What I'm being told & what i've tried
I was initially going to use IPN to do a post back to paypal to verify the recieved data (ensure it wasn't spoofed), however, I'm being told that for cost purposes and having to setup an "ipn server" we can't use IPN ....
Ok, so I was gonna use PDT, except either I missed a major step in my attempt or it ISNT working right at all because I'm not doing somthing right. Here is where I'm lost, i've tried a dozen different things, including a direct link post, using sparks (for CI) to set the data and call to paypal link, and etc ...
I've looked over every paypal question on here and a half dozen other forums and can't seem to get anything going.
Can anyone "clearly" tell me how I can verify the POST data of a successful paypal transaction and maybe even tell me if i'm being misinformed about the IPN, cause I looked over the docs and I can't find what i've been told, nor can I really find my solution.
I feel stupid, please help.
When your user clicks a PayPal button and goes to PayPal, when they complete the transaction, an IPN POST is made to a URL of your choosing. So you don't have to have another web server.
When the IPN request comes in, PayPal wants you to re-send the entire POST they made to you back to them, including all of the fields, in the exact order, at which point they will return the word 'VERIFIED' or 'INVALID.' If verified, then do whatever it is that you need to do to toggle your txn log from pending to verified. Also, any information you include in your button (your button is actually a form so you can include your own fields) is included in the POST. Useful for keeping a 'transaction id' or some other identifier for mapping back to your transaction.
If the IPN fails it will resend in n+4 minute increments (where n is how long it waited the last time - 4 minutes, next after 8 minutes, next after 12 minutes, etc) for a few days.
Finally made it work correctly thanks to the update in info on IPN.
My solution added the following line to my form:
<input type="hidden" name="notify_url" value="<?= site_url('payment/notifyTest'); ?>">
Then in the notifyTest function i ran this:
$pDat = $this->input->post(NULL, TRUE);
$isSandBox = array_key_exists('test_ipn', $pDat) && 1 === (int)$pDat['test_ipn'] ? TRUE : FALSE;
$verifyURL = $isSandBox ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr';
$token = random_string('unique');
$request = curl_init();
curl_setopt_array($request, array
(
CURLOPT_URL => $verifyURL,
CURLOPT_POST => 0,
CURLOPT_POSTFIELDS => http_build_query(array('cmd' => '_notify-validate') + $pDat),
CURLOPT_RETURNTRANSFER => 0,
CURLOPT_HEADER => 0,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_CAINFO => 'cacert.pem',
));
$response = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
curl_close($request);
if($status == 200 && $response == 'VERIFIED') {
// SUCCESS
$data = array (
... => ...
);
$this->db->insert('transactions', $data);
}
else {
// FAILED
$data = array (
... => ...
);
$this->db->insert('transactions', $data);
};
THE IMPORTANT DIFFERENCE AS WE FOUND -> DO NOT SET YOUR CURL VARS TO TRUE OR FALSE
USE 0 FOR TRUE AND 1 FOR FALSE, IT MIGHT SOUND STUPID, BUT IT WOIKED!!!

Categories