adding contact to existing group (people api migration) - google-apps-script

Trying to get all this stuff migrated from the much simpler Contact API before it's switched before it's switched off in a few days. I'm able to add people now, but adding them to the group that is shared company wide isn't working.
// https://stackoverflow.com/questions/64095816/add-a-created-contact-to-a-group-by-people-api-using-google-apps-script
function createContactLead(lead) {
var contactResource = {
"names": [{
"displayNameLastFirst": lead["FirstName"] + " " + lead["LastName"],
"familyName": lead["LastName"],
"givenName" : lead["FirstName"]
}],
"phoneNumbers": [{
'value': lead["Phone"],
'type' : 'mobile',
}],
"emailAddresses": [{
'value': lead["Email"]
}],
"addresses": [{
"city": lead["city"],
"region": lead["state"]
}],
}
var peopleResource = People.People.createContact(contactResource);
var contactResourceName = peopleResource["resourceName"];
groupName = "Leads (Shared)";
var groups = People.ContactGroups.list()["contactGroups"];
var group = groups.find(group => group["name"] === groupName);
console.log(group);
var groupResourceName = group["resourceName"];
console.log("group resource name %s", groupResourceName);
var membersResource = {
"resourceNamesToAdd": [
contactResourceName
]
}
People.ContactGroups.Members.modify(membersResource, groupResourceName);
}
It definitely finds the group but trying to modify it results in " Invalid value at 'resource_names_to_add' (resource_names_to_add), Starting an object on a scalar field"
Execution log
12:34:02 PM Notice Execution started
12:34:03 PM Info { formattedName: 'Leads (Shared)',
groupType: 'USER_CONTACT_GROUP',
metadata: { updateTime: '2021-02-08T17:56:34.066Z' },
name: 'Leads (Shared)',
memberCount: 89,
etag: 'XadlO6et7QY=',
resourceName: 'contactGroups/27ee381f0e7d94e7' }
12:34:03 PM Info group resource name contactGroups/27ee381f0e7d94e7
12:34:03 PM Error
GoogleJsonResponseException: API call to people.contactGroups.members.modify failed with error: Invalid value at 'resource_names_to_add' (resource_names_to_add), Starting an object on a scalar field
createContactLead # test.gs:41
driver # test.gs:68
Thanks in advance!

Apparently I had a bug early on where I wasn't pulling out the "resourceName" from the people object. The code has since been updated in the question. Once that was fixed everything worked. I'll leave this up as it wasn't easy to get right.

Related

How to check if the response includes specified value and if so - end test in Postman

I'm learning Postman test scripts and I am stuck with one exercise. I need to check if the response includes specified value (one of the planet from array is called Tatooine). Body response:
"results": [
{
"name": "Tatooine",
"rotation_period": "23",
"orbital_period": "304",
"diameter": "10465",
{
"name": "Alderaan",
"rotation_period": "24",
"orbital_period": "364",
"diameter": "12500",
},
I created this script:
const jsonData = pm.response.json();
pm.test("Your test name", function () {
for (let i = 0; i <= jsonData.results.length; i++) {
pm.expect(jsonData.results[i].name).to.include("Tatooine")};
});
But I don't know how to get out of the loop and mark test as "passed" after finding searched value.
I assume you want to verify that at least there is a name Tatooine.
Step 1: Get all names
const jsonData = pm.response.json();
let names = _.map(jsonData.results, "name");
Step 2: Validate the array names contains Tatooine
pm.test("Your test name", function () {
pm.expect(names).to.include("Tatooine")
});

Adding a Topic ID to a Google Classroom assignment

I'm trying to create an assignment using Google Apps script and place it under a topic that is also created in the same script. I have no problem creating an assignment when no topicId is specified, but as soon as I try to specify a topicId , I receive the following error when I run the script: API call to classroom.courses.courseWork.create failed with error: Invalid JSON payload received. Unknown name "Test Topic"
Here is my code:
function makeStuff() {
var topic = {
name: "Test Topic"
};
Classroom.Courses.Topics.create(topic, "46088716060");
var TWS1 = {
title: "Test Worksheet 1",
state: "DRAFT",
materials: [
{
driveFile:{
driveFile: {
id: "1REOs1RYtyVTX67VnJezjWf-wm7HqDVexeaeiQL3-HvM",
},
shareMode: "STUDENT_COPY"
}
}
],
workType: "ASSIGNMENT",
topicId: {
name: "Test Topic"
}
};
Classroom.Courses.CourseWork.create(TWS1, "46088716060")
}
Is it possible to reference the topicId by name, or assign the topicId number that is created in the script to a variable that can be referenced?
To create a topic, you only need to supply a name (the topic name is not its id, only the API can generate ids). The Classroom API then creates the topic, which it returns as an object with the topicId property defined on it, as seen below;
var courseId = "46088716060";
var topicName = "Test Topic";
var topic = Classroom.Courses.Topics.create({name:topicName}, courseId);
var topicId = topic.topicId;
You then use that topicId when creating coursework.

Winston log format

i am using Winston ^3.0.0-rc6 as below :
var options = {
file: {
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
prettyPrint: true,
maxsize: 5242880, // 5MB
maxFiles: 5,
colorize: true,
}
};
const jsonFormatter = (logEntry) => {
if (logEntry.type) {
const base = {
timestamp: new Date()
};
const json = Object.assign(base, logEntry);
logEntry[MESSAGE] = JSON.stringify(json);
} else {
logEntry = "";
}
return logEntry;
}
const logger = winston.createLogger({
format: winston.format(jsonFormatter)(),
transports: [
new winston.transports.File(options.file)
],
exceptionHandlers: [
new winston.transports.File(options.uncaughtExceptions)
]
});
my log output :
{"timestamp":"2018-06-10T07:41:03.387Z","type":"Authentication","status":"failed","level":"error","message":"Incorrect password"}
but i want them to be like :
{
"timestamp": "2018-06-10T07:41:03.387Z",
"type": "Authentication",
"status": "failed",
"level": "error",
"message": "Incorrect password"
}
i tried to play around with json : true , and prettyPrint but it did not do the trick .
Can any one help please
Thanks.
I noticed in your code that on the line
logEntry[MESSAGE] = JSON.stringify(json);
you're using JSON.stringify() which takes two more optional arguments
JSON.stringify(value[, replacer[, space]])
If you set space to the amount of spaces you'd like you'll get the output you're looking for. So change the initial line to be:
logEntry[MESSAGE] = JSON.stringify(json, null, 2); // or 4 ;)
(The replacer argument is null because we don't want to change the default behavior.)
This is deprecated: You can check the link here.
I tried to play around with json: true, and prettyPrint but it did not do the trick.
Simple code like this work for you:
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
// - Write all logs error (and below) to `error.log`.
//
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
If this does not work, let me know so that I can improvise.

DocumentDB: bulkImport Stored Proc - Getting 400 Error on Array/JSON issue

I'm simply trying to execute the standard example bulkImport sproc for documentDB API and I can't seem to pass it an array of objects. I always get 400 errors despite the documentation giving clear direction to send an array of objects
.. very frustrating.
Additional details: Even if I wrap the array in an object with the array under a property of 'items' and include it in my sproc it still errors out saying the same bad request, needs to be an object or JSON-serialized. When I try to do JSON.stringify(docs) before sending it fails to parse on the other side.
Bad Request: The document body must be an object or a string representing a JSON-serialized object.
bulkInsert.js:
https://github.com/Azure/azure-documentdb-js-server/blob/master/samples/stored-procedures/BulkImport.js
My Code (using documentdb-util for async):
execProc(docs, insertProc);
async function execProc(docs, insertProc){
let database = await dbUtil.database('test');
let collection = await dbUtil.collection(database, 'test');
let procInstance = await dbUtil.storedProcedure(collection, insertProc);
try{
let result = await dbUtil.executeStoredProcedure(procInstance, docs);
console.log(result);
} catch(e){
console.log(e.body)
}
}
Header
Object {Cache-Control: "no-cache", x-ms-version: "2017-11-15",
User-Agent: "win32/10.0.16299 Nodejs/v8.9.0 documentdb-nodejs-s…",
x-ms-date: "Mon, 11 Dec 2017 07:32:29 GMT",
Accept:"application/json"
authorization: myauth
Cache-Control:"no-cache"
Content-Type:"application/json"
User-Agent:"win32/10.0.16299 Nodejs/v8.9.0 documentdb-nodejs-sdk/1.14.1"
x-ms-date:"Mon, 11 Dec 2017 07:32:29 GMT"
x-ms-version:"2017-11-15"
Path
"/dbs/myDB/colls/myColl/sprocs/myBulkInsert"
Params
Array(3) [Object, Object, Object]
length:3
0:Object {id: "0001", type: "donut", name: "Cake", …}
1:Object {id: "0002", type: "donut", name: "Raised", …}
2:Object {id: "0003", type: "donut", name: "Old Fashioned", …}
[{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55
},
{
"id": "0002",
"type": "donut",
"name": "Raised",
"ppu": 0.35
},
{
"id": "0003",
"type": "donut",
"name": "Old Fashioned",
"ppu": 0.25
}]
The "docs" must be an array of array of params, otherwise, the procedure executor will treat them as multiple params of the procedure, not a single-array-param.
the following code works when call storedProcedure to pass argument with array type.
JS:
var docs = [{'id':1},{'id':2}];
executeStoredProcedure(proc, [docs])
C#
var docs = new[] {new MyDoc{id=1, source="abc"}, new MyDoc{id=2, source="abc"}];
dynamic[] args = new dynamic[] {docs};
ExecuteStoredProcedureAsync<int>(
procLink,
new RequestOptions {PartitionKey = new PartitionKey("abc")},
args);
NOTE: you must ensure the 'docs' have the same partition key, and pass partion key in RequestionOptions
I had the same problem. I was able to get it to work by Stringify the Array and parse it in the stored procedure. I opened an issue on the github where that code originated as well. Below is what worked for me. Good luck.
---- Stringify Array
var testArr = []
for (var i = 0; i < 50; i++) {
testArr.push({
"id": "test" + i
})
}
var testArrStr = JSON.stringify(testArr)
//pass testArrStr to stored procedure and parse in stored procedure
---- Slightly altered original BulkImport
exports.storedProcedure = {
id: "bulkImportArray",
serverScript:function bulkImportArray(docs) {
var context = getContext();
var collection = context.getCollection();
var docsToCreate = JSON.parse(docs)
var count = 0;
var docsLength = docsToCreate.length;
if (docsLength == 0) {
getContext().getResponse().setBody(0);
}
var totals = ""
function insertDoc(){
var msg = " count=" + count+" docsLength=" +docsLength + " typeof docsToCreate[]=" + typeof docsToCreate+ " length =" + docsToCreate.length
if(typeof docsToCreate[count] != 'undefined' ) {
collection.createDocument(collection.getSelfLink(),
docsToCreate[count],
function (err, documentCreated) {
if (err){
// throw new Error('Error' + err.message);
getContext().getResponse().setBody(count + " : " + err);
}else{
if (count < docsLength -1) {
count++;
insertDoc();
getContext().getResponse().setBody(msg);
} else {
getContext().getResponse().setBody(msg);
}
}
});
}else{
getContext().getResponse().setBody(msg);
}
}
insertDoc()
}
}
If you want to test it in the portal Script Explorer I had to create an escaped string i.e.
var testArr = []
for(var i=200; i<250; i++){
testArr.push({"id":"test"+i})
}
var testArrStr = JSON.stringify(testArr)
console.log('"'+testArrStr.replace(/\"/g,'\\"') + '"')

best way to parse nested object in AngularJS?

I'm trying to use angularjs for parsing a nested data structure returned from a remote server. I'm really stumped by this pattern because i'm trying to access the "events" data with the following function
$scope.generate_event = function(){
from_date = $scope.dts.from
to_date = $scope.dts.to
from = from_date.getFullYear()+'/'+(from_date.getMonth()+1)+'/'+from_date.getDate()
to = to_date.getFullYear()+'/'+(to_date.getMonth()+1)+'/'+to_date.getDate()
$http.get(server+'rawdata?vids='+$scope.selected_vehicle.id+'&evfields=lat,lon,f_event_time,speed&from='+from+'&to='+to)
.success(function(data){
$scope.report_data = data
$localStorage.report_data = data
$scope.generate()
})
}
Any advice or even a hint on the best approach would be great, i need this running for work and its been a month now. Thanks!
{
"rawData": {
"keys": {
"lat": ["number", "lat"],
"lon": ["number", "lon"],
"speed": ["number", "Speed [mph]"],
"code": ["number", "EVC"],
"vid": ["number", "Vehicle ID"]
},
"keys_order": ["lat", "lon", "speed", "code", "vid"],
"events": [{
"f_lon": -8.3315599999999996,
"code": 4,
"vid": 5,
"lon": -833156,
"f_lat": 51.90831,
"lat": 5190831,
"speed": 78.0
}, {
"f_lon": -8.3741599999999998,
"code": 4,
"vid": 5,
"lon": -837416,
"f_lat": 51.903979999999997,
"lat": 5190398,
"speed": 78.0
}]
}
}
UPDATE: I didnt explain the problem correctly. Here's the generate function
$scope.generate = function(){
$scope.event_config = {
title: 'Events', // chart title, legend etc
/*etc
*etc
*/
data = {}
data.series = [' Events']
data.data = []
this fucker ----->$scope.report_data.events.forEach(function(value, index, array){
o = {}
o.x = value.f_event_time
o.y = [value.lat+'/'+value.lon]
o.tooltip = value.speed
data.data.push(o)
})
$scope.event_data = data
I'm getting error 'forEach undefined'. This is supposed to generate a d3 chart but 'report_data' is intially used to store distance data from a different function for local storage. So do i need a second variable for localStorage? ie $scope.report_event = $localStorage.report_event? Can someone look at the source code if i send it?
$http.get(server+'rawdata?vids='+$scope.selected_vehicle.id+'&evfields=lat,lon,f_event_time,speed&from='+from+'&to='+to)
.success(function(data){
if (data) {
var events = data.rawData.events; // get the events json array
$scope.generate(events);
}
})
and in your controller have the declarative function like
$scope.generate = function(events) {
// your code
}
Solved it with the following
$scope.generate_report = function(){
from_date = $scope.dts.from
to_date = $scope.dts.to
from = from_date.getFullYear()+'/'+(from_date.getMonth()+1)+'/'+from_date.getDate()
to = to_date.getFullYear()+'/'+(to_date.getMonth()+1)+'/'+to_date.getDate()
$http.get(server+'vehicle/'+$scope.selected_vehicle.id+'/counters/deltas/day?from='+from+'&to='+to)
.success(function(data){
$scope.report_data = data
$localStorage.report_data = data
$scope.process()
})
$http.get(server+'rawdata?vids='+$scope.selected_vehicle.id+'&genevcodes=39,40&evfields=lat,lon,f_event_time,mph,speed,code&from='+from+'&to='+to)
.success(function(data){
if(data){
var events = data.rawData.events
}
$scope.report_event = events
$localStorage.report_event = events
$scope.generate()
})
}
just had to declare another localstorage variable for storing events from the JSON object Thanks Yannik