Google Classroom push notification registration Permission Denied for Students Only - google-api

I'm trying to create a registration for push-notifications with Python googleapiclient for Google Classroom. My code is working for classes where the user is a teacher but is not working for when the user is a student in a given class. I've tried on gsuite and non gsuite accounts.
The error is googleapiclient.errors.HttpError: <HttpError 403 when requesting https://classroom.googleapis.com/v1/registrations?alt=json returned "The caller does not have permission">
The relevant code is
def register(self, courseId):
body = constants.registration_body(courseId)
o = self.service.registrations().create(body=body).execute()
return o["registrationId"], o["expiryTime"]
where self.service is build("classroom", "v1", credentials=get_creds(uid, db)).
and constants.registration_body returns
{
"feed": {
"feedType": "COURSE_WORK_CHANGES",
"courseWorkChangesInfo": {
"courseId": courseId,
},
},
"cloudPubsubTopic": {
"topicName": secret.pubSubTopicName,
},
}
I have also enabled all relevant API Scopes to remove that from troubleshooting:
scopes = [
"https://www.googleapis.com/auth/classroom.push-notifications",
"https://www.googleapis.com/auth/classroom.coursework.students.readonly",
"https://www.googleapis.com/auth/classroom.coursework.me.readonly",
"https://www.googleapis.com/auth/classroom.announcements.readonly",
"https://www.googleapis.com/auth/classroom.courses.readonly",
"https://www.googleapis.com/auth/classroom.courseworkmaterials.readonly",
"https://www.googleapis.com/auth/classroom.topics.readonly",
"openid",
]
I'm not sure if it is a code error since it works when users are teachers. Is this a limitation of the Google Classroom API?
Full code: https://github.com/karmanyaahm/google_classroom_discord_feed

This is intended behaviour:
Your code is fine, and this is working as intended. Push notifications are a tool to manage courses, not to be used by students, so it makes sense that only teachers and administrators can create registrations.
While not very explicit, the fact that a user needs to be a teacher in order to manage notifications is implied by the following statement, to be found in the official docs:
Your Cloud Pub/Sub topic only receives notifications about resources that you can view with the credentials you supply when creating a registration. For example, if the user revokes permission from your application or is removed as a teacher, notifications are longer delivered.
Reference:
Push notifications in the Classroom API

Related

Can I move Google calendar events from one user to another user via API with a Service Account

I have created a Service account and I need to move event1 from calendar1 of User1 to calendar2 of User2.
When I request access token as User1 with "sub":"user1#gmail.com" during JWT step and using that token When I do following
POST https://www.googleapis.com/calendar/v3/calendars/User1calendarId/events/event1Id/move?Destination=user2calendarId
I get following error
{
"error": {
"errors": [
{
"domain": "calendar",
"reason": "requiredAccessLevel",
"message": "You need to have reader access to this calendar."
}
],
"code": 403,
"message": "You need to have reader access to this calendar."
}
}
Are there any permission that needs to be assigned to Service Account in order to make this operation? or What should be correct way to move event between different user's calendar as a Service Account?
Explanation:
The scopes you are adding to your application are classified as sensitive scopes, as they request access to private user data such as Calendar events.
Your application would need to undergo a verification process to be able to use these scopes. For more information, please check the official documentation.
Sensitive scopes
Some of the scopes used by the following APIs are considered sensitive; see the API documentation or look for the lock icon in the Cloud Console. If your app requests sensitive scopes, and doesn't meet any of the criteria for an exception (see below), you will need to verify that your app follows the API Services User Data Policy.
For a complete list of Google APIs, see OAuth 2.0 Scopes for Google APIs. To check if scopes are sensitive or restricted, add the scopes to your project via the Google Cloud Console.

Classroom API - Access classroom with Service Account

I need some help as I'm really stuck!!!! I have spent days and hours on this one but I can't figure it. I have searched all possible forums and other similar posts without any success.
So, the requirement :
We are trying to integrate Classroom API on our .Net platforms. The tricky part is that they want to use service accounts.
The problem :
Google.Apis.Requests.RequestError The caller does not have permission [403]
The caller does not have permission] Location[ - ] Reason[forbidden] Domain[global]
I have followed the documentation as shown in :
https://developers.google.com/identity/protocols/OAuth2ServiceAccount.
I understand that we need to set up a service account in the Google API Console, so I've done the following:
1) I have created a service account and enabled G Suite Domain-wide Delegation in the Google API Console
2) In the Admin Console, in Manage API Client Access, I have entered the service account's client id and have enabled scopes.
3) A have downloaded the json file with all the service account credentials (private key, email)
and the code...
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(cr.client_email)
{
Scopes = new[] { ClassroomService.Scope.ClassroomCourses },
}.FromPrivateKey(cr.private_key));
// Create the service.
service = new ClassroomService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Demo-School",
});
and the actual call to the Classroom API to create a course :
var resource = service.Courses.Create(course);
var result = await resource.ExecuteAsync();
So, despite all that, whenever i try to create a course, I get the above error.
When I try to create a Course using the Reference page (https://developers.google.com/classroom/reference/rest/v1/courses/create) it works fine. I can create courses, teachers, set permissions etc..
But when I try to do that programmatically.. i.e from a console app, there is NO way I can get it working.
Can ANYONE please advice???????What am I missing??

Top-level access token returned from Slack Button

I have a question about the top-level access token that is returned after the "Add to Slack" button is clicked and consent is granted.
This is the JSON response:
{
"access_token": "xoxp-XXXXXXXX-XXXXXXXX-XXXXX",
"scope": "incoming-webhook,commands,bot",
"team_name": "Team Installing Your Hook",
"team_id": "XXXXXXXXXX",
"incoming_webhook": {
"url": "https://hooks.slack.com/TXXXXX/BXXXXX/XXXXXXXXXX",
"channel": "#channel-it-will-post-to",
"configuration_url": "https://teamname.slack.com/services/BXXXXX"
},
"bot":{
"bot_user_id":"UTTTTTTTTTTR",
"bot_access_token":"xoxb-XXXXXXXXXXXX-TTTTTTTTTTTTTT"
}
}
In documentation https://api.slack.com/docs/slack-button, the only place that mentions the top-level access_token is "Use the top-level access_token value for other integration points."
Could you please give some examples on how the top-level access_token will be used?
This is the standard response from Slack after a successful installation of your app to a Slack workspace, e.g. via "Add to Slack" button.
You get two tokens, which have different meanings:
access_token: This is called the user token. It allows your app to work directly on behalf of users, based on the OAuth scopes they award to your app. e.g. it can upload files on behalf of the user that installed the app. You always get this token if you install a Slack app.
bot_access_token: bot token, which allows your app to work on behalf of its bot user and always has the bot scope. You only get this token if your app includes a bot user.
If you have both tokens I would recommend to use the bot token primarily, because that way all your actions will clearly show as being related to your app.
Note that not all API methods work with a bot token. (check the documentation of your API method to find out which token works)

Get a user's API key for using in Slack

So I'm building a small Slack bot that I want multiple users to be able to use in different Slack teams. So far the workflow is like this:
User signs up on website.
User connects with an API provider and receives their OAuth credentials. The access token for each user is saved in the database.
User adds Slack bot to their team.
With hardcoded API values the bot retrieves the desired data, but what is the best way for the bot to be able to get the appropriate data for each Slack team?
I obviously don't want a user to need to keep signing into the website etc, so how do I associate the slack team with the Laravel user and then pull the relevant API data?
For some example code, imagine that I have a Strava access token stored in my DB for a user and I want to call the API:
$botman->hears('runstats', function ($bot) {
$payload = \Strava\Account::get(
\Auth::user()->strava_id,
array('api_key' => "here_is_a_secret_key")
);
$bot->reply($payload->monthly_kms);
This works fine when I query from my web interface as I'm signed into my website and it spits back 123km as an example.
Obviously when I'm signed into Slack then there's no Auth::user instance and so it cannot find the relevant Strava ID. That's what I want to be able to retrieve for the relevant Slack user. I envisage it being installed in multiple Slack workspaces.
You need to store the relation between a Slack user (with team ID, user ID) and his individual token for each API in your database.
So you have two options when adding new API tokens:
Ensure that the process of adding new tokens for API services is always started on Slack (e.g. with a slash command) and then forward the user to your webpage. Thus your app knows which user it is.
Let users log into your web-page with their Slack credentials (using Slack Sign-in).
Both options require that your Slack app has been previously installed to the relevant team of course.

Getting user's Google Account avatar without him signing in with Google

I have a web application where users can sign in with their username and password or with Google Account. If the email from their Google Account happens to be one of the users' email, this user is signed in. In the response from Google API on sign in I get their avatar.
Is it possible to get user's avatar from Google Account just by email without them having to sign in?
While technically speaking a users profile info should be public. You shouldn't need access to see a users google avatar. The problem is that there is no way to search for a user based upon their email address.
I tried people api, gmail api, contacts api, google plus api. None would allow me to search unauthenticated for a user based upon their email address.
update
after google+ shutdown this workaround no longer works
The only thing I did find that worked was this.
http://www.google.com/profiles?q=myemail#gmail.com
Which will really only work if the user has a Google+ account. You should be able to scrape the users id off of that then run an Activities: search which would return any posts they had made and in that contains.
"actor": {
"id": "117200475532672775346",
"displayName": "Linda Lawton",
"url": "https://plus.google.com/117200475532672775346",
"image": {
"url": "https://lh5.googleusercontent.com/-a1CWlFnA5xE/AAAAAAAAAAI/AAAAAAAAdVM/sHkU9F-AwwQ/photo.jpg?sz=50"
},
Again all of this will only work if the user has a google+ account and actually uses it.

Resources