I am trying to make a simple Twilio application, I am broadly following this tutorial : https://www.twilio.com/docs/voice/tutorials/click-to-call-php
I have slightly tweaked and simplified it to suit my needs however, although the problem element doesn't seem any different.
Ajax :
$('#twilio_click_form').on('submit', function(e) {
// Prevent submit event from bubbling and automatically submitting the form
e.preventDefault();
// Call our ajax endpoint on the server to initialize the phone call
$.ajax({
url: '[...]/twilio_click_call',
method: 'POST',
dataType: 'json',
data: {
userPhone: $('#userPhone').val()
}
}).done(function(data) {
// The JSON sent back from the server will contain a success message
alert(data.message);
}).fail(function(error) {
alert('error');
alert(JSON.stringify(error));
});
});
PHP:
public function twilio_click_call()
{
$twilio_creds = array(
'TWILIO_ACCOUNT_SID' => 'xxxx',
'TWILIO_AUTH_TOKEN' => 'xxxx',
'TWILIO_NUMBER' => 'xxxx'
);
$userPhone = $this->input->post('userPhone');
// Create authenticated REST client using account credentials
$client = new Twilio\Rest\Client(
$twilio_creds['TWILIO_ACCOUNT_SID'],
$twilio_creds['TWILIO_AUTH_TOKEN']
);
try
{
$client->calls->create($userPhone, $twilio_creds['TWILIO_NUMBER'],
array("url" => 'http://demo.twilio.com/docs/voice.xml')
);
}
catch (Exception $e)
{
// Failed calls will throw
return $e;
}
return array('message' => 'Call incoming!');
}
The call initiate and runs through perfectly, however the Ajax response always triggers the .fail(), rather than the .done() method - cannot establish why.
There are two things wrong in your code.
1. In ajax call you have defined the datType as json so it will expect the contentType too as json but you're returning the array that is first issue
2. You're calling url inside the url
Use this code:
public function twilio_click_call()
{
$twilio_creds = array(
'TWILIO_ACCOUNT_SID' => 'xxxx',
'TWILIO_AUTH_TOKEN' => 'xxxx',
'TWILIO_NUMBER' => 'xxxx'
);
$userPhone = $this->input->post('userPhone');
// Create authenticated REST client using account credentials
$client = new Twilio\Rest\Client(
$twilio_creds['TWILIO_ACCOUNT_SID'],
$twilio_creds['TWILIO_AUTH_TOKEN']
);
try
{
$client->calls->create($userPhone, $twilio_creds['TWILIO_NUMBER'],
array("url" => 'http://demo.twilio.com/docs/voice.xml')
);
}
catch (Exception $e)
{
// Failed calls will throw
echo json_encode(array($e));
}
echo json_encode(array('message' => 'Call incoming!'));
}
Related
The below public function returns oauth token against user name and password. However, I have a requirement where, the username has to queried first from email id. In the first part of the function, I need to somehow add the username to the request object. The request is created using laminas from what I can understand.
Full code from which function is taken is here.
/**
* Processes POST requests to /oauth/token.
*/
public function token(ServerRequestInterface $request) {
////////////////
////////////////
// ADD LOGIC TO GET EMAIL FROM REQUEST & GET USERNAME
// ADD USERNAME TO $request
////////////////
////////////////
//Extract the grant type from the request body.
$body = $request->getParsedBody();
$grant_type_id = !empty($body['grant_type']) ? $body['grant_type'] : 'implicit';
$client_drupal_entity = NULL;
if (!empty($body['client_id'])) {
$consumer_storage = $this->entityTypeManager()->getStorage('consumer');
$client_drupal_entities = $consumer_storage
->loadByProperties([
'uuid' => $body['client_id'],
]);
if (empty($client_drupal_entities)) {
return OAuthServerException::invalidClient($request)
->generateHttpResponse(new Response());
}
$client_drupal_entity = reset($client_drupal_entities);
}
// Get the auth server object from that uses the League library.
try {
// Respond to the incoming request and fill in the response.
$auth_server = $this->grantManager->getAuthorizationServer($grant_type_id, $client_drupal_entity);
$response = $this->handleToken($request, $auth_server);
}
catch (OAuthServerException $exception) {
watchdog_exception('simple_oauth', $exception);
$response = $exception->generateHttpResponse(new Response());
}
return $response;
}
The request is send as form data:
See example js code below:
(username is accepted, email param is added to demonstrate whats needed)
var formdata = new FormData();
formdata.append("grant_type", "password");
formdata.append("client_id", "828472a8-xxxx-xxxx-xxx-ab041d3b313a");
formdata.append("client_secret", "secret-xxx-xxx-xxx");
//formdata.append("username", "username");
formdata.append("email", "email#email.com");
formdata.append("password", "password");
var requestOptions = {
method: 'POST',
body: formdata,
redirect: 'follow'
};
fetch("{{base_url}}oauth/token", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
I'm doing login from an app using php and mysql. When I put the URL on the browser with credentials appended with it, if the credentials are valid, it prints correct response like success:true. If credentials are not valid, it prints success:false. But when I put do ionic serve and do a login from the app, it prints success:true on console all the time, even if the credentials are not valid.
This is my IONIC-2 code:
var headers = new Headers();
headers.append("Accept",'application/json');
headers.append('Content-Type','application/json');
let options = new RequestOptions({headers:headers});
let postParams={
username: logincreds.username,
password: logincreds.password,
}
this.http.post("http://vaishalishaadi.com/AppLogin.php", postParams, options)
.subscribe(data=>{
console.log(postParams);
console.log(data);
/*if(data.json().success=="success"){
}
else{
} */
}, error => {
console.log(error);
});
Following code is of PHP:
header('Content-type: application/json');
if($check){
session_start();
$_SESSION['u_id'] = $check->u_id;
$_SESSION['u_name'] = $check->u_firstname;
$login_response=["success"=>"true"];
//print(json_encode($login_response));
//echo $check->u_id;
$data[] = array(
'pram'=$username
'id' => $check->u_id,
'fname' => $check->u_firstname,
'lname' => $check->u_lastname,
);
$result = "{'success':true, 'data':" . json_encode($data) . "}";
}
else{
$result = "{'success':false}";
}
echo($result);
Found Solution Over It
Just changed the way I was passing parameters and also removed 'options' argument from post request.
let params = new URLSearchParams();
params.append('username',logincreds.username);
params.append('password',logincreds.password);
this.http.post(url, params)
.subscribe(data=>{
console.log(postParams);
console.log(data);
/*if(data.json().success=="success"){
}
else{
} */
}, error => {
console.log(error);
})
Use URLSearchParams instead of using array to collect parameters being passed to server
I have been struggling with getting the Stripe card errors to work properly with my AJAX call. Instead of returning some nice JSON, it is returning a 500 error. Of course, I need to be able to display the error for the user to see. I'm not sure if this is Laravel specific so I thought that was worth mentioning. Here is my try/catch block:
public function charge($type, $amount, $isSubscription = false)
{
try {
Charge::create([
'amount' => $amount,
'currency' => 'usd',
'description' => $type,
'customer' => $this->customer['id'],
]);
} catch (\Stripe\Error\Card $e) {
$body = $e->getJsonBody();
dd($body); // This does not work
}
It seems like I never reach the dd() block of code, but instead I get a 500 in the console and when I preview the error, it is in html like the Laravel exceptions. I have tried using echo json_encode() to return the error, but again, if I'm not even getting to the dd() part, then it makes sense I would never reach echo json_encode.
Here is my AJAX call:
$.ajax({
url: url,
data: data,
type: 'POST',
dataType: 'JSON',
success: function (data) {
console.log(data);
_.showSuccess();
_.clearForm();
},
error: function (response) {
_.hideSubmitProcessing();
console.log(response); // This is returning html and a 500 in the console
}
});
Here is a screenshot of the error in the console:
I've been looking at this for too long and def need another set of eyes to help me out.
I know this is an old post, here's the fix if anyones still looking for it:
\Stripe\Exception\CardException
- this is now used as the main exception for any stripe card exception.
} catch (\Stripe\Exception\CardException $e) {
return response()->json([
'status' => 5,
'message' => $e->getMessage()
]);
} catch (Exception $e) {
return response()->json([
'status' => 5,
'message' => $e->getMessage()
]);
}
I have a file ajax.php which I am using to process data passed through jquery. I have this particular line of code called on successful form verification:
$.post("/ajax.php",{'request': 'emailLogin', 'loginmail': mail, 'loginpass': pass}, function(data) {} );
data in my case is: {"valid":true}{"auth":false}which is returned as a response from ajax.php, but I can't seem to file the correct way of defining "auth" and a variable with value "false".
My ajax.php is just checking if login and password are in the database and than echo json_encode(array('auth' => false)); or echo json_encode(array('auth' => true)); depending on the result. But it has also contain these lines:
if( isset($_POST['loginmail'])) {
$usermail = htmlspecialchars($_POST['loginmail']);
if (!filter_var($usermail, FILTER_VALIDATE_EMAIL)) {
$response = array('valid' => false, 'message' => 'You did not enter a correct email address.');
} else {
// All good
$response = array('valid' => true);
}
}
echo json_encode($response);
Don't echo json_encode($response) separately from the authentication result, you need to combine them. After you do the authentication, do:
$response['auth'] = $result_of_authentication;
then do
echo json_encode($response);
Once you do this, you should be able to access data.auth in Javascript. You should tell $.post that it's returning JSON:
$.post("/ajax.php",{
'request': 'emailLogin',
'loginmail': mail,
'loginpass': pass},
function(data) {
alert(data.auth);
},
"json");
Based on your PHP code you should be able to access the valid attribute like so:
$.post("/ajax.php",{'request': 'emailLogin', 'loginmail': mail, 'loginpass': pass}, function(data) {
var auth = data.valid;
if (auth) {
// do something!
} else {
// do something else!
}
});
Also there is a bug in your PHP code, you need to set up a default value for $response like so:
$response = array('valid' => false, 'message' => 'Email address is required');
if( isset($_POST['loginmail'])) {
$usermail = htmlspecialchars($_POST['loginmail']);
if (!filter_var($usermail, FILTER_VALIDATE_EMAIL)) {
$response = array('valid' => false, 'message' => 'You did not enter a correct email address.');
} else {
// All good
$response = array('valid' => true);
}
}
echo json_encode($response);
Otherwise if $_POST['loginmail'] is not set your app with throw an undefined variable exception
EDIT:
As Barmar pointed out in his answer, you should only echo a response back once time to avoid creating an invalid response. Any data you need should be sent back in a single array. I don't see you doing that in your PHP code but you do make mention of echoing another array ['auth' => false] which will not work the way you want it to
I have read a few posts on fail parameters for a JQuery Ajax call, but none that have directly answered my question. If you want to read up on my jumping off point here, this post would be a good start:
jquery: is there a fail handler for $.post in Jquery?
My problem is that there are a handful of things that may cause my application to fail - if my script returns false the above method would work just fine for me (if I understand it correctly), but most of the time my script will fail by kicking out an exception that I handle using the Zend Framework. I would prefer to return the exception so that I can provide the user with a more detailed message. Is it possible to have my PHP script return a value while still letting the Ajax call know that it was a failure?
Sure you can. First of all you need to categorize you errors, for example:
Fatals
Exceptions
false / error status
I would advise you to take as a return value for correct and with no errors processing - 0. In all other case that would be an error.
Another useful advise would be to use JSON as a client-server conversation.
In PHP it would be:
function prepareJSONResponse($code, $message, array $extra = array())
{
return json_encode(array_merge(
$extra, array(
'code' => (int) $code,
'message' => $message)));
}
In this case you could pass error code and message, and additional params in $extra, for example, for this call:
prepareJSONResponse(1, 'Not enough data passed', array('debug' => true));
Response from server side would be:
{code:1,message:'Not enough data passed','debug': true}
For the client side you need a wrapper function for $.ajax:
// calback(result, error);
function call(url, params, callback)
{
if (typeof params == 'undefined') {
params = {};
}
$.ajax({
'type' : "POST",
'url' : url,
'async' : true,
'data' : params,
'complete' : function(xhr) {
if (xhr.status != 200) {
if (typeof callback == 'function') {
callback(xhr.responseText, true);
}
} else {
if (typeof callback == 'function') {
callback(xhr.responseText, false);
}
}
}
});
}
and function to validate JSON, in order if the corrupted format comes.
function toJSON(data){
try {
data = JSON.parse(data);
} catch (err) {
data = { 'code' : -999, 'message' : 'Error while processing response' };
}
if (typeof data.debug != 'undefined') {
console.log(data.debug);
}
return data;
}
Wrap in try-catch you code, and in catch statement do something like:
try {
...
} catch (Exception $e) {
exit(prepareJSONResponse(1, $e->getMessage(), array(
'debug' => 'There was an error while I were processing your request')));
}
The result would be that you receive debug information in browser console, and could handle errors / exception (prepareJSONResponse()) and fatals (by reading HTTP-status header, if it's not 200, then there was error).
Hope thats what you asked about.