melomg melomg - 7 months ago 28
PHP Question

How can I reach users' calendar information on server?

Users authorize in my android application. And I am sending users' token and other information to my server. At this server I want to implement some logic for users.

I want to have exactly this flow.

I followed the steps quickstart.php in this link to get users' calendars on server.

But I get following error :


google oauth exception' with message 'could not json decode the token'


For this reason I tried this solution.
But i take same error. So as 3rd option I created the json format myself like in this solution as below.

$access_token = '{
"access_token":'.$access_token.',
"token_type":"Bearer",
"expires_in":3600,
"id_token":'.$id_token.',
"refresh_token":" ",
"created":'. time() .'
}';


as you see I do not know how to exchange refresh token . I searched how to get refresh token and saw this question. And implemented this solution to my code but nothing changed.

Edit 4 : I tried to get access token according to this answer at android application and send it to app server. I'm taking the code as before I did :

GoogleSignInAccount acct = result.getSignInAccount();
code = acct.getServerAuthCode();//sending this code to AsyncTask to get access token


my function to get Access Token:

private void getAccessToken()throws GoogleAuthException, IOException{
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
List<String> scopes = new LinkedList<String>();
scopes.add("https://www.googleapis.com/auth/calendar");
scopes.add("https://www.googleapis.com/auth/calendar.readonly");
scopes.add("https://www.googleapis.com/auth/urlshortener");

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(transport, jsonFactory, client_id, client_secret, scopes).build();

try{
GoogleTokenResponse res = flow.newTokenRequest(code).execute();
accessToken = res.getAccessToken();
}catch(IOException e){
}


at the php server side I changed user-example.php file little bit as below because I have the access token now:

$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setAccessType("offline");
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/urlshortener");
$service = new Google_Service_Urlshortener($client);
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
}
$client->setAccessToken('{"access_token":"'. $access_token .'","token_type":"Bearer","expires_in":3600,"created":'. time() .'}');
if ($client->getAccessToken() && isset($_GET['url'])) {
$url = new Google_Service_Urlshortener_Url();
$url->longUrl = $_GET['url'];
$short = $service->url->insert($url);
$_SESSION['access_token'] = $client->getAccessToken();


But now I'm getting below error:


Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST https://www.googleapis.com/urlshortener/v1/url: (403) Insufficient Permission' in C:\wamp\www\google-php\src\Google\Http\REST.php on line 110

Answer

I was getting Insufficient Permission error after I started to use GoogleAuthorizationCodeFlow to get access token as I mentioned in my OP. And then I tried to add Calendar scope to GoogleApiClient.Builder(this) but I get error like I can't add scope if I add Auth.GOOGLE_SIGN_IN_API because I had added Auth.GOOGLE_SIGN_IN_API to GoogleApiClient.Builder. So this time I tried to add the scope to GoogleSignInOptions.Builder and it is working now. I'm able to get both refresh token and access token. Below code solved my problem:

GoogleSignInOptions gso = state.getGso();
if(gso == null){
    gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(new Scope("https://www.googleapis.com/auth/calendar"))
        .requestIdToken(getString(R.string.server_client_id))
        .requestEmail()
        .requestServerAuthCode(getString(R.string.server_client_id), false)
        .requestProfile()
        .build();
}