Trying to insert rows with smartsheet-api and php - smartsheet-api

I am able to update a row easily, but for the life of me can't get a new row inserted.
Here's my data:
{
"toTop":true,
"cells": [
{
"columnId": 5830169266022276,
"value": true
},
{
"columnId": 5830169266022276,
"value": "New status",
"strict": false
}
]
},
{
"toTop":true,
"cells": [
{
"columnId": 5830169266022276,
"value": true
},
{
"columnId": 5830169266022276,
"value": "New status",
"strict": false
}
]
}
The error I get is:
Required object attribute(s) are missing from your request: id.
Help, please!

Based on that error message, I'd suspect that perhaps you're trying to use the verb PUT on your "Add Row" request. (If you're sending PUT, then Smartsheet thinks you want to update a row and therefore requires that you specify the id of the row.) The command to Add a Row should use the verb POST:
POST /sheets/(sheetId}/rows
Also, I notice that you're specifying the same cell (i.e., columnId) twice for each row. This might be problematic as well. Each row object should contain cell objects corresponding to columns that you want to update in that row -- and columnId value should not be repeated/duplicated within a given row.

Related

data factory - check if result of pipeline task contains a specific string or value?

I have a web task in a pipeline.
The result of the api call can be one of 3:
An item exists in a database.
an item does not exist in a database.
the body sent to the call was invalid.
If the record exists, I want to take further action.
As the resulting JSON from the API call is entirely different when an entity exists vs does not exists, how can I check for if a specific value is returned, if there is a chance it wont be returned at all?
Below is the output from a successful call. I'd like to check for the "Tag" attribute, but also cover a case where this does not exist.
How is this done using a dynamic content expression, seeing as there is no exists function?
{
"Data": [
{
"Data": {
"RowNumber": 0,
"Tag": "GLT-GM-45",
"GMStatus": 0,
"CustomValues": [
{
"CSLabel": "Asset Status",
"CSType": 0,
"CSValue": "Assigned"
},
{
"CSLabel": "Usage Status",
"CSType": 0,
"CSValue": "Permanent"
}
],
"AttachmentsToAdd": [],
"AttachmentsToDelete": []
},
"Messages": [
{
"ResultCode": 0,
"Message": "Success",
"HttpStatusCode": 200,
"FieldName": "GLT-GM-45"
}
],
"HasError": false,
"HasHttpError": false,
"HasMessage": true,
"HasSuccessWithMoreDataRemaining": false
}
],
"Messages": [
{
"ResultCode": 0,
"Message": "Success.",
"HttpStatusCode": 200,
"FieldName": ""
}
],
"TotalRecordsLongCount": 1,
"HasSuccessWithMoreDataRemaining": false,
"HasError": false,
"HasMessage": true,
"HasHttpError": false,
"ADFWebActivityResponseHeaders": {
"Connection": "keep-alive",
"Pragma": "no-cache",
"WaspResult": "WaspResult",
"X-UA-Compatible": "IE=edge;IE=edge",
"Cache-Control": "no-store, no-cache",
"Date": "Tue, 02 Aug 2022 11:58:31 GMT",
"Server": "Microsoft-IIS/10.0;Microsoft-IIS/8.5",
"X-AspNet-Version": "4.0.30319",
"X-Powered-By": "ASP.NET;ASP.NET",
"Content-Length": "2364",
"Content-Type": "application/json",
"Expires": "-1"
},
"effectiveIntegrationRuntime": "AutoResolveIntegrationRuntime (North Europe)",
"executionDuration": 0,
"durationInQueue": {
"integrationRuntimeQueue": 1
},
"billingReference": {
"activityType": "ExternalActivity",
"billableDuration": [
{
"meterType": "AzureIR",
"duration": 0.016666666666666666,
"unit": "Hours"
}
]
}
}
Wouldn't you be able to use an IF Condition that uses a contains function? Obviously I do not have a way to recreate your output, but I did the following to simulate something.
Added an If Condition to a pipeline
Added dynamic content that uses a contains function. The first part was a string containing part of your output from above (copy/paste). The part behind the comma (i.e. the search string) being 'Tag'
Added False activity causing the component to fail
Added a True activity to set a variable to be equal to "Found"!.
The full If Condition:
#contains('{
"Data": [
{
"Data": {
"RowNumber": 0,
"Tag": "GLT-GM-45",
"GMStatus": 0
}
}', 'Tag')
Seeing the 'Tag' should be found in the string, it produces the result of setting the variable:
Changing the search word to NotATag which does not exist in the string produces this instead:
My guess would be that you can substitute the hard-coded string with something like the following:
#contains(activity('Web1').output, 'Tag')
Obviously, change 'Web1' to the name of your web component.
Might not be an ideal way but you can do something like below to check the existence of Tag attribute in output (the reason i am trying to check the string size is the pipeline exp expected the return type to be boolean, hence using condition to achieve it), you can map the other actions based on If activity status. If the property doesn't exist if condition fails with error.
Condition
Mapping

Smartsheet - add row with multiple values in cell using c# sdk

One of columns has 'Contact List' type with checked 'Allow multiple contacts per cell' see example.
I tried to add row using smartsheet-csharp-sdk(v2.3). Cell object:
new Cell
{
ColumnId = 111111,
Value = "Test#test.com",
Strict = false
}
and I got the next error:
{
"errorCode": 1235,
"message": "Value is not supported for this column type. Use objectValue instead.",
"refId": "163zew9slvgfq",
"detail": {
"index": 0
}
Then I tried to find how to pass ObjectValue and found only how pass 'Predecessor List', but nothing about multi 'Contact List'.
Question: How to add multi contact list cell using C# SDK ?
Welcome to Stack Overflow, o.jev!
Unfortunately, the C# SDK does not currently support the multi-contact columns. If you wanted to update the value of a multi-contact cell, you'd have to make a native HTTP call (not using the SDK). This would require making a PUT request to the row you want to update, and then your HTTP request body would look like this:
{
"cells": [
{
"columnId": 6654716978456452,
"objectValue": {
"objectType": "MULTI_CONTACT",
"values": [
{
"objectType": "CONTACT",
"email": "user1.email#smartsheet.com"
},
{
"objectType": "CONTACT",
"email": "user2.mail#smartsheet.com"
}
]
}
}
]
}

Validate referential integrity of object arrays with Joi

I'm trying to validate that the data I am returned it sensible. Validating data types is done. Now I want to validate that I've received all of the data needed to perform a task.
Here's a representative example:
{
"things": [
{
"id": "00fb60c7-520e-4228-96c7-13a1f7a82749",
"name": "Thing 1",
"url": "https://lolagons.com"
},
{
"id": "709b85a3-98be-4c02-85a5-e3f007ce4bbf",
"name": "Thing 2",
"url": "https://lolfacts.com"
}
],
"layouts": {
"sections": [
{
"id": "34f10988-bb3d-4c38-86ce-ed819cb6daee",
"name": "Section 1",
"content:" [
{
"type": 2,
"id": "00fb60c7-520e-4228-96c7-13a1f7a82749" //Ref to Thing 1
}
]
}
]
}
}
So every Section references 0+ Things, and I want to validate that every id value returned in the Content of Sections also exists as an id in Things.
The docs for Object.assert(..) implies that I need a concrete reference. Even if I do the validation within the Object.keys or Array.items, I can't resolve the reference at the other end.
Not that it matters, but my context is that I'm validating HTTP responses within IcedFrisby, a Frisby.js fork.
This wasn't really solveable in the way I asked (i.e. with Joi).
I solved this for my context by writing a plugin for icedfrisby (published on npm here) which uses jsonpath to fetch each id in Content and each id in Things. The plugin will then assert that all of the first set exist within the second.

Getting specific headers along with other body data in Users.thread: get

You can very easily select what headers you want in a Users.thread: get-request, like so:
format = metadata
metadataHeaders = From
GET https://www.googleapis.com/gmail/v1/users/me/threads/14eaffaf5e3e8242?metadataHeaders=From&format=metadata&key={YOUR_API_KEY}
Response:
{
"id": "14eaffaf5e3e8242",
"historyId": "510358",
"messages": [
{
"id": "14eaffaf5e3e8242",
"threadId": "14eaffaf5e3e8242",
"labelIds": [
"SENT",
"INBOX",
"IMPORTANT"
],
"snippet": "Wow Emil!",
"historyId": "510292",
"internalDate": "1437471536000",
"payload": {
"mimeType": "multipart/mixed",
"headers": [
{
"name": "From", // I just got the header I asked for.
"value": "Emil Tholin <emtholin#gmail.com>"
}
]
},
"sizeEstimate": 9260
}, ...
}
You can also get certain parts of the body very easily. E.g. here I ask for the attachmentIds of all the attachments in the message body:
field = messages/id,messages/payload/parts/body/attachmentId
GET https://www.googleapis.com/gmail/v1/users/me/threads/14eaffaf5e3e8242?fields=messages%2Fid%2Cmessages%2Fpayload%2Fparts%2Fbody%2FattachmentId&key={YOUR_API_KEY}
Response:
{
"messages": [
{
"id": "14eaffaf5e3e8242",
"payload": {
"parts": [
{
"body": { // This message had an attachment.
"attachmentId": "ANGjdJ_0lphTo48BO0xBT_YOSo3tYah23hzpjyATe3GwfziK0I6401P_8-ZYoGuCQPHhpPP0-S_pjL68WIEZzQ0tu72RcIOE4UY3kA4u8PjXPf3Cm5PxVJjmH9N0hm0fFX31RYo8bfZQ6l7bDbYbnCSZbckG7g8enGaKMPbBzIEEC4HXr_YghOYWSfrXKXiFLnxWN4LfsFk3IXUN2tVvMe_0xMhDDfBlqYPnXHr2PhPghq7bQojNxiH4YziIqaKmwiU4xqVfygbae-K-_Q2blyz0EgI4OXjMzwz56Q5e1w"
}
}
]
}
},
{
"id": "14eaffb277b61cd0" // This message had no attachment.
}, ...
]
}
As you can see in the first request, no part of the body is retrieved when asking for specific metadata headers. Individual fields are also hard to pick out in the fields-parameter, since headers are not key-value pairs, but objects on the form { "name": <HEADER_NAME>, "value": <HEADER_VALUE> }.
Is there any way to combine these two requests? I would like to get all the relevant metadata about a message at the same time as getting how many attachments there are in the message.
From Users.threads.get.
"metadata": Returns email headers with message metadata such as identifiers and labels.
The fields parameter is only used to limit the amount of data returned. Since metadata mode is already a limited response you can't use fields to get data outside of that subset. Your best option would be to use your second example with fields and then filter the metadata values locally.

Office365/Sharepoint:: API Error when getting ParentUniqueId for a list item

I'm trying to identify the Parent Id for a list item.
I'm making the following call;
https://{sitecollection}/{personal_site}/_api/Web/Lists(guid'blabla')/Items(blabla)?$select=ParentUniqueId
But it is giving me the following error;
{
"error": {
"code": "-1, Microsoft.SharePoint.SPException",
"message": {
"lang": "en-US",
"value": "The field or property 'ParentUniqueId' does not exist."
}
}
}
The same issue is with "ParentLeafName" and some others.
However, when I get the /fields (meta of fields for a list) for this list, it mentions this field along with others, which means I'm doing the right call as I'm successfully getting other fields like
https://{sitecollection}/{personal_site}/_api/Web/Lists(guid'blabla')/Items(blabla)?$select=ServerUrl
Result
{
"d": {
"__metadata": {
"id": "blabla",
"uri": "blabla",
"etag": "\"10\"",
"type": "SP.Data.DocumentsItem"
},
"ServerUrl": "/personal/{site}/{filepath}"
}
}
One thing I have noticed though, that these fields are case sensitive, that is, if i write "serverurl" it gives me the same error. Is this a case issue with "ParentUniqueId" field?
Unfortunately ListItem resource in SharePoint 2013 REST interface does not expose ParentUniqueId property.
But you could use the following query to return ParentUniqueId property for ListItem:
/_api/Web/Lists/getByTitle('<list title>')/items(<item id>)/FieldValuesAsText?$select=ParentUniqueId
References
Lists and list items REST API reference