GoogleJsonResponseException: API call to classroom.courses.courseWork.create failed with error: Internal error encountered - google-classroom

I can't understand why this piece of code suddenly returns internal error.
It was working like a charm, after a while it started to throw the error in header and there is nothing to do.
var courseWork = {
'title': 'Reglamento',
'description': 'Por favor, leer los documentos adjuntos.',
'materials': [
{'link': { 'url': linkDocumento }},
{'link': { 'url': "https://drive.google.com/file/d/1eESDk5HA3vR2IEbV0UglaR0F6UysuEmd/view?usp=sharing" }}
],
'workType': 'ASSIGNMENT',
// 'state': 'DRAFT',
'state': 'PUBLISHED',
'topicId': idTema
};
Classroom.Courses.CourseWork.create(courseWork, passa.idClasse);

Answer from the comments on the question:
Actually the problem was the document I was sharing. As I mentioned before, each month I generate 120 classrooms and in each one I put a document "Course Rules". This document is shared from my Drive account (Sharing rules is "Everyone that has the link can see"). Doing this the system charges to the document the link of each classroom that shares it and, I suppose, there is a limit in the number of links that a document can receive.
With a new copy of the document no more error. The workaround will be to copy the document in the classroom drive folder and share it from there.

Related

Sudden Failure Requests on Braintree Sandbox API: 'Billing state format is invalid'

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.

How do I mention a Bot (not a user) using CardFactory.adaptiveCard (NodeJS) in a post to a channel

I've scoured all four corners of interweb trying to find documentation on how to do this. But my journey has been unsuccessful so far. Part way through the search, I was able to find out how to mention a User (not a bot), and that was even a pain to find. I found that you have to post a field named msteams at the top level of the "any" object parameter which is an object consisting of an entities array. That array is an array of objects. The following use of adaptiveCard works when mentioning a user with the proper values replacing username and userID:
CardFactory.adaptiveCard({
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
type: 'AdaptiveCard',
msteams: {
entites: [
{
type: 'mention',
text: '<at>(username)</at>',
mentioned: {
id: <userID>,
name: <username>,
role: 'user'
}
}
]
}
body: [
{
type: 'TextBlock',
text: '<at>(userName)</at>',
}
]
});
The documentation of CardFactory.adaptiveCard just lists the parameter as an any Object and gives a small example not displaying an exhaustive list of fields of this parameter. It also posts a link to the Adaptive Card documentation, but that's what it's abstracting and the fields are not 1:1 (point and case this msteams object that is never referenced in the Adaptive Card documentation from what I can tell). I want to mention the bot itself that is posting this Adaptive Card. I've attempted to replace the mentioned object with the following
{
"id": "a3216960-131c-11eb-xxxx-xxxxxxxxx",
"name": "Bot",
"role": "bot"
}
This is equivalent to the object that I'm using to mention the "from" user in the adaptive card. But this is the recipient. The from user which is successfully mentioned is formatted like the following:
{
"id": "c3370a7c-95f2-4a60-xxxx-xxxxxxxxx",
"name": "User",
"role": "user"
}
Any help/guidance, tips, references would be greatly appreciated!
Currently #mention a bot in Adaptive card is not supported. You can #mention user in Adaptive card.

Mailchimp API Node - create campaign for list based on tags

I'm making an async api request with a firebase cloud function to create a campaign within mailchimp for a specific set of users from a list. I read in the documentation that this can be done with tags this way I can build my own structure. I'm building a donation system for a nonprofit and would like the tag to represent the name of a client who is currently being donated to.
Below is my firebase function. I'm stuck at the segment_opts object. I want to define a segment based on whether the list member has a tag equivalent my clients name.
The doc says segment_opts is "An object representing all segmentation options. This object should contain a saved_segment_id to use an existing segment, or you can create a new segment by including both match and conditions options.". I don't have any other segments set up so I figured I'd create a new one that specifies the tags to contain the client's name.
This post helped me get to this point. Stackoverflow post
I now see that condition is supposed to be a Segment Type but in the dropdown I don't see an option for Tags. Here is a link to the documentation reference. Reference
const response = await mailchimp.post('/campaigns', {
type: 'regular',
recipients: {
list_id: functions.config().mailchimp.test,
segment_opts: {
"match": "any",
"conditions": match: 'any',
conditions: [
{
condition_type: 'StaticSegment',
field: 'static_segment',
op: 'static_is',
value: ??? (Int),
},
],
}
},
});
For now I removed segment_opts and will settle on sending campaign to entire list until I figure out how to segment by tags. This version works and creates a campaign within my mailchimp account and from the UI I can see the segment options offered in the documentation but don't see an option to filter by tags
const response = await mailchimp.post('/campaigns', {
type: 'regular',
recipients: {
list_id: functions.config().mailchimp.test,
},
settings: {
subject_line: `${firstName} has been funded!`,
preview_text: `$${goal} has been raised for ${firstName}.`,
title: `${firstName} has been funded`,
from_name: 'Organization name',
reply_to: 'org_email#gmail.com',
},
});
Here is a screenshot of the dropdown options in Mailchimp dashboard.
This is what I have for my campaign segment options. Here I'm checking for two conditions. Is the SITE merge tag = the site variable I pass in, and also does the member belong to the tag/segment called tagName. However, I can't pass a tagName, only a tagId which I lookup beforehand.
'segment_opts':
{
'match': 'all',
'conditions': [
{
'condition_type': 'TextMerge',
'field': 'SITE',
'op': 'is',
'value': site
},
{
'condition_type': 'StaticSegment',
'field': 'static_segment',
'op': 'static_is',
'value': tagId
}
]
}
To get the tagId I use this Python function:
tagId, segments = self.getSegmentIdFromTagName(tagName)
This is the Python code to get the tagId from the tagName, which gets all the Segments/Tags from the system and then looks for the name you pass in:
def getSegmentIdFromTagName(self,reqTagName,segments=None):
audienceId = self.audienceId
reqId = None
if not segments:
segments = self.mcClient.lists.segments.all(list_id=audienceId,get_all=True)
for segment in segments['segments']:
segName = segment['name']
segId = segment['id']
if segName == reqTagName:
reqId = segId
break
return reqId,segments

Mailchimp Batch the resource submitted could not be validated array Schema describes object, NULL found instead

Posting a batch operation to Mailchimp I keep getting "schema describes object, NULL found instead" error. I get the error in them mailchimp playground https://us10.api.mailchimp.com/playground/. This was working fine for a year up to a few weeks ago and then stopped.
Response Body:
{"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the 'errors' array.","instance":"70a5c431-1cc4-4933-a5c9-2ab84ed06263","errors":[{"field":"","message":"Schema describes object, NULL found instead"}]}
I've tried removing whitespace ,merged fields, and checking to be sure the merge fields natch the mailchimp list and verified the listID matching the correct list.
Any other suggestions would help?
Thanks
{"operations": [{
"method": "POST",
"path": "lists/436db7f77acd/members",
"body": "{\"email_address\":\"yahoo#yahoo.com\", \"status\":\"subscribed\"
,\"tags\":[\"Green Standard\", \"Customer Care\",\"96959N\"]
,\"merge_fields\": {
\"BADGE\": \"\",
\"CPATH\": \"https://secu/Certificate/96959N_0978317_Certificate.pdf\",
\"FNAME\": \"Charles\",
\"FRAME\": \"Coupon Code: 1CZ3d17 Expires: 12/31/2019\",
\"FRAMEHEAD\": \"Certificate\",
\"LNAME\": \"Gren\",
\"MKAL\": \"17MA19\",
\"MKAMT\": \"$250\",
\"MMERGE3\": \"Global Production\",
\"MMERGE4\": \"96959N\"
\"MMERGE5\": \"13d215\",
\"MMERGE6\": \"ABC, Inc.\"
}
}"
}]}
After removing all unnecessary spaces, tabs and whitespace, it's working now.
https://jsonlint.com was helpful

Can't write acl rules to primary calendar in google service account

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

Resources