Getting a 500 error for google calendar request - google-calendar-api

I have a node app that I am running locally in a lamda function using netlify dev. I get a 500 response error, not sure why I am pretty certain I have all the right credentials. I don't know how else to debug this. Hope some one can help I read something about trying to send the response 3s then 6s so on but that still returned the exact same issue. This is my first time using the api so not exactly sure what to do.
Keep in mind I am using the developer playground as my oauth redirect and have generated a refresh token there
const { google } = require("googleapis")
const { oAuth2 } = google.auth
const oAuth2Client = new oAuth2(
"fdsfs.apps.googleusercontent.com",
"fdsaf"
)
oAuth2Client.setCredentials({
refresh_token:
"1//0fdsfas",
})
// Create a new calender instance.
const calendar = google.calendar({ version: "v3", auth: oAuth2Client })
// Create a new event start date instance for temp uses in our calendar.
const eventStartTime = new Date()
eventStartTime.setDate(eventStartTime.getDay() + 2)
// Create a new event end date instance for temp uses in our calendar.
const eventEndTime = new Date()
eventEndTime.setDate(eventEndTime.getDay() + 4)
eventEndTime.setMinutes(eventEndTime.getMinutes() + 45)
// Create a dummy event for temp uses in our calendar
const event = {
summary: `Meeting with David`,
location: `3595 California St, San Francisco, CA 94118`,
description: `Meet with David to talk about the new client project and how to integrate the calendar for booking.`,
colorId: 1,
start: {
dateTime: eventStartTime,
timeZone: "America/Denver",
},
end: {
dateTime: eventEndTime,
timeZone: "America/Denver",
},
}
// Check if we a busy and have an event on our calendar for the same time.
calendar.freebusy.query(
{
resource: {
timeMin: eventStartTime,
timeMax: eventEndTime,
timeZone: "America/Denver",
items: [{ id: "primary" }],
},
},
(err, res) => {
// Check for errors in our query and log them if they exist.
if (err) return console.error("Free Busy Query Error: ", err)
// Create an array of all events on our calendar during that time.
const eventArr = res.data.calendars.primary.busy
// Check if event array is empty which means we are not busy
if (eventArr.length === 0)
// If we are not busy create a new calendar event.
return calendar.events.insert(
{ calendarId: "primary", resource: event },
err => {
// Check for errors and log them if they exist.
if (err)
return console.error("Error Creating Calender Event:", err)
// Else log that the event was created.
return console.log("Calendar event successfully created.")
}
)
// If event array is not empty log that we are busy.
return console.log(`Sorry I'm busy...`)
}
)

It was a simple mistake
const { OAuth2 } = google.auth with capital O !not oAuth2

Related

Unable to catch the 'auth' event in Hub.listen while calling Auth.federatedSignIn

I am using SolidJS and building a SPA (no server rendering). For authentication, I use the #aws-amplify/core and #aws-amplify/auth packages. At the application root I call the Hub.listen function:
Hub.listen('auth', ({ payload }) => console.log(payload));
In the SignUp component I call Auth.federatedSignIn:
const SignUp = () => {
return (
<button onClick={() => {
Auth.federatedSignIn({ provider: CognitoHostedUIIdentityProvider.Google });
}}>
Sign up
</button>
);
}
I have configured the Amplify as such:
Amplify.configure({
Auth: {
region: import.meta.env.VITE_AWS_REGION,
userPoolId: import.meta.env.VITE_AWS_POOL_ID,
userPoolWebClientId: import.meta.env.VITE_AWS_POOL_CLIENT_ID,
oauth: {
domain: import.meta.env.VITE_AUTH_URL,
responseType: 'code',
redirectSignIn: location.origin + '/account/external',
redirectSignOut: location.origin + '/my',
},
},
});
When I click on the button I am redirected to the import.meta.env.VITE_AUTH_URL (simply outside of my app), choose an account, and then return back to the /account/external page. At that time I expect a consoled payload object in Web tools, but there is nothing. I get it when I call Auth.signOut(), so I assume that I configured Amplify correctly and Hub is subscribed to the auth channel.
My thoughts were that Hub cannot catch any events because after returning the application basically renders again in a new context and Hub simply isn't able to catch anything (events aren't sent from AWS?). I tried to declare the urlOpener function under the oauth property in the config and Google's sign page opened in a new tab, but even then I couldn't get any events in the preserved old page (from which I called Auth.federatedSignIn).
Questions:
How should I organize the code to get the signIn and signUp events?
Can I pass some data into the Auth.federatedSignIn to get it back in the Hub.listen, so I will be able to join the CognitoUser with the data that existed at the time of starting Sign in/Sign up (I want to add a new login type to existed user)?
Here is an example regarding the first question. Just check that your listener is set before you call the Auth.federatedSignIn() method.
export default class SignInService {
constructor(private landingFacade: LandingFacade) {
this.setupAuthListeners(); // Should be called at the top level.
}
private setupAuthListeners() {
Hub.listen('auth', ({ payload: { event, data } }) => {
switch (event) {
case 'signIn':
this.landingFacade.signInSuccess();
break;
case 'signIn_failure':
console.log('Sign in failure', data);
break;
case 'configured':
console.log('the Auth module is configured', data);
}
});
}
public async signIn(): Promise<void> {
await Auth.federatedSignIn();
}
}
For the second one: I'll use a local state and set/query the object you need.

flutter app - trending posts by using google analytics data api

In my app, users create posts and I'd like to show trending posts by the number of views, comments, etc in a specific date range. To do that I thought I can create a custom event as below:
await FirebaseAnalytics.instance.logEvent(
name: "trending_contents",
parameters: {
"content_type": EnumToString.convertToString(type),
"content_id": contentModel.externalId,
"action_type": "post",
"point": 3,
},
);
I wonder if it is possible to use Google Analytics Data API to get trending posts by a specific date range? Or is there any better way to get trending posts instead of google analytics data API?
I finally found a solution on how to use Google Analytics Data API to manage trending content. If anyone is looking for a solution for a similar need, here is what I've done so far:
I send a custom event in specific situations such as when the user views the content etc. as below. If you use parameters' names according to predefined dimensions & metrics (see API Dimensions & Metrics), it will be easy to prepare a custom report (at least it was for me...). Later, I use contentType and contentId as dimensions and eventValue as a metric in the custom report.
await FirebaseAnalytics.instance.logEvent(
name: "trending_contents",
parameters: {
"content_type": EnumToString.convertToString(event.type),
"content_id": contentId,
"action_type": "view",
"value": 1,
},
);
Lastly, I created a scheduled cloud function that runs every 6 hours and populates firebase collection according to custom report results. This report gives contentIds in a specific date range ordered by the sum of values that I sent in a custom event
P.S. you need to create a service account in Google Cloud Console, then generate JSON credentials for it and add the file to your project (see credentialsJsonPath variable below). Then you need to add its email address to google analytics 'Property Access Management' section to access analytics data. To see Google Analytics Data API samples, you can check their GitHub repo
const { BetaAnalyticsDataClient } = require('#google-analytics/data');
exports.scheduledTrendingFunction = functions.pubsub.schedule('0 */6 * * *').onRun((context) => {
const propertyId = process.env.GA_PROPERTY_ID;
const credentialsJsonPath = process.env.GA_CRENDENTIALS_PATH;
const analyticsDataClient = new BetaAnalyticsDataClient({
keyFilename: credentialsJsonPath,
});
async function runReport(filterType) {
// [START analyticsdata_json_credentials_run_report]
const [response] = await analyticsDataClient.runReport({
property: `properties/${propertyId}`,
dateRanges: [
{
startDate: '3daysAgo',
endDate: 'today',
},
],
dimensions: [
{
name: 'contentType',
},
{
name: 'contentId'
}
],
metrics: [
{
name: 'eventValue'
},
],
dimensionFilter: {
andGroup: {
expressions: [
{
filter: {
fieldName: "eventName",
inListFilter: {
values: ["trending_contents"]
}
}
},
{
filter: {
fieldName: "contentType",
inListFilter: {
values: [filterType]
}
}
}
]
}
},
offset: 0,
limit: 20,
orderBys: [
{
desc: true,
metric: {
metricName: "eventValue"
}
}
]
});
// [END analyticsdata_json_credentials_run_report]
const batch = admin.firestore().batch();
// BATCH: delete
const trendRef = admin.firestore().collection('trends').doc(filterType);
batch.delete(trendRef);
const subTrendRef = admin.firestore().collection('trends').doc(filterType).collection('trendContents');
// console.log(response);
response.rows.forEach((row, index) => {
// BATCH: add each contentId to trend
const contentId = row['dimensionValues']['1']['value'];
batch.set(subTrendRef.doc(contentId), {priority: index + 1});
});
// Commit the batch
await batch.commit();
}
runReport("book");
return null;
});

Cypress reutrns 302 instead of 200

I was trying to test sign-in page of our app. I am using cypress to test Vuejs frontend works with AspNet Api. When I click on the signin button on chrome it makes following requests and visits the homepage "localhost:44389"
first request from Chrome
second request from Chrome
if I want to simulate it on cypress it sends same request but get 302 from second request instead of 200.
first request from Cypress
second request from Cypress
Can someone help me to find out the problem?
Cypress.Commands.add('IdentityServerAPILogin', (email, password) => {
console.log("SERVER_URL is called. Server: " + Cypress.env('SERVER_URL'));
cy.request({
method: 'GET',
url: Cypress.env('SERVER_URL'),
failOnStatusCode: false,
headers: {
'Cookie': '...coookies...'
}
})
.then(response => {
if (response.status == 401){
console.log ("Check for NOnce");
console.dir(response, { depth: null });
const requestURL = response.allRequestResponses[1]["Request URL"]
console.dir(requestURL, { depth: null })
//const signInPage = (response.redirects[0]).replace('302: ', '');
const signInPage = (response.redirects[1]).replace('302: ', '');
console.log("signInPage:" + signInPage);
const nOnceObj = response.allRequestResponses[0]["Response Headers"];
console.dir(nOnceObj, { depth: null });
const nOnce = nOnceObj["set-cookie"][0];
console.log("Nonce:" + nOnce);
cy.visit({
method: 'GET',
url: signInPage,
failOnStatusCode: false,
headers: {
//'Cookie': nOnce
}
})
// TODO: Create all needed tests later to test sign in
cy.get('#username').type(email)
cy.get('#password').type(password)
// TODO: Waiting for to click signIn button. When I call the click() method I get infinite loop!!
cy.get('.ping-button')
// .click()
// .then((response_login) => {
// console.log("Status REsponse_Login: "+ response_login);
// console.dir(response_login, { depth: null });
// if (response_login.status == 401){
// cy.visit(Cypress.env('SERVER_URL'))
// }
// })
}else
cy.visit(Cypress.env('SERVER_URL'))
})
console.log("vorbei");
});
Just figured out Cypress is not able to get Cookies from .../signin-oidc, because there is an error as in the photo below
Asking kindly for a solution. I am not allowed to make changes on authorization service. Looking for a possibility around cypress.

Firebase Phone Auth Error 400

Just getting started with Firebase phone auth. Seems pretty slick however I've hit a wall with a bug.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "SESSION_EXPIRED"
}
],
"code": 400,
"message": "SESSION_EXPIRED"
}
}
Starting with the Captcha: (standard documentation code!)
var applicationVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
'size': 'invisible',
'callback': function(response) {
},
'expired-callback': function() {
}
});
Its rendered and the captcha works well.
Next is the sign-in bit where you are sent the auth code to your phone. Works great:
$scope.signInWithPhoneNumber = function signInWithPhoneNumber() {
var phoneNumber = "*censored*";
var appVerifier = window.recaptchaVerifier;
firebase.auth().signInWithPhoneNumber(phoneNumber, applicationVerifier)
.then(function (confirmationResult) {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
window.confirmationResult = confirmationResult;
$scope.setConfirmationResult(confirmationResult);
alert('Result: ' + JSON.stringify(confirmationResult));
}).catch(function (error) {
// Error; SMS not sent
alert('Error: ' + error);
// ...
});
};
Finally its the authentication of the code that the user inputs from the text message. Here is when I get the error 400:
$scope.AuthenticateCode = function (code) {
var code = String(document.getElementById("auth_code").value);
var confirmationResult = $scope.getConfirmationResult();
alert(code);
confirmationResult.confirm(code).then(function (result) {
// User signed in successfully.
var user = result.user;
console.log('Signed In! ' + JSON.stringify(user));
// ...
}).catch(function (error) {
// User couldn't sign in (bad verification code?)
// ...
});
}//end of AuthenticateCode
The error is coming from the VerifyPhone method:
https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPhoneNumber?key=censored
Any help or ideas?
Many Thanks,
Kieran
Ok, there are 2 likely reasons:
The code expired. The user took too long to provide the SMS code and finish sign in.
The code was already successfully used. I think this is the likely reason. You need to get a new verificationId in that case. Get a new reCAPTCHA token via the invisible reCAPTCHA you are using.
You are most likely to forget the "Country Code" before the phone no.
That is why firebase throw error 400 which means invalid parameters
If it's an Ionic3 project, change the following lines:
Imports:
import { AngularFireAuth } from 'angularfire2/auth';
import firebase from 'firebase';
Create var:
public recaptchaVerifier: firebase.auth.RecaptchaVerifier;
on "ionViewDidLoad()"
this.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
on "your_method(phoneNumber: number)"
const appVerifier = this.recaptchaVerifier;
const phoneNumberString = "+" + phoneNumber;
this.fireAuth.auth.signInWithPhoneNumber(phoneNumberString, appVerifier)
.then(confirmationResult => {
// SMS sent. Prompt user to type the code from the message, then sign the
// user in with confirmationResult.confirm(code).
let prompt = this.alertCtrl.create({
title: 'Enter the Confirmation code',
inputs: [{ name: 'confirmationCode', placeholder: 'Confirmation Code' }],
buttons: [
{
text: 'Cancel',
handler: data => { console.log('Cancel clicked'); }
},
{
text: 'Send',
handler: data => {
confirmationResult.confirm(data.confirmationCode)
.then(result => {
// Phone number confirmed
}).catch(error => {
// Invalid
console.log(error);
});
}
}
]
});
prompt.present();
})
.catch(error => {
console.error("SMS not sent", error);
});
Reference:
Firebase Phone Number Authentication
I got into a similar situation when a POST request to google API was returning Bad Request 400. When the message was logged, it said:
All requests from this device are blocked due to Unusual Activity. Please try again later
The issue was when the ReCaptcha was sensing a bot out of my development environment and it worked well when I tried later. During the rest of the development, I turned off this feature for easy work.

Communicate notification data from messaging.setBackgroundMessageHandler to webpage

I am trying to communicate data received by the service worker back to webpage.
On the webpage 'navigator.serviceWorker.controller' is null. The sevice worker has self.client as empty.
Any samples or directions will help
What you can do is get a list of window clients which will return a list of the tabs for your origin and then post a message to each window client. (This code would be in the setBackgroundMessageHandler() ):
const promiseChain = clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
windowClient.postMessage(data);
}
})
.then(() => {
return registration.showNotification('my notification title');
});
return promiseChain;
Then to receive the message in the page, add a listener like so:
navigator.serviceWorker.addEventListener('message', function(event) {
console.log('Received a message from service worker: ', event.data);
});

Resources