Reputation: 35116
I have subscribed to a Google Calendar. I can see in the calendar the data, the events. But when I would download them via API, it gives me a permission denied error. Why?
Returned error message:
{
"message": "Failed to fetch calendar data",
"details": {
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Insufficient Permission",
"domain": "global",
"reason": "insufficientPermissions"
}
],
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
"domain": "googleapis.com",
"metadata": {
"method": "calendar.v3.Events.List",
"service": "calendar-json.googleapis.com"
}
}
]
}
}
}
code with googleapis.com
import { NextApiRequest, NextApiResponse } from 'next'
import { connectToDatabase } from 'lib/connectToDatabase'
import { Db, ObjectId } from 'mongodb'
import jwt from 'jsonwebtoken'
import { getTeams } from 'services/getTeams'
import { AuthResponse, JwtPayload } from 'tikexModule/Types/dto/user'
import { User } from 'types/user'
import { identifyGender } from 'services/identifyGender'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { userId, calendarId } = req.body
const { mongoClient } = await connectToDatabase()
const db: Db = mongoClient.db(process.env.DB_NAME)
const clientIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress
await db.collection('logs').insertOne({
api: 'fetchEventTimesFromGoogleCalendar',
createdAt: new Date(),
severity: 'log',
body: req.body,
clientIp,
})
try {
let user = await db
.collection<User>('users')
.findOne({ _id: new ObjectId(userId) })
if (!user?.googleAccessToken) {
return
}
const response = await fetch(
`https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(
calendarId
)}/events`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${user?.googleAccessToken}`,
},
}
)
if (response.ok) {
const data = await response.json()
await db.collection('logs').insertOne({
api: 'fetchEventTimesFromGoogleCalendar',
createdAt: new Date(),
severity: 'log',
clientIp,
eventTimes: data.items,
})
return res.status(200).json({
data: {},
})
} else {
const errorText = await response.json() // Get the response body text for debugging
return res
.status(404)
.json({ message: 'Failed to fetch calendar data', details: errorText })
}
} catch (error) {
await db.collection('logs').insertOne({
api: 'fetchEventTimesFromGoogleCalendar',
createdAt: new Date(),
severity: 'error',
error: error.message,
})
return res.status(500).json({ message: 'Failed to fetch calendar data' })
}
}
How to set scope
?
This is how google login click is handled:
<button
className={`${styles.button} ${styles.googleBtn}`}
onClick={() => registerGoogle()}
>
Google bejelentkezés
</button>
const registerGoogle = useGoogleLogin({
onSuccess: (tokenResponse) => {
console.log(tokenResponse)
auth.handleAuth(
'auth/registerGoogle',
{
accessToken: tokenResponse.access_token,
},
completion,
createTeamIfNotExist
)
},
})
Do I need to set scope somehow?
Upvotes: 0
Views: 55