Can't validate Slack dialog fields. response_url call always fails - php

I am trying to build a slack dialog, triggered by a slash command. The dialog pops up correctly, and when the user submits the data, slack hits an endpoints on my server.
From that moment there are two possible outcomes:
Everything is good and I post a confirmation to the user
The data submitted by the user does not pass my app's validation and I need to let the user know.
Let's focus on #2 for a second:
I am getting a response_url that seems valid (https:\/\/hooks.slack.com\/app\/MY-APP-ID\/433197747012\/kQANkbvc3lIViVyLSJKR695z)
For testing, I'd like to simulate a validation error with one of my fields, so I do this in my endpoint:
$errors = [
'errors' => [
[
'name' => 'vendor_email',
'error' => 'sorry, I do not like this dude'
]
]
];
// define the curl request
$ch = curl_init();
// $decoded->response_url does contain the correct slack URL...
curl_setopt($ch, CURLOPT_URL, $decoded->response_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// set the POST query parameters
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($errors));
// execute curl request
$response = curl_exec($ch);
error_log(" -- response_url response: " . json_encode($response). "\n", 3, './runtime.log');
// close
curl_close($ch);
The response I am getting from hitting the response_url is this:
{\"ok\":false,\"error\":\"invalid_request_data\"}
What am I doing wrong?
****** EDIT ************
Even when not going the CURL route, and just doing this:
return json_encode($errors)
will just close the dialog after submission, and will not trigger any validation error.

The respond_url is not for replying to submissions (e.g. for validation errors), but for sending a message back to the user in the channel.
Once the user completes the dialog you will get a request from Slack. You need to directly respond to that request. You can respond either with an empty response if everything was ok - or with a list of errors for validation. The response must be in JSON and occur within 3 seconds.
To respond all you need to do is echo your error array in JSON. Also make sure to correctly set the header to JSON, like so:
header('Content-Type: application/json');
echo json_encode($errors);
If you have no errors just echo nothing to automatically send a HTTP 200 OK.
See also here in the documentation about how to correctly respond to a submission.

Related

cUrl not returning response - response is BOOL

I am trying to verify my recapture with google, but I am getting a response of null
I copy and paste the information to Postman and sent the request and I received a positive response.
I copied the link in my browser as a GET request and I also got a response.
I am not sure what causing this, as all information is correct.
here is my code.
// set API URL
$url = 'https://www.google.com/recaptcha/api/siteverify';
// Collection object
$data = [
'secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', //<--- my reCaptcha secret key
'response' => $_POST['recaptcha']
];
// Initializes a new cURL session
$curl = curl_init($url);
// Set the CURLOPT_RETURNTRANSFER option to true
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// Set the CURLOPT_POST option to true for POST request
curl_setopt($curl, CURLOPT_POST, true);
// Set the request data as JSON using json_encode function
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
// Execute cURL request with all previous settings
$response = curl_exec($curl);
// Close cURL session
curl_close($curl);
echo 'the response was ' . $response . PHP_EOL;
I saw this but didn't help me. PHP cURL not return a response, POSTMAN returns response
Because it is an HTTPS url you may need to add:
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, false);
It's a good idea to use CURLOPT_FOLLOWLOCATION.
I always use it. It is in my standard options.
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
While Google does not return a 302 redirect HTTP status code, they do something funny with the initial request. I made an HTML form and submitted it and a json response was returned but looking at the Browser's headers my initial request disappeared.
I do not think Google wants the post data as JSON.
In the API Request documentation is says METHOD:POST.
It says noting about making the request with JSON.
Google is expecting an array.
Try removing the json_encode().
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
If Google (unlikely) wants a JSON request, you need to add
Content-Type: application/json to the HTTP header.
By adding this header curl will put the "post data" in the body and will not use the
default POST header: application/x-www-form-urlencoded
$request = array();
$request = 'Content-Type: application/json';
curl_setopt($curl, CURLOPT_HTTPHEADER, $request);
I do not understand why there was no response. I would have at least expected:
{
"success": false,
"error-codes": [
"missing-input-secret"
]
}
You may want to add this code after your curl_exec($curl)
This should give you all the details of you request and Google's response.
$response = curl_exec($curl);
$info = rawurldecode(var_export(curl_getinfo($curl),true));
echo "<pre>\n$info<br>\n</pre>";
If you want to see your outgoing request header (recommended) add this option and the header will be in the curl_getinfo:
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
I'm a bit concerned about a NULL being returned. Was the word NULL returned? Or did you see nothing for $response in your string?
curl does not return a NULL. So maybe it was a false. Meaning there is likely a typo. echo does not show boolean false if $response was false you would not see it. Maybe add a
if($response == false){echo "curl failed<br>";}
Even if it failed, all the above is still true.
I looked over your code and I see nothing that would cause curl to fail. Even with the issues, there still should have been some sort of response. And there may have been an HTTP status code that would not show in your $response. It would be in the curl_getinfo
Are you using your local machine in linux? If that so, it is probably because you don't have curl installed in your system. So do
sudo apt install php{version}-curl

Redirecting to a remote URL with POST Method, POST Fields and Header Info in PHP

I've just ran into a situation where i want to POST some data to a remote URL. Apart from POSTing the data, with some header information, i also want the user to be redirected to that POST url.
Let me explain the scenario here, I'm integrating a third-party Payment Gateway in my web app. I'm Using Laravel. After a chain of API calls, the app is submitting payment details to the API. The API result does have a third-party url (of the respective bank) to which, i need to take the user to complete the authentication process. I have a couple of data and a header info to take along with it. I have tried Laravel Guzzle, but like cURL when we submit the POST data, we'll actually get the response back in our side. But not getting redirected.
If i have to go with a standard html form, how can i post the header information there. Using jQuery ajax could possibly pose the same issue too, that i can't redirect the user.
I have done some re-search and tried something,
With guzzle, i'm actually able to show the HTML content back to the user using the getBody method, but the HTML is not getting parsed the right way, the images are broken (because of the relative path they using in there web pages) and the links and buttons are not taking me to the desired locations.
$response = $client->request('POST', $transactionResponse['redirectForm']['actionUrl'], [
'headers' => $transactionResponse['redirectForm']['headers'],
'form_params' => $transactionResponse['redirectForm']['content']
]);
echo $response->getBody();
I have tried cURL as well with the CURLOPT_FOLLOWLOCATION directive, but it too returns the response, not redirecting the user.
$post = [
'username' => 'user1',
'password' => 'passuser1',
'gender' => 1,
];
$ch = curl_init('http://localhost/laravel/arax_v1/paytm/callback');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'location: http://localhost/laravel/arax_v1/paytm/callback'
));
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
Could anyone have any better idea to work this out ?

How to save form data before sending to URL

I try to save data from a FORM to file. But when 'submit' to external URL my script doesn't see $_POST array. How to save $_POST which I send not receive.
I can save $_POST data I received (I sent to my script and save as post_array.txt). But I have to send it to external url.
I tried to receive and resend saved $_POST using cURL but I cannot do redirect with $_POST.
So my customer stays on my page but should be redirected to payment page with $_POST data.
html : <form method="POST" action="cert.php">
php : cert.php
file_put_contents('post_array.txt', $_POST, FILE_APPEND);
$url = 'https://sandbox.przelewy24.pl/trnDirect';
$fields =['p24_merchant_id' => $_POST['p24_merchant_id'],
'p24_session_id' => $_POST['p24_session_id'],
'p24_amount' => $_POST['p24_amount'],
'p24_currency' => $_POST['p24_currency'],
'p24_sign' => md5($_POST['p24_session_id'].'|'.$_POST['p24_merchant_id'].'|'.$_POST['p24_amount'].'|'.$_POST['p24_currency'].'|'.$_POST['p24__sign'])];
//open connection
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
// this cURL dosnt have a redirect option coz it doesnt work for me :(
// execute!
$response = curl_exec($ch);
file_put_contents('response.txt', $response, FILE_APPEND);
// close the connection, release resources used
curl_close($ch);
Because cURL doesnt work as expected i want to direct send $_POST do external page. (it works well , but i dont have saved $_POST in my file)
How to save $_POST without sending data to my server/script ?
You can make a redirect with http status 307 developer.mozilla.org/en-US/docs/Web/HTTP/Status/307 In this case also body will be redirected.
Another option is to do it with js, first make a request to you server, receive successful answer and then make second request using js to external URL with POST method. Maybe you will need some hidden form to do it in browser.

redirect user after curl post success

I have access a web service via url and I have created a registration page with form to add users to it. There are a couple of issues though. Firstly, it does not seem to work when wrapped in an if (isset($_POST['submit'])) conditional, which means there are some empty variables (as the user hasn't added their information). This results in warnings above the document for an undefined index and a 400 status and a bad request error due to the curl processing without a form submission.
Secondly, whilst I can fill out the form and successfully add a user to the web service, I cannot work out how to redirect the user after a successful curl posting. I tried putting a header('location: 'somepage.php'); after the curl, wrapper in an if statement checking if the username existed but to no avail. They remain on the registration page looking at the now blank form they just submitted.
$headers= array('Accept: application/json','Content-Type: application/json');
$url = "http://thewebsite.com/user";
$fields = array(
'UserName' => urlencode($_POST['UserName'])
);
$fields_json = json_encode($fields);
// open connection
$ch = curl_init($url);
// set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_json);
// execute post
$result = curl_exec($ch);
// close connection
curl_close($ch);
Hopefully this isn't too broad a question. Any help would be appreciated. Thanks.

PHP CURL 1 url, 2 responses

I am working with a vendor's API. In the documentation they state:
"... will generate up to 2 response messages for each command. The first response will be an
acknowledgement message that indicates the message was received and parsed...
The second response will indicate the result of the command. Some commands may take a while to complete, so the manager should not expect an immediate response to commands. If an error occurred during the execution of the command, the response will contain an error message."
Is there a way to make cURL wait for a second response?
$ch = curl_init('http://myserver.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, "XML=".$data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: plain/xml'));
$result = curl_exec($ch);
It seems like this was an error in what I was sending the API, not the response. I have fixed the XML structure and received an appropriate response. However, I still think the documentation is written poorly.
It sounds like you will need to wait and check the same URL over and over until you get the data and not a status message. Not very optimal. Ideally they would let you pass a URL for them to POST back to when the result is ready.

Categories