I'm trying to insert a new event using only an API Key that I created.
The problem is that when I'm just checking available times using FreeBusy, everything works perfectly, but when I try to create and insert a new event, I get the following error:
Uncaught Google_Service_Exception: {
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
In the Authorizing Requests to the Google Calendar API page it is stated that:
Your application must use OAuth 2.0 to authorize requests. No other
authorization protocols are supported. If your application uses Google
Sign-In, some aspects of authorization are handled for you.
But I can't manually authorize access to the calendar every time it is asked for.
How can I authorize requests and insert new events without having to manually authorize them?
You need to use a Service Account, if you want to perform server-to-server API requests. Please see https://developers.google.com/calendar/auth.
Generally you'd create a key, and download the JSON file that is provided. You can then call $client->setAuthConfig($jsonPath); to set up authentication. It's probably a good idea to keep the private key outside of the web root. Then set the scope using $client->addScope('https://www.googleapis.com/auth/calendar'), and instantiate the Calendar service using $service = new Google_Service_Calendar($client);. You should now be able to do your stuff.
You may also need to share the calendar with the generated e-mail address that is associated with the Service Account.
Related
I am trying to fetch order status in real time in php but not able to find proper way or documentation so I can go ahead.
In sales api I am getting details of sold subscription, but I want payment pending and cancelled orders too.
In Documentation I got below link
https://developers.google.com/android-publisher/api-ref/rest/v3/monetization.subscriptions/list
Gets below output when I run it in Try this method
{
"error": {
"code": 403,
"message": "The project ID used to call the Google Play Developer API has not been linked in the Google Play Developer Console.",
"status": "PERMISSION_DENIED"
}
}
But i am not able to implement it in PHP.
I had the same question so I raised a ticket and got reply that google play does not provide any API for order status, its available for kotlin and java only,
Target
I'm trying to integrate Google Calendar API to my company website to automate event creation upon some events.
The events will be added to a company calendar and displayed to the users, so i don't need the users to authenticate, i will not work on their own calendars.
What i've done
made a OAuth 2.0 service account as described in the Google OAuth 2.0 for Server to Server Applications docs
created, downloaded and added the credentials file to my project, and added its path to the environment variable GOOGLE_APPLICATION_CREDENTIALS;
followed the docs example to authorize my requests using the service account and the docs to create events.
Here's a short version of my sourcecode:
$client = new Google_Client();
$client->setApplicationName("XXX");
$client->addScope(Google_Service_Calendar::CALENDAR); // "https://www.googleapis.com/auth/calendar"
$client->useApplicationDefaultCredentials();
$service = new Google_Service_Calendar($client);
$event = new Google_Service_Calendar_Event(/* array with event data */);
$calendarId = /* calendar id taken from calendar Settings and Sharing on calendar.google.com*/;
$event = $service->events->insert($calendarId, $event);
Compared to the example (lines 43:52) I didn't manually check for the credential files but gone straight for useApplicationDefaultCredentials().
The error
The logged errror from my code is
[2020-10-19 14:29:19] local.ERROR: {
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "Not Found"
}
],
"code": 404,
"message": "Not Found"
}
}
{"userId":2,"exception":"[object] (Google_Service_Exception(code: 404): {
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"notFound\",
\"message\": \"Not Found\"
}
],
\"code\": 404,
\"message\": \"Not Found\"
}
}
at /var/www/vendor/google/apiclient/src/Google/Http/REST.php:123)
[stacktrace]
It looks like it is calling the wrong api endpoint since a 404 is a page not found response.
Calendar ID
Just to be clear, here is where i taken the calendar id
As far as I know, service accounts do not have their own calendars, so they need to be granted access to a specific organization in order to create/read events.
If this is for an internal application (and you are an administrator for your organization), you can follow the steps under Delegating Authority to grant your service account access to the calendars for your organization:
Then, a super administrator of the G Suite domain must complete the following steps:
From your G Suite domain’s Admin console, go to Main menu menu > Security > API Controls.
In the Domain wide delegation pane, select Manage Domain Wide Delegation.
Click Add new.
In the Client ID field, enter the service account's Client ID. You can find your service account's client ID in the Service accounts page.
In the OAuth scopes (comma-delimited) field, enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide full access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
Click Authorize.
You'll also need to follow the steps to impersonate a specific user under Preparing to make an authorized API call in order to retrieve a token for a user that has access to the calendar in question.
If this is for an application intended to be installed by multiple organizations, you should consider using a managed OAuth service, like Xkit (where I work). Xkit in particular has a Google Calendar Service Account connector that abstracts away all of these steps (including a step-by-step guide for the IT admin) from you as the developer to deliver you a working access token in one API call.
As a side note, the service account example you cited uses public data from the Books API, so it does not need authorization from a user, it only needs to identify itself as an application.
I am creating an app related to customer service and marketing through social media and YouTube are the project i am working on.
I have a job to obtain ads related data from YouTube api. I need to show this data on my app so our client can make sure that their money used in promoting their YouTube channel are not wasted. i am used to work in this api social media related field but this project really give me headache.
First of all i am confused where to start to get the data i obtain. i try to see YouTube analytics and reporting data but keep getting this error when im trying their api.
{
"error": {
"code": 403,
"message": "Forbidden",
"errors": [
{
"message": "Forbidden",
"domain": "global",
"reason": "forbidden"
}
]
}
}
i has enable the Youtube analytic and reporting api on my console
The coding language that i think i wii use is php so it will be great if you can give sugestion.
I'm using google-api-php-client to query YouTube Data API.
First, I get a token from a user with the following scopes:
[
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/youtube.readonly',
'https://www.googleapis.com/auth/yt-analytics-monetary.readonly',
'https://www.googleapis.com/auth/yt-analytics.readonly',
'https://www.googleapis.com/auth/youtubepartner',
'https://www.googleapis.com/auth/youtubepartner-channel-audit',
]
Then I make listChannels request:
(new \Google_Service_YouTube($client))->channels->listChannels('snippet', [
'mine' => 'true',
'maxResults' => 1,
]);
And most of the times it works like a charm. I get their channel data.
But sometimes it throws an exception with code 401 and the error message:
{
"error": {
"errors": [
{
"domain": "youtube.header",
"reason": "youtubeSignupRequired",
"message": "Unauthorized",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Unauthorized"
}
}
It looks like it happens for users who have multiple channels. But I tried adding a new channel to my personal account and choosing that new channel when authorizing access via OAuth. And it worked fine.
It's very confusing as far as why it happens, and the error message doesn't make much sense. Because their tokens are definitely fine, I can renew them or query their Google Plus profiles without problems.
Have anyone encountered that error?
Based from this documentation, youtubeSignupRequired indicates that the user has an unlinked Google Account, which means that the user has a Google Account but does not have a YouTube channel.
This error is commonly seen if you try to use the OAuth 2.0 Service Account flow. YouTube does not support Service Accounts, and if you attempt to authenticate using a Service Account, you will get this error.
The YouTube API blog post introducing Google Account support also discusses the youtubeSignupRequired error in more detail. Although the blog post explains the error for API version 2.1, the meaning of the error is still applicable.
Here are some related posts which might help:
Youtube API v3 return 401 when i try to upload video
Service account doesnt work with youtube. Also please ensure that if you are using a gmail ID it must be linked to youtube otherwise you would get 401.
Youtube v3 api 401 Unauthorized
The reason "youtubeSignupRequired" usually means the YouTube account has not been set up properly or you have not created your YouTube channel yet. This is a requirement before you can upload videos. It would be great if Google could improve their error message for this case and make it a bit more verbose.
Hope this helps!
How can I get a JSON with the events of a public Google Calendar? I have it's ID but no acess to it. I don't want to change its events, nor log in.
I would like get a JSON from it to sync with my PHP/MySql database.
Tried https://www.googleapis.com/calendar/v3/calendars/{calendarId}
but got login error:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
Since November 17th 2014, v1 and v2 of the Google Calendar API have been disabled.
Google Calendar API V3 requires oauth authentication for almost all of its operations. As near as I can tell, this also requires user interaction.
However, for public calendars, it is still possible to use a single link to get JSON data (this is not currently documented by Google - I don't know if it's oversight on their part or private API that might disappear tomorrow).
Register your application with the Google Developers Console
Activate the Google Calendar API in the Google Developers Console.
Under Credentials, create a new Public API access key (you may want to leave referrers blank for testing)
The JSON url now looks like this
https://www.googleapis.com/calendar/v3/calendars/{calendarid}/events?key={Your Public API Key}
(The curly braces {} should not present in the actual url).
The API documentation describes additional parameters you can include (except that you can also include the parameter &callback=, as with most JSON requests, to create a JSONP response for javascript).
Your calendar have to be shared publicly!
This one works if you have shared only free/busy status:
http://www.google.com/calendar/feeds/{calendarId}#group.calendar.google.com/public/basic?orderby=starttime&sortorder=ascending&futureevents=true&alt=json
Full details - this one works only if calendar is shared fully publicly
http://www.google.com/calendar/feeds/{calendarId}#group.calendar.google.com/public/full?orderby=starttime&sortorder=ascending&futureevents=true&alt=json
Or just free-busy
http://www.google.com/calendar/feeds/{calendarId}#group.calendar.google.com/public/free-busy?orderby=starttime&sortorder=ascending&futureevents=true&alt=json
Parameters orderby, sortorder and futureevents are optional but might help you later :)