I am trying to load from a web server some scores from GPGS, using the Google API PHP Client.
Here's how I proceed:
1/ SETTING UP THE OAUTH CLIENT
I created the OAuth client on the Google API Console using a service account, according this doc: https://developers.google.com/accounts/docs/OAuth2ServiceAccount
It provided me a certificate + an email address + a client_id.
2/ WRITING PHP CODE
Here's my code:
$client = new Google_Client();
$client->setApplicationName("");
$client->setAssertionCredentials(
new Google_Auth_AssertionCredentials(
"something#developer.gserviceaccount.com", // email provided by console
array('https://www.googleapis.com/auth/games'), // scope
file_get_contents("../certificates/certificate.p12") // keyfile i downloaded
)
);
$service = new Google_Service_Games($client);
$service->scores->listScores("myLeaderboardId", "PUBLIC", "ALL_TIME");
3/ FIRST RESULTS
The first weird thing about this snippet, is that the API thrown me an error with an HTTP status 401 with this message:
Request was missing required scope(s): plus.login
According the official documentation (https://developers.google.com/games/services/web/api/scores/list) the required scope for this request is only games
4/ HITTING A WALL
Adding this scope to my request was really not a big deal, but after that, the API responded me again with a 401 HTTP status:
User has not completed registration
which I completly understand, since I am using credentials from a service account, and not a real account.
QUESTION
What am I doing wrong? Do I really can load leaderboards by calling the Google API from a server?
Thanks in advance for helping me,
Regards,
Related
I am building a feature for a PHP Symfony app that will update calendar events in a Google Calendar upon changes in my database on my server. The calendar belongs to the google account info#my-domain.com which I administer (domain just illustrative).
I am following the instructions for the google-api-php-client in combination with the example for using this library with the calendar API.
Since this is not a multiuser scenario but pure server-to-server communication I opted for a service account on the Google Cloud Platform.
I created a project while logged in as info#my-domain.com and a service account. I downloaded the credentials.json for that service account. I enabled the Google Calendar API.
Now to the problem:
When I use this library this way:
$client = new \Google_Client();
$client->setAuthConfig('/config/google_api_keys.json');
$client->addScope(\Google_Service_Calendar::CALENDAR);
$cal_service = new \Google_Service_Calendar($client);
$results = $cal_service->calendarList->listCalendarList()->getItems();
dump($results); //basically a fancy symfony-version of print_r()
die();
the code throws no errors but the variable $results is empty even though it should contain 3 calendars.
Yet when I use the API Explorer while being logged in as info#my-domain.com the result of the same operation (GET https://www.googleapis.com/calendar/v3/users/me/calendarList) contains the 3 items I am looking for.
Just to check, I tried instead to use the PHP library to get the events for one of the 3 calendars using its id s2b[...]e81#group.calendar.google.com, but Google responded with 404-json containing "Not found".
One caveat with the API Explorer is that it only allows for login with OAuth 2.0 so seeing what might be wrong with a service account is not possible.
Does anyone see what I might be doing wrong? Or what I should try next? Or what concept I might have misunderstood when using the API?
possible cause for your issue one
Remember that listCalendarList is not automatically populated if you want a calendar to appear in listCalendarList then your going to have to insert it there. I suggest trying to do a listCalendarList.insert and trying to add the calendar id that you gave it access to.
If that returns an error then see possible cause for issue number to
possible cause for your issue two
I assume that you have set up domain wide deligation but you forgot to set which user you are delegating as you do that by setSubject
function initializeCalendar()
{
// Use the developers console and download your service account
// credentials in JSON format. Place them in this directory or
// change the key file location if necessary.
$KEY_FILE_LOCATION = __DIR__ . '/service-account-credentials.json';
$user_to_impersonate ="user#domain.com";
// Create and configure a new client object.
$client = new Google_Client();
$client->setApplicationName("Hello Calendar");
$client->setAuthConfig($KEY_FILE_LOCATION);
$client->setScopes(['https://www.googleapis.com/auth/calendar']);
$client->setSubject($user_to_impersonate);
$service = new Google_Service_Calendar($client);
return $service;
}
Without setting up delegation the service account does not have access to any calendars.
Okay, with the help of #daimto I could come to a very simple solution:
I had to actually share the calendar owned by info#my-domain.com with the service account by adding its email address abc-123#my-project-name.iam.gserviceaccount.com in the calendar settings, just like I'd share this calendar with any other physical person like eric#gmail.com.
So my understanding of what a service account actually is was seriously flawed. I thought that it would be the co-owner of any resource (docs, spreadsheets, calendars, etc) that project's owner owned.
WRONG: info#my-domain.com owns the project my-project-name which "owns" the service account abc-123#my-project-name.iam.gserviceaccount.com and therefore the service account owns "everything".
(MORE) RIGHT: The service account acts rather like a virtual user that first has to get access to any resource that it's supposed to be working with. The access sharing can be done like you would add a friend to a resource or via an API.
right now i'm using google-calendar-api with Laravel, i want to create a reminder, and let the user decides if he wants to shows it in his Google Calendar (based in his gmail account). Right now this code works fine:
I got an error when trying to add an attendee, Googling i found out that you need to "impersonate" the user you want to invite, so i tried the next approach:
And getting this error:
What do you guys think am i doing wrong?
In my Google Api Console i'm using a Service Account, i tried with several keys, i enabled Domain Wide Delegation:
Nothing works, as i said, i can create and list the events, but can't invite anyone.
Thanks in advance!
The error message
the client is not authorized to request a token using this method
Means that the client credetials that you created on Google developer console do not match the login method you are using
You apear to be using code designed for use with a service account
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
To use this you need to create service account credentials on Google developer console. You have not.
I am using the PHP SDK. I created a user account under my admin account. I use "send on behalf of" to send envelopes from the user account. I am able to check the status of and download completed envelope documents and tab data with the master account, but I am unable to update the envelope notification settings from the master account.
The error I get is:
"errorCode": "USER_LACKS_PERMISSIONS",
"message": "This user lacks sufficient permissions to access this resource."
Am I unable to update the notification settings on behalf of another user through the API? Here is the relevant code snippet:
$envelopeApi = new DocuSign\eSign\Api\EnvelopesApi($apiClient);
$expirations = new DocuSign\eSign\Model\Expirations();
$expirations->setExpireAfter('120');
$expirations->setExpireEnabled('true');
$expirations->setExpireWarn('0');
$reminders = new DocuSign\eSign\Model\Reminders();
$reminders->setReminderDelay('5');
$reminders->setReminderEnabled('true');
$reminders->setReminderFrequency('5');
$envelope_notification_request = new DocuSign\eSign\Model\EnvelopeNotificationRequest();
$envelope_notification_request->setReminders($reminders);
$envelope_notification_request->setExpirations($expirations);
$envelope_notification_request->setUseAccountDefaults('true');
$envelopeApi->updateNotificationSettings($accountId, $id,
$envelope_notification_request);
This is when I get an error. I have tried using SendOnBehalfOf in the headers and without, with no change in results. Does anyone know if it is simply not possible to update the notification settings on behalf of another user with the API?
Thank you
OAuth JWT Grant is the recommended authentication technique instead of the old SOBO system. See https://github.com/docusign/eg-01-php-jwt for an example of how to do this.
That probably isn't the issue but can only help.
The best would be to set the notification parameters when you create the envelope.
Another possibility: when you try to set the notification parameters are you sure that the envelope is not complete?
Next idea: use the API Logging system to see exactly what was sent to DocuSign. Check it against the API reference page for that call as a check that the call is being made correctly.
Finally, I don't understand why you're requesting the account defaults and also trying to set the notification parameters. Wouldn't it be one or the other?
I recently get in touch with Google merchant product to sync all my website products into Google Merchant. When I follow the structure of the API documentation https://developers.google.com/shopping-content/v2/quickstart
down to Authorization section I copy their library and copy the sample code to use. It actually work! However, when I doing testing to load that auth page it requires me to log in to the developer account for getting the access token and save it into session.
Is there any possibility that I can skip the login section to make it automatically then I can do corn system to run the sync (update products' details) hourly?
I tried to hardcore my account login API key into my code like this:
$client = new Google_Client();
$client->setApplicationName('Sample Content API application');
//add my api key here
$client->setDeveloperKey(MY_API_KEY);
$client->setClientId('YOUR_CLIENT_ID');
$client->setClientSecret('YOUR_CLIENT_SECRET');
$client->setRedirectUri('YOUR_REDIRECT_URI');
$client->setScopes('https://www.googleapis.com/auth/content');
But it doesn't workЖ шt still requires me to log in.
You want to use a service account for this.
The Google OAuth 2.0 system supports server-to-server interactions such as those between a web application and a Google service. For this scenario you need a service account, which is an account that belongs to your application instead of to an individual end user. Your application calls Google APIs on behalf of the service account, so users aren't directly involved. This scenario is sometimes called "two-legged OAuth," or "2LO." (The related term "three-legged OAuth" refers to scenarios in which your application calls Google APIs on behalf of end users, and in which user consent is sometimes required.)
Below is a working example of authentication via Service account with PHP.
PREREQUISITES
Install the "Content API for Shopping" library which you can download here. For installation see here.
Create your service account. Here you will find the complete procedure.
At this point you will have obtained your JSON file needed for authentication.
As suggested by Google:
Important: Protect the *.json key file that allows a service account
to access the Google services for which it has been authorized. It is
good practice to allow service accounts to only access one Google API
each. This is a preventative measure to mitigate the amount of data an
attacker can access in the situation that the service account’s *.json
key file is compromised.
You can now use the following function to get the access token for the API call:
// gets access token for API call to Google Merchant Center
function gets_access_token_for_API_call() {
// load the "Google APIs Client Library for PHP"
require_once ( '/path/to/google-api-php-client/vendor/autoload.php' );
// gets the JSON key of the service account
$credentialsFilePath = '/path/to/merchant-center-123456789-987654321.json';
$client = new Google_Client();
$client->setAuthConfig($credentialsFilePath);
$client->addScope( 'https://www.googleapis.com/auth/content' );
// fetches a fresh access token with a given assertion token.
$client->fetchAccessTokenWithAssertion(); // the deprecated alias: "refreshTokenWithAssertion()"
$token = $client->getAccessToken();
return $token;
}
The returned result will be an array similar to:
{
"access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
"scope": "https://www.googleapis.com/auth/content"
"token_type": "Bearer",
"expires_in": 3600
}
The code has been tested and works.
I want to be able to query the Gmail API through a HTTP GET request.
I'm trying to query the Gmail API to get a message unread count from my INBOX label.
API Reference : https://developers.google.com/gmail/api/v1/reference/users/labels/get
The API reference shows the following HTTP request to get the unread count.
GET https://www.googleapis.com/gmail/v1/users/userId/labels/id
The API reference also says you need authorization through OAuth 2.0.
I managed to get examples working in the PHP library to successfully query the API but there is not enough PHP documentation to write any specific code.
However the API reference lists all HTTP calls to access different parts of the API however I can't figure out how to use OAuth (Access Tokens) with these HTTP requests?
The official PHP client library comes with a few examples like this one that shows you how to authenticate using OAuth. The API documentation also has a lot of information about this process.
To get the unread messages count, you should do something like this:
// $googleClient is an authenticated instance of 'Google_Client'
$gmail = new \Google_Service_Gmail($googleClient);
$label = $gmail->users_labels->get('me', 'INBOX');
$unreadCount = $label->messagesUnread;
You might have to turn 'Conversation view' off in the Gmail settings for this to return an accurate result.
Accessing the Gmail API in php should be similar to other Google APIs from php. Maybe look at quickstart examples from the calendar or Google Drive APIs in PHP and work from there?
If you have the oauth2 access token you can often just put it in the "Authorization" header. c.f. https://www.rfc-editor.org/rfc/rfc6750#section-2.1
Though honestly, I think it'll be a lot easier long-term to figure out how to do it with the PHP Google APIs library...