PHP Google Search Console API "invalid_grant" response - google-api

I am using following PHP code to fetch data through Google Search Consonle API.
It was working fine 2 months ago but now it's showing invalid grand message instead of data. Please! need your help.
error: '400 - {"error":"invalid_grant","error_description":"Bad Request"}'
I've right credentials included. Also you can see token is saved in file and is being fetched on demand and getting refresh too. I don't why it's stopped working.
Thanks
At the top I've added
use Google_Client;
use Google_Service_Webmasters_SearchAnalyticsQueryRequest;
use Google_Service_Webmasters;
and here is the code
$siteToFetch = (!empty($site)) ? base64_decode($site) : "https://www.siteiamfulluserof.com/";
$client_id = 'XXXXXXXXXXXX-FULL-TOKEN-REMOVED';
$client_secret = 'xxxxxx-xxxxx_xxxxxxxxxxxxxxx-xxxx';
$redirect_uri = 'http://localhost/redirect_url';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setAuthConfig(public_path("client_secret_latest.json"));
$client->setScopes("https://www.googleapis.com/auth/webmasters", 'https://www.googleapis.com/auth/webmasters.readonly');
if (file_exists($this->tokenFile)) {
$accessToken = json_decode(file_get_contents($this->tokenFile), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
if (isset($_REQUEST['code'])) {
$authCode = $_REQUEST['code'];
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
if (!file_exists(dirname($this->tokenFile))) {
mkdir(dirname($this->tokenFile), 0700, true);
}
file_put_contents($this->tokenFile, json_encode($accessToken));
} else {
exit('No code found');
}
}
$client->setAccessToken($accessToken);
// Refresh Token if expired.
if ($client->isAccessTokenExpired()) {
$refreshTokenSaved = $client->getRefreshToken();
$client->fetchAccessTokenWithRefreshToken($refreshTokenSaved);
}
if ($client->getAccessToken()) {
$googleQuery = new \Google_Service_Webmasters_SearchAnalyticsQueryRequest();
$googleQuery->setStartDate(date('Y-m-d', strtotime('-180 days')));
$googleQuery->setEndDate(date('Y-m-d', strtotime('-3 days')));
$googleQuery->setDimensions(['page', 'date']);
$googleQuery->setSearchType('web');
try {
$service = new Google_Service_Webmasters($client);
$response = $service->searchanalytics->query($sitesFetched[0]["site"], $googleQuery);
$siteData = [];
foreach ($response as $row) {
$siteData[] = [
"site" => $row->keys[0],
"date" => $row->keys[1],
"clicks" => $row->clicks,
"impressions" => $row->impressions,
"ctr" => $row->ctr,
"position" => $row->position,
];
}
} catch (\Exception $e) {
$error = json_decode($e->getMessage());
if ($error->error = "invalid_grant") {
echo "You don't have proper permissions to access this site or data is being fetched.";
}
}
}

Related

Facebook uploading image with laravel framework

I am trying to uploading image to the facebook page using GraphQL API
Bellow is some code I am using
use SammyK\LaravelFacebookSdk\LaravelFacebookSdk as Facebook;
try {
$token = $token ? $token : $this->access_token;
// $fb = app(Facebook::class);
$fb = new Facebook(array( 'appId' => '366774494090568', 'secret' => '9f847b900176325ce45d87dec94e81ea', 'fileUpload' => true));
//$fb->setFileUploadSupport(true);
//$fb->setDefaultAccessToken($token);
return $fb;
} catch (\Exception $e) {
throw $e;
}
$payload = unserialize($scheduledPost->payload);
$images = $payload['images'];
$timezone = $payload['scheduled']['publishTimezone'];
$appUrl = config("app.url");
$mediaIds = [];
$mediaCount = 0;
foreach($images as $image){
$relativePath = $image['relativePath'];
$fullPath = $appUrl."/".$relativePath;
$media = ["url" => $fullPath, "published" => false];
$uploadResponse = $this->uploadMedia($media);
$mediaId = $uploadResponse['id'];
$mediaIds["attached_media[$mediaCount]"] = "{'media_fbid': '$mediaId'}";
$mediaCount++;
}
public function uploadMedia($media)
{
$fb = $this->setAsCurrentUser($this->access_token);
$response = $fb->post("/{$this->original_id}/photos", $media);
return $response->getDecodedBody();
}
When I use setFileUploadSupport(true), there is error that function is not defined
If I use new Facebook with 'fileupload' => 'true' it gives me error like bellow
exception: "Symfony\Component\Debug\Exception\FatalThrowableError"
file: "C:\Users\king\Documents\work\01_Unicilix\API\vendor\sammyk\laravel-facebook-sdk\src\LaravelFacebookSdk\LaravelFacebookSdk.php"
line: 28
message: "Argument 1 passed to SammyK\LaravelFacebookSdk\LaravelFacebookSdk::__construct() must implement interface Illuminate\Contracts\Config\Repository, array given, called in C:\Users\king\Documents\work\01_Unicilix\API\app\Traits\Facebook\FacebookTrait.php on line 22
This code was very correct.
The problem was I can get storage image from url because of the server(ubunt) permmission.

Laravel File Upload "Laminas\Diactoros\Exception\InvalidArgumentException"

Good day,
I have been running into this exception "Laminas\Diactoros\Exception\InvalidArgumentException: Invalid stream reference provided in file" while trying to upload a video file taken from the camera with react-native-image-picker. Now i ran into this same issue while trying to upload photos some days back till i switched from using "$file->move()" to using "Intervention Image". I dont really understand the error and need some help.
EDIT: I should also mention that when i used postman to upload, it was successful.
Thanks
public function save_verification_video(Request $request) {
/**
* 'file' => 'mimes:video/x-ms-asf,video/x-flv,video/mp4,application/x-mpegURL,video/MP2T,video/3gpp,video/quicktime,video/x-msvideo,video/x-ms-wmv,video/avi'
*/
try {
$validator = $this->validator($request->all(), [
'glam_id' => '',
]);
if ($validator['failed']) {
return \prepare_json(false, ['messages' => $validator['messages']],'',$status_code=200);
}
$data = $request->all();
if ($request->hasFile('body_video') || $request->hasFile('speech_video')) {
// $this->out->writeln("User ".$user->last_name);
$file = $request->file('body_video') ?? $request->file('speech_video');
$verification_type = ($request->hasFile('body_video')) ? 'body_video' : 'speech_video';
$path = public_path('/uploads/glams/'. $user->code . '/videos/'.$verification_type . '/');
File::makeDirectory($path, $mode=0777, true, true);
// $res = MediaUploader::fromFile($file)->upload();
$res = $file->move($path, $file->getClientOriginalName());
if ($res) {
return \prepare_json(true, [],\get_api_string('generic_ok'), $status_code=200);
}
else {
return \prepare_json(false, [],\get_api_string('file_not_ploaded'), $status_code=200);
}
}
else {
return \prepare_json(false, [],\get_api_string('no_videos'), $status_code=200);
}
}
catch(\Illuminate\Database\Eloquent\ModelNotFoundException $ex) {
return \prepare_json(false, [], \get_api_string('glam_not_found'));
}
catch(\Exception $ex) {
return \prepare_json(false, [],\get_api_string('error_occured').$ex->getMessage(), $status_code=200);
}
}

How can I store the web push notification settings after the login in database

I want to send web push notification on the browser. I used this tutorial to
send the notification. This is working fine and show the details.
{
"endpoint":"https://fcm.googleapis.com/fcm/send/ftB1OYn5bJY:APA91bGNcquGDcUXr29JiVV5Zos4Vi7FzmZ_wJQMITEXt8FlVBRBtgrPdLnPR6GALtnCOe9RNPP1cmC_bkv9D1BE1o6_-0cMXQsodpPoRCeOP5EDt6EwqK0ys36MbCi3HNTWf7ZcItVi",
"expirationTime":null,
"keys":{"p256dh":"BLJQqNovnlJ28d5xteX8whwdby6l0BYLvC_iyNtY2nO7YXQSI-EOvdOs1LXy8F_EuH2MZi0FU_HoCO-5GRQYYVQ",
"auth":"tDcEgiy5M5tJ3_vXuuQ9uw"}
}
but I want to integrate with my Laravel API.
After the user login, I want to save the endpoint, public key, and auth
to the database.
Login Controller
public function authenticate(Request $request)
{
$credentials = $request->only('username', 'password');
// return $credentials;
$response = array(
'status' => 'Failed',
'msg' => '',
'is_success' => false,
'data' => ''
);
try {
if (!$token = JWTAuth::attempt($credentials)) {
$response["msg"] = "Wrong Username or Password";
$response["status"] = "Failed";
$response["is_success"] = false;
} else {
if (Auth::user()->is_active == 0) {
$response["msg"] = "Your account has not been activated";
$response["status"] = "Failed";
$response["is_success"] = false;
} else {
$data = array();
$user = User::find(Auth::user()->id);
$data['id'] = $user->id;
$data['fname'] = $user->fname;
$data['lname'] = $user->lname;
$data['email'] = $user->email;
$data['username'] = $user->username;
$response["msg"] = "Login Successfully";
$response["status"] = "Success";
$response["data"] = compact('token');
$response["user"] = Auth::user();
}
}
} catch (\Exception $th) {
$response["msg"] = $th->getMessage();;
$response["status"] = "Failed";
$response["is_success"] = false;
}
return $response;
}
I think the best way to solve this, is to make another model for that data, a one to one relationship between user model and push notification data model. Make a controller for CRUD operations on this new model, and just have another http call from the front end to store the data.

Codeigniter with google oauth2 adds hashtag php to redirect('usercp')

I want to be able to redirect to another controller but when user logins in with google and is success full it gets redirected to there usercp but for some reason it gets the # from the end of here
http://www.example.com/test/google?code=4/sorrynocodeshown#
And when redirects using codeigniter redirect() it adds # to it.
http://www.example.com/usercp#
Question When redirecting to new page once successful login how to stop # from being added.
I use https://github.com/moemoe89/google-login-ci3
I also use vhost with xammp
Controller function
public function google() {
if ($this->input->get('code')) {
$googleplus_auth = $this->googleplus->getAuthenticate();
$googleplus_info = $this->googleplus->getUserInfo();
$google_data = array(
'google_id' => $googleplus_info['id'],
'google_name' => $googleplus_info['name'],
'google_link' => $googleplus_info['link'],
'image' => $googleplus_info['picture'],
'email' => $googleplus_info['email'],
'firstname' => $googleplus_info['given_name'],
'lastname' => $googleplus_info['family_name']
);
$login_google_userid = $this->login_model->login_with_google($googleplus_info['id'], $google_data);
$_SESSION['user_id'] = $login_google_userid;
redirect('usercp');
}
}
config/googleplus.php settings
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
$config['googleplus']['application_name'] 'Somename';
$config['googleplus']['client_id'] = '*****';
$config['googleplus']['client_secret'] = '*****';
$config['googleplus']['redirect_uri'] = 'http://www.mysetname.com/account/login/google';
$config['googleplus']['api_key'] = '*****';
$config['googleplus']['scopes'] = array();
I am using HMVC with codeigniter
application/modules/account/controllers/Login.php
Full Controller
<?php
class Login extends MX_Controller {
private $error = array();
public function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->library('googleplus');
}
public function index() {
if ($this->login_model->is_logged_in()) {
$this->session->set_flashdata('success', 'Welcome back! If you wish to logout ' . anchor('account/logout', 'Click Here'));
redirect(base_url('usercp'));
}
if (($this->input->server("REQUEST_METHOD") == 'POST') && $this->validateForm()) {
$this->load->model('account/login_model');
$user_info = $this->login_model->get_user($this->input->post('username'));
if ($user_info) {
$_SESSION['user_id'] = $user_info['user_id'];
redirect(base_url('usercp'));
}
}
$data['login_url'] = $this->googleplus->loginURL();
if (isset($this->error['warning'])) {
$data['error_warning'] = $this->error['warning'];
} else {
$data['error_warning'] = '';
}
if (isset($this->error['username'])) {
$data['error_username'] = $this->error['username'];
} else {
$data['error_username'] = '';
}
if (isset($this->error['password'])) {
$data['error_password'] = $this->error['password'];
} else {
$data['error_password'] = '';
}
// Common
$data['header'] = Modules::run('common/header/index');
$data['navbar'] = Modules::run('common/navbar/index');
$data['footer'] = Modules::run('common/footer/index');
$this->load->view('login', $data);
}
public function validateForm() {
$this->form_validation->set_rules('username', 'username', 'required');
$this->form_validation->set_rules('password', 'password', 'required');
if ($this->form_validation->run() == FALSE) {
$this->error['username'] = form_error('username', '<div class="text-danger">', '</div>');
$this->error['password'] = form_error('password', '<div class="text-danger">', '</div>');
}
if ($this->input->post('username') && $this->input->post('password')) {
$this->load->model('account/login_model');
if (!$this->login_model->verify_password($this->input->post('username'), $this->input->post('password'))) {
$this->error['warning'] = 'Incorrect login credentials';
}
}
return !$this->error;
}
public function google() {
if ($this->input->get('code')) {
$googleplus_auth = $this->googleplus->getAuthenticate();
$googleplus_info = $this->googleplus->getUserInfo();
$google_data = array(
'google_id' => $googleplus_info['id'],
'google_name' => $googleplus_info['name'],
'google_link' => $googleplus_info['link'],
'image' => $googleplus_info['picture'],
'email' => $googleplus_info['email'],
'firstname' => $googleplus_info['given_name'],
'lastname' => $googleplus_info['family_name']
);
$login_google_userid = $this->login_model->login_with_google($googleplus_info['id'], $google_data);
$_SESSION['user_id'] = $login_google_userid;
redirect('usercp');
}
}
}
Codeigniter's redirect() function uses the php header() function in 2 ways:
switch ($method)
{
case 'refresh':
header('Refresh:0;url='.$uri);
break;
default:
header('Location: '.$uri, TRUE, $code);
break;
}
using the refresh parameter will not add the hashtag.
You find more about this in system/helpers/url_helper.php
you can use this to your advantage in google_login.php changing
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
accordingly to
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Refresh:0;url=' . filter_var($redirect, FILTER_SANITIZE_URL));
When calling the redirect, you should be able to drop the hash by using the refresh param:
redirect('usercp', 'refresh');
You can modifying the url by doing something like
$url = strstr($url, '#', true);
But otherwise since it's a client-side stuff there's not a lot of options. You could also remove it from javascript when the client load the page with
history.pushState('', document.title, window.location.pathname + window.location.search)
since this is too long in the comment section, here goes:
try to use your browser's debug mode/developer tools, and see the network part of it. in there, you could see the sequence of requests when your page are loading.
if you are using chrome, thick the preserve log option before doing the oauth.
do the oauth and then try to find the request to google that redirects to your page.
click on the request, you will get the details of the request.
see for the response header, it should be 302 status and the destination should be your http://www.example.com/usercp url.
if you did not see the #, then you have problems in your part, try to check your .htaccess file.
if it's there in the destination, then the problem lies in google part, and not much you can do about it

Google Analytics Api Error

I am trying to make a call to get data from Google Analytics.
<?php
require_once 'lib/apiClient.php';
require_once 'lib/contrib/apiAnalyticsService.php';
session_start();
$client = new apiClient();
$service = new apiAnalyticsService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$accounts = $service->management_accounts->listManagementAccounts();
print "<h1>Accounts</h1><pre>" . print_r($accounts, true) . "</pre>";
try {
$data = $service->data_ga->get('ga:29214712', '2012-01-01', '2012-01-15',
'ga:visits', array('dimensions' => 'ga:source,ga:keyword', 'sort' =>
'-ga:visits,ga:source', 'filters' => 'ga:medium==organic', 'max-results' => '25'));
}
catch (apiServiceException $e) {
echo $e->getCode();
print_r($data);
}
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
After Wrapping the code in the TRY Catch Block i am getting the following error
403
Error calling GET https://www.googleapis.com/analytics/v3/data/ga?ids=ga%3A29214712&start-date=2012-01-01&end-date=2012-01-15&metrics=ga%3Avisits: (403) Forbidden
( ! ) Notice: Undefined variable: data in
C:\wamp\www\gitgrow\index.php on line 43
Note: I have granted the permission and have forced the Profile ID to test it.
The 403 error you're getting means the authorized user doesn't have access to the ga:29214712 reporting profile that is defined in your query.
Take a look at the HelloAnalyticsAPI.php sample in the examples/analytics/demo directory, and make sure you can connect to the API:
http://code.google.com/p/google-api-php-client/source/browse/#svn%2Ftrunk%2Fexamples%2Fanalytics%2Fdemo
Also, take a look at the Google Analytics developer guide. It will describe how you can obtain the correct profile IDs:
https://developers.google.com/analytics/devguides/reporting/core/v3/#user_reports

Resources