I am trying to send push notifications to my android application using PHP server with Zend framework, but i am getting the HttpResponse as : The request could not be parsed as JSON or contains invalid fields, with the error code 400.
I have used the server code as given in the demo of Zend framework, which is as follows :
<?php
require_once 'Zend/Mobile/Push/Gcm.php';
require_once 'Zend/Mobile/Push/Message/Gcm.php';
$regId = $_POST["registrationid"];
$message = new Zend_Mobile_Push_Message_Gcm();
$message->setId(time());
$message->addToken($regId);
$message->setData(array(
'foo' => 'bar',
'bar' => 'foo',
));
$gcm = new Zend_Mobile_Push_Gcm();
$gcm->setApiKey('my api key');
try {
$response = $gcm->send($message);
} catch (Zend_Mobile_Push_Exception $e) {
// all other exceptions only require action to be sent or implementation of exponential backoff.
die($e->getMessage());
}
// handle all errors and registration_id's
foreach ($response->getResults() as $k => $v) {
if ($v['registration_id']) {
printf("%s has a new registration id of: %s\r\n", $k, $v['registration_id']);
}
if ($v['error']) {
printf("%s had an error of: %s\r\n", $k, $v['error']);
}
if ($v['message_id']) {
printf("%s was successfully sent the message, message id is: %s", $k, $v['message_id']);
}
}
I don't have my exact URL handy and I'm trying on my phone, but I touched on this recently in my blog. See http://www.rogerethomas.com
What you will need is to use a browser API key, not a server one. Don't ask why but it seems there's an error with Googles documentation.
Edit: here's a recent link to my answer from another similar question:
GCM with PHP (Google Cloud Messaging)
Related
I am trying to implement the new "Sign in with Google" button as described in https://developers.google.com/identity/gsi/web/guides/display-button.
Everything is fine, and I am able to get a response from the button with "credential" and "g_csrf_token" elements, which I can send to my server. However, using the Google API Client to decode the credential doesn't work. I'm trying to follow the instructions.
Here's my code:
$id_token = filter_input(INPUT_POST, 'credential');
$csrfToken = filter_input(INPUT_POST, 'g_csrf_token'); //??? Do we need this?
$client = new Google_Client(['client_id' => $clientid]);
$client->addScope("email"); // Recommended in another StackOverflow answer but makes no difference
try {
$payload = $client->verifyIdToken($id_token);
} catch(Exception $ex) {
$errorMessage = "Error in verifyIdToken():" . $ex->getMessage();
// ...do stuff with the error message
}
// ...do stuff with the returned payload
The result is the error message id_token must be passed in or set as part of setAccessToken.
I've updated my Google API Client to v2.11.
I assume that I've missed a step somewhere - can someone help?
Have found a solution, by trial and error! Turns out that $id_token needs to be passed to the client twice, once in setAccessToken() and then again in verifyIdToken(). Omitting setAccessToken fails (like the error message says), but if you pass it in setAccessToken but NOT in verifyIdToken, that doesn't work either.
$id_token = filter_input(INPUT_POST, 'credential');
$client = new Google_Client(['client_id' => $clientid]);
try {
$client->setAccessToken($id_token);
$payload = $client->verifyIdToken($id_token);
} catch(Exception $ex) {
$errorMessage = "Error in verifyIdToken():" . $ex->getMessage();
// ...do stuff with the error message
}
// ...do stuff with the returned payload
It would nice, if you're at Google and picking this up, if you updated the documentation.
While developing Recaptcha Enterprise for use of the V2 "I am not a robot" checkbox, I am stuck on this error:
Fatal error: Uncaught DomainException: Could not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information
I follow the link and have settled on this to authenticate:
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient([
'keyFile' => json_decode(file_get_contents($path_to_keyfile), true),
'projectId' => 'MY_PROJECT'
]);
I cannot find anything else that suggests I need to do anything more than this, and this link to the constructor API doesn't suggest I can pass it in as a parameter and then proceed. I do not want to use environment variables for this project, I want to connect manually in the code. What am I missing? I can confirm I have a working service account.
If it's helpful, the code I'm trying to run after I presumably authenticate is this:
// ==================== CAPTCHA ===================
use Google\Cloud\RecaptchaEnterprise\V1\RecaptchaEnterpriseServiceClient;
use Google\Cloud\RecaptchaEnterprise\V1\Event;
use Google\Cloud\RecaptchaEnterprise\V1\Assessment;
use Google\Cloud\RecaptchaEnterprise\V1\TokenProperties\InvalidReason;
$captcha_response = $_POST['g-recaptcha-response'];
$site_key = "123456789abc";
$client = new RecaptchaEnterpriseServiceClient();
define('SITE_KEY', $site_key);
define('TOKEN', $captcha_response);
define('PROTECTED_ACTION', 'signup');
define('PARENT_PROJECT', 'projects/MY_PROJECT');
$event = (new Event())
->setSiteKey(SITE_KEY)
->setExpectedAction(PROTECTED_ACTION)
->setToken(TOKEN);
$assessment = (new Assessment())
->setEvent($event);
try {
$response = $client->createAssessment(
PARENT_PROJECT,
$assessment
);
if ($response->getTokenProperties()->getValid() == false) {
printf('The CreateAssessment() call failed because the token was invalid for the following reason: ');
printf(InvalidReason::name($response->getTokenProperties()->getInvalidReason()));
} else {
if ($response->getEvent()->getExpectedAction() == PROTECTED_ACTION) {
printf('The score for the protection action is:');
printf($response->getRiskAnalysis()->getScore());
}
else
{
printf('The action attribute in your reCAPTCHA tag does not match the action you are expecting to score');
}
}
} catch (exception $e) {
printf('CreateAssessment() call failed with the following error: ');
printf($e);
}
Here's how I got it working. Thanks to John Hanley for the help in a previous answer. The documentation had lead me to believe that (for whatever reason) Storage was required, but that was not the case: it was as simple as providing the path to the key via the credentials parameter. Not the keyFile parameter.
if (empty($_POST['g-recaptcha-response']))
die("You have failed the not-a-robot check.");
$captcha_response = $_POST['g-recaptcha-response'];
require 'composer/vendor/autoload.php';
use Google\Cloud\RecaptchaEnterprise\V1\RecaptchaEnterpriseServiceClient;
use Google\Cloud\RecaptchaEnterprise\V1\Event;
use Google\Cloud\RecaptchaEnterprise\V1\Assessment;
use Google\Cloud\RecaptchaEnterprise\V1\TokenProperties\InvalidReason;
$path_to_keyfile = "MY_PROJECT-1234567890abc.json";
$site_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$client = new RecaptchaEnterpriseServiceClient([
'credentials' => $path_to_keyfile,
'projectId' => 'MY_PROJECT'
]);
define('SITE_KEY', $site_key);
define('TOKEN', $captcha_response);
define('PROTECTED_ACTION', 'signup');
define('PARENT_PROJECT', 'projects/MY_PROJECT');
$event = (new Event())
->setSiteKey(SITE_KEY)
->setExpectedAction(PROTECTED_ACTION)
->setToken(TOKEN);
$assessment = (new Assessment())
->setEvent($event);
try {
$response = $client->createAssessment(PARENT_PROJECT, $assessment);
if ($response->getTokenProperties()->getValid() == false) {
printf('The CreateAssessment() call failed because the token was invalid for the following reason: ');
printf(InvalidReason::name($response->getTokenProperties()->getInvalidReason()));
exit;
} else {
if ($response->getEvent()->getExpectedAction() == PROTECTED_ACTION) {
// Closer to 1 = human, to 0 = robot.
$bot_score = $response->getRiskAnalysis()->getScore();
// do what you want with the score here...
} else {
die('The action attribute in your reCAPTCHA tag does not match the action you are expecting to score');
}
}
} catch (exception $e) {
printf('CreateAssessment() call failed with the following error: ');
printf($e);
exit;
}
Your problem is that you are not specifying the service account to use in the client constructor and the system is falling back to using ADC (Application Default Credentials).
ADC will check the environment variable GOOGLE_APPLICATION_CREDENTIALS for the service account JSON key file.
You can set the environment variable before running your program:
Windows:
set GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
Linux:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
Or modify your program by changing this line of code:
$client = new RecaptchaEnterpriseServiceClient();
To this:
$options = ['keyFile' => $path_to_keyfile];
$client = new RecaptchaEnterpriseServiceClient($options);
Note 1:
If you are running your program on a Google Cloud computer service such as Compute Engine, App Engine, Cloud Run, ... the default service account will be used if neither of the above methods are implemented.
Note 2:
While developing, another method is to use the CLI's application default credentials. Run the following command using the Google Cloud SDK CLI:
gcloud auth application-default login
However, I have not verified that the reCAPTCHA Enterprise library checks for this type of credential.
I'm struggling to get a web service to work which we are using to integrate with a software package from Civica. Unfortunately they have sent us code in visual basic which we don't use here and I'm struggling to "translate" the visual basic into PHP.
So here's the code I have so far:
error_reporting(E_ALL);
$client = new SoapClient('https://xxx/cx/WebService/WSTokenService?
singleWsdl');
var_dump($client->__getFunctions());
The above works and I can see the functions. It's the next bit I can't get to work:
$request_param = array('Password' => 'xxx', 'UserName' => 'yyy');
try
{
$request = $client ->GetUserWSToken($request_param);
$result = $request ->GetUserWSTokenResult;
print_r($result);
}
catch (Exception $e)
{
echo "<P><P>Exception Error!";
echo $e->getMessage();
}
When I run the above code I get an error message "Exception Error!GetUserWSToken has service faults". I also get another error "Object reference not set to an instance of an object".
The visual basic code we've been sent by the package company to use is:
Dim tokenClient As New TokenService.WSTokenServiceClient
Dim tokenreq As New TokenService.SecurityTokenRequest
tokenreq.UserName = "usernamehere"
tokenreq.Password = "passwordhere"
Dim token = tokenClient.GetUserWSToken(tokenreq)
Does anyone know how to translate the visual basic above into what I need to do for PHP?
Our code sends twilio sms messages by doing the following:
// send the text message to the member's mobile phone
try {
// attempt to send the message through Twilio
$tw_msg = $twilio_client->messages->create(
"+1".$recipient['address'],
array (
'From' => "+1".$org['twilio_number'],
'Body' => $txtmsg,
'StatusCallback' => CALLBACK_LINK.'/text_message_handler.php'
)
);
// else trap the error since the message could not be sent and the callback routine is not called
} catch (Exception $e) {
// process the text message error
process_text_msg_error($db, $e, $org, $msg, $recipient);
}
In the v4 library we would get the error code by doing the following:
// get the twilio error components
$twilio_error_status = $e->getStatus();
$twilio_error_code = $e->getCode();
$twilio_error_msg = $e->getMessage();
This is not giving us what we expected using the V5 library. How do we get the error status and code using the V5 lib?
Twilio developer evangelist here.
It looks to me like you need to update one of the methods you call on the exception to get the status code. The exception is now a RestException and has the method getStatusCode(). You should update to:
// get the twilio error components
$twilio_error_status = $e->getStatusCode();
$twilio_error_code = $e->getCode();
$twilio_error_msg = $e->getMessage();
Let me know if that helps at all.
I am using soundcloud php sdk. It works successfully when i use the sdk to get track. But when i've tried to get an access Token in order to use it, the sdk send me back an error 401. After debugging the error message, i ve get the responseJSON below: {"error":"invalid_grant"}
This is my code , i m using Zend framework
$code = $this->getRequest()->getParam('code',false);
if($code){
$client = new Services_Soundcloud($this->soundcloud['client_id'],$this->soundcloud['secret_key']);
try {
$access_token = $client->accessToken($code);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
}
Did anyone has any idea about how to solve this error ?
In order to exchange a code for an access token, you must instantiate your Services_Soundcloud instance with a client id, client secret and a redirect uri. The following code should work, assuming you are storing the redirect uri in $this->soundcloud:
$client = new Services_Soundcloud(
$this->soundcloud['client_id'],
$this->soundcloud['secret_key'],
$this->soundcloud['redirect_uri']
);
$code = $this->getRequest()->getParam('code',false);
if ($code) {
try {
$access_token = $client->accessToken($code);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
}
Let me know if that solves the problem.