This question already has an answer here:
Google calendar api (Calendar usage limits exceeded)
(1 answer)
Closed 2 years ago.
What I am trying to achieve: - I am trying to create an application through which I can create multiple calendar events having 4 attendees each at a particular time. For eg: I should be able to send different meet links to different groups but same meet link to the members of that group for a particular time.
For eg: Group 1 has 4 members (m1,m2,m3,m4)
Group 2 has 4 members (m5,m6,m7,m8)
I should be able to generate two calendar events one for each group having respective members in attendees.
When event is created user should get the notification of the event.
Note: Attendees are external to my domain.
Tech Stack - using googleapis npm package and application is in node.js
Problem - I am creating multiple events but after creating only 4 to 5 events, I start receiving the error "Calendar usage limits exceeded".
Snippet of my code
module.exports = {
scheduleHangoutMeeting: (createLinkObj) => {
return new Promise((resolve, reject) => {
fs.readFile(CREDENTIAL_PATH, async (err, content) => {
if (err) resolve(err);
try {
let auth = await authorize(JSON.parse(content));
let calendarEvent = await createCalendarEvents(auth, createLinkObj);
resolve(calendarEvent);
}
catch (err) {
resolve(err);
}
});
});
}
};
let createCalendarEvents = (auth, meetingObj) => {
return new Promise(async (resolve, reject) => {
let createEvent = {
summary: 'Testing Calendar Api',
description: 'Please ignore this events is for testing purpose',
start: {
dateTime: meetingObj.start_time,
timeZone: 'Asia/Kolkata',
},
end: {
dateTime: meetingObj.end_time,
timeZone: 'Asia/Kolkata',
},
attendees: meetingObj.attendees,
reminders: {
useDefault: false,
overrides: [
{ method: 'email', minutes: 24 * 60 },
{ method: 'popup', minutes: 10 },
],
},
conferenceData: {
createRequest: {
requestId: 'someRandomKey',
},
},
guestsCanSeeOtherGuests: false
};
try {
let calendarEvent = await calendar.events.insert(
{
auth: auth,
calendarId: 'primary',
resource: createEvent,
sendNotifications: true,
conferenceDataVersion: 1
}
);
resolve(calendarEvent.data);
}
catch (err) {
reject(err);
}
});
}
I have gone through various questions on stackoverflow, which talks about the quotas but my number of events are much less and within the quotas. You can refer to the below screenshot for the number of queries. On 19th feb, there were only 6 queries after which we started getting the error and if we count the total number of queries sent to google till date, it would be around 190. Can anyone please let me know what am I doing wrong.
Error Message
code: 403, errors: [
{
domain: 'usageLimits',
reason: 'quotaExceeded',
message: 'Calendar usage limits exceeded.'
} ]
Quota Screenshot
Calendar usage limits exceeded—Results from an API call.
To avoid exceeding Calendar limits, follow these guidelines:
DON'T...
Create too many events
If you create more than 100,000 events in calendar during a short period, you might lose calendar edit ability for a few hours.
It might take several months until this limit type is fully replenished.
Create too many calendars
If you create more than 60 new calendars in a short period, your calendar might go into read-only mode for several hours.
It might take several hours until this limit type is fully replenished.
Send too many invitations to external guests
To prevent spamming, Google Calendar limits the number of invitations a user sends to external guests. If a user sends 10,000 invites in a short period, the user’s calendar might go into read-only mode.
Inviting Google Workspace users in your primary or secondary domain will not consume this limit type. Users in your domain that are not on Google Workspace systems are considered external.
It might take several days until this limit type is fully replenished.
Email too many guests via Google Calendar events
To prevent spamming, Google Calendar limits the number of emails a user can send to external guests with the ‘Email Guests’ feature.
Using the ‘email guests’ feature with Google Workspace users in your primary or secondary domain does not consume this limit type.
This limit replenishes gradually within 24 hours.
Share calendars with too many users
If you share calendars with many users in a short period, you might lose the ability to share calendars for a few hours.
It might take several hours until this limit type is fully replenished.
Reference:
See Google support page reference link to avoid Calendar use limits, and follow the guidelines(the same with what I indicated above) on this page to avoid exceeding limits: https://support.google.com/a/answer/2905486?hl=en
Related
We're running a UK Magento store hooked up to Braintree. All has been running smoothly for months, then suddenly, we are no longer able to complete an order on any of our staging or local test environments which are hooked up to Braintree Sandbox.
At checkout, a request is made to the 3d secure endpoint, and if we have entered a UK based county, we get the following response:
Endpoint:
https://api.sandbox.braintreegateway.com/merchants/xxx/client_api/v1/payment_methods/xxx/three_d_secure/lookup
Request billing part:
"additionalInfo": {
"billingCity": "Leeds",
"billingCountryCode": "GB",
"billingGivenName": "John",
"billingLine1": "50 Upton Road",
"billingPhoneNumber": "07733222111",
"billingPostalCode": "LE6 7TH",
"billingState": "Yorkshire",
"billingSurname": "Smith"
},
Response:
{
"error": {
"message": "Billing state format is invalid."
},
"threeDSecureInfo": {
"liabilityShiftPossible": false,
"liabilityShifted": false
}
}
If we remove the county field from the checkout (and ultimately the 'billingSate from the request), the response is valid and we are able to checkout fine.
This has only started happening recently
The same codebase works fine on production Braintree
I simulated the a request with exact same params on production and it worked OK
Raised ticket with Braintree but no response
I am able to checkout if I use a two digit US state code in the county field
Anyone have any ideas?
I did finally get an answer from Braintree regarding this. Apparently 3ds2 is now enforced on the Sandbox, and this requires the state or county to be sent as a two digit code.
On production, if the full name is sent, it will (currently) gracefully degrade to 3ds1 and complete.
In an attempt to push people to using 3ds2, the Sandbox does not switch to 3ds1 and returns the error.
Today I encountered same problem with 3DSecure in Braintree.
First of all, I made sure that I use the latest version of drop-in, client and data-collector scripts which (at the time of writing this response) are:
<script src="https://js.braintreegateway.com/web/3.71.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.71.0/js/data-collector.min.js"></script>
<script src="https://js.braintreegateway.com/web/dropin/1.25.0/js/dropin.min.js"></script>
Then I modified/renamed two of "threeDSecure" properties "locality"->"city" and "region"->"state"
dropin.requestPaymentMethod({
threeDSecure: {
amount: '10.01',
email: 'me#mydomain.com',
billingAddress: {
givenName: 'John',
surname: 'Smith',
streetAddress: '51 East Street,
extendedAddress: 'na',
city: 'Colchester',
state: 'Essex',
postalCode: 'CO1 2QY',
countryCodeAlpha2: 'GB'
}
}
}, function (err, payload) {
if (err) {
console.log('tokenization error:');
dropin.clearSelectedPaymentMethod();
return;
}
if (!payload.liabilityShifted) {
console.log('Liability did not shift');
return;
}
console.log('verification success');
console.log(payload.nonce);
});
I hope this will help you as it works fine for me in the Sandbox environment.
(Hello all. This is my first post using the guided posting mode, so please bear with me)
I have been using Fullcalendar for a little while now to display events from JSON feeds for multiple calendars (One calendar per JSON feed). These JSON feeds are conversions of .ics feeds by ical.js to work fullcalendar. However, I now have need to break these calendars down into lists and filter them based on certain text in the event names in a manner similar to this:
Full event list.
January 1
lunch
gathering
outing
dinner
January 2
lunch
gathering
outing
dinner
January 3
lunch
closing
filtered event list for webpage (filtered for lunch).
January 1
lunch
January 2
lunch
January 3
lunch
Can I filter based on event title with Fullcalendar when the calendar is based on a feed and not a manual list of events?
I am running fullcalendar 3.9.0 (I may move to 3.10). It is the most current version I can run due to other software needing to be configured to work with version 4.
I am also employing the mozilla ical.js script to convert ical feeds into JSON feeds.
My expectation is that I may actually have two areas in which I could possibly filter:
within ical.js or ical_events.js
within my configuration for fullcalendar (maybe in the defaultView section)
Here is a portion of code I use to call up a calendar:
ics_sources = [
{
url:'https://www.example.com/calendaring/15/',
event_properties: {
color:'#7a9b49'
}
},
]
function data_req (url, callback) {
req = new XMLHttpRequest()
req.addEventListener('load', callback)
req.open('GET', url)
req.send()
}
function add_recur_events() {
if (sources_to_load_cnt < 1) {
$('#calendar').fullCalendar('addEventSource', expand_recur_events)
} else {
setTimeout(add_recur_events, 30)
}
}
function load_ics(ics){
data_req(ics.url, function(){
$('#calendar').fullCalendar('addEventSource', fc_events(this.response, ics.event_properties))
sources_to_load_cnt -= 1
})
}
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: '',
center: '',
right: ''
},
viewDisplay: function(view) {
parent.setIframeHeight(iframeId) ;
},
eventClick: function(event) {
window.open(event.url,);
return false;
},
defaultView: $(window).width() < 765 ? 'listYear':'listYear',
nowIndicator: false,
eventLimit: 4,
fixedWeekCount: false,
listDayFormat: 'MMMM Do',
listDayAltFormat: false,
noEventsMessage: "No Currently Scheduled Events"
})
sources_to_load_cnt = ics_sources.length
for (ics of ics_sources) {
load_ics(ics)
}
add_recur_events()
})
Expected (desired) results would be a list pre-filtered in the calendar call based on the desired event title for the end user.
Actual results: I currently do not have any pre-filtering going on.
How do I fetch the list of MS Teams users in an organization? And store and then broadcast a notification to them.
I see this snippet but it fetches the list of members in a conversation only
bot.dialog('FetchMemberList', function (session) {
var conversationId = session.message.address.conversation.id;
connector.fetchMembers(session.message.address.serviceUrl, conversationId, function (err, result) {
if (err) {
session.endDialog('There is some error');
}
else {
session.endDialog('%s', JSON.stringify(result));
}
});
});
Currently there is no option to fetch user's unique Id without installing the bot. You need the user’s unique ID and tenant ID to send a proactive message.
Bot can only send proactive message to users who has installed your bot. When user installs your app, you could save user details which can be used later to send messages.
You can fetch the list of the users using the Teams roster REST API.
https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/bots/bots-context#fetching-the-team-roster
Your bot can query for the list of team members and their basic profiles, which includes Teams user IDs and Azure Active Directory (Azure AD) information such as name and objectId. You can use this information to correlate user identities; for example, to check whether a user logged into a tab through Azure AD credentials is a member of the team.
You can directly issue a GET request on /conversations/{teamId}/members/, using the value of serviceUrl as the endpoint.
Currently, the only source for teamId is a message from the team context—either a message from a user or the message that your bot receives when it is added to a team (see Bot or user added to a team).
Response would follow the format:
[{
"id": "29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc",
"objectId": "9d3e08f9-a7ae-43aa-a4d3-de3f319a8a9c",
"givenName": "Larry",
"surname": "Brown",
"email": "Larry.Brown#fabrikam.com",
"userPrincipalName": "labrown#fabrikam.com"
},
...
]
If attempting to charge a customer record (which has an associated credit-card) via a connected account, I get an error claiming, "No such customer: cus_xxxx" -- even though making a charge to the same-exact customer will work fine when not using a "connected" account (when charging via the platform account).
For example, consider the following Ruby code, assuming we have a "connected" (Standalone) account with ID acct_ABC123:
# Use the (secret) API key for the "platform" or base account.
Stripe.api_key = 'sk_[...]'
customer = Stripe::Customer.create(email: 'customer#example.com')
# Associate a credit-card with the customer.
token = # Generate a token (e.g., using Stripe Checkout).
customer.sources.create(source: token)
# Attempt to charge the card via the connected account...
Stripe::Charge.create({ amount: 150, currency: 'usd', customer: customer.id,
application_fee: 25 }, stripe_account: 'acct_ABC123')
The last line there leads to a Stripe::InvalidRequestError exception, with the "No such customer" error mentioned above. However, the same charge will go through fine if we just try to run it on the "platform" account (without the stripe_account parameter and no application_fee)...
Stripe::Charge.create({ amount: 150, currency: 'usd', customer: customer.id }
For some (confusing and slightly bizarre) reason, you must add the intermediate step of creating a new token when making charges against "Shared Customers" (customers that will be charged through one or more connected accounts). So, assuming we've already created the customer with an associated credit-card (as per the question), the working code ends up looking something like this...
token = Stripe::Token.create({ customer: customer.id },
{ stripe_account: 'acct_ABC123' })
Stripe::Charge.create({ amount: 150, currency: 'usd', source: token.id,
application_fee: 25 }, stripe_account: 'acct_ABC123')
As an aside, I would consider Stripe's error message ("No such customer") to be a bug and the fact that this extra step (generating a token) is required only for "Stripe Connect" charges a confusing quirk.
So I have set up a google service account for one of my apps. My intention is to keep a google calendar associated with the admin portal that all of the admins can post events to. I have got the JWT auth working I can post events to the calendar and perform other API actions. However, for some reason I cannot change the access control rules on the primary calendar. It is initialized with a single acl rule (role: owner, scope: {type: user, value: service_account_id}), and when I try to add public read access (role: reader, scope: {type: default}) like so:
POST https://www.googleapis.com/calendar/v3/calendars/primary/acl
Authorization: Bearer my_jwt_here
{
"role":"reader",
"scope":{
"type":"default"
}
}
I get the following error:
{
"error": {
"errors": [
{
"domain": "calendar",
"reason": "cannotRemoveLastCalendarOwnerFromAcl",
"message": "Cannot remove the last owner of a calendar from the access control list."
}
],
"code": 403,
"message": "Cannot remove the last owner of a calendar from the access control list."
}
}
This doesn't make any sense to me because this request shouldn't be trying to remove any access control rules. When I create a secondary calendar and do this I have no issues. When I do this with the primary calendar of my personal google account I have no issues. Is this some behavior specific to service accounts that I am not familiar with or what? I could settle for using a non-primary calendar but it bothers me that this isn't working. Any advice is appreciated.
so I found a weird work around for this issue and im posting here because I could not find SQUAT to help resolve this so hopefully this saves others some hassle.
I will also post some common problems I found when creating a organization-wide calendar (whether this is your use case or not I believe these tips will be helpful) - Jump to the bottom of the solution to this particular error.
First I needed to set up authentication with google calendar:
const { google } = require("googleapis");
const calendar = google.calendar("v3");
const scopes = [
"https://www.googleapis.com/auth/admin.directory.resource.calendar",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/admin.directory.user",
];
const path = require("path");
const key = require(path.join(__dirname, "google-cal-api.json"));
I created a service account and then allowed it domain wide delegation with the above listed scopes; then downloaded the key. Now if you want to do actions like create calendar events FOR users within this domain what you have to do is generate a JWT token that 'impersonates' the user whos calendar you wish to interact with; like so
const generateInpersonationKey = (email) => {
var jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
scopes,
email
);
return jwtClient;
};
To set up a JWT client for the service account itself (and so you can create a calendar people can subscribe to; in our case it was a google calendar to show whos on leave within the workplace; so a calendar that has ALL that people can subscribe and toggle on/off was ideal) you just replace the email with 'null' and it defaults to itself, instead of 'impersonating' someone within the domain wide org.
Creating events are simple, follow the google cal api docs, depending on the auth token will depend on where the calendar is generated
JUMP HERE FOR THE IMMEDIATE SOLUTION TO THE ABOVE
For resolving the issue you pointed out; What I did was set my personal accounts email as an owner of this service accounts calendar with the following NodeJS code:
var request = await calendar.acl.insert({
auth,
calendarId: "primary",
resource: {
role: "owner",
scope: {
type: "user",
value: "callum#orgdomain.com",
},
},
});
I set myself as an owner, then I went to Google Calendar API > Patch (Try Me) filled in the calendarId as the service account with the calendar im trying to restrict; and then rule ID would be the gsuite domain domain:orgdomain.com The body should be
{
"role": "reader",
"scope": {
"type": "domain",
"value": "orgdomain.com"
}
}
And thats how I was able to restrict people within our gsuite domain from deleting or editing custom calendar events. This solution is coming from the perspective of someone who originally inserted the domain ACL as
var request = await calendar.acl.insert({
auth,
calendarId: "primary",
resource: {
role: "owner",
scope: { type: "domain", value: "orgdomain.com" },
},
});
Because adding it as a 'reader' like this messes with the service account ownership and wont allow anything but owner
Hope this has been helpful
Callum