How to get google sheet multiple tabs data as JSON? - google-sheets

Can you some help to get google sheets multiple tabs data as single JSON ?

Answer:
You can use the Sheets API to get the data of each sheet pre-compiled as a JSON.
More Information:
The spreadsheets.get endpoint of the Google Sheets API allows you to get the data from a Spreadsheet by specifying the Spreadsheet ID. The URL for the endpoint is:
https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET-ID
You can use a field mask to narrow down the data in the response you get from the API. In order to only get the Sheet name and the data, you can use:
sheets(properties/title,data/rowData/values/userEnteredValue)
to test using the Try this API, or if using the URL directly:
https://sheets.googleapis.com/v4/spreadsheets/yourSpreadsheetId?fields=sheets(properties/title,data/rowData/values/userEnteredValue)
Example Response:
{
"sheets": [
{
"properties": {
"title": "Sheet1"
},
"data": [
{
"rowData": [
{
"values": [
{
"userEnteredValue": {
"numberValue": 1
}
},
{
"userEnteredValue": {
"numberValue": 12
}
}
]
},
{
"values": [
{},
{},
{
"userEnteredValue": {
"numberValue": 123
}
}
]
}
]
}
]
}
]
}
References:
Method: spreadsheets.get | Sheets API | Google Developers
Working with field masks | Slides API | Google Developers
Package google.protobuf | Protocol Buffers | Google Developers
google.protobuf.FieldMask

Related

How To Convert "created_timestamp" Value To A Valid Date In Python

I'm currently working on a Twitter bot that automatically reply messages, I'm doing this by using tweepy (the official python twitter library)
I need to filter messages based on the created time as I don't want to reply same message twice. Now the problem is that the API endpoint returns created_timestamp as string representation of positive integers.
Below is an example of data returned as per the doc
{
"next_cursor": "AB345dkfC",
"events": [
{ "id": "110", "created_timestamp": "1639919665615", ... },
{ "id": "109", "created_timestamp": "1639865141987", ... },
{ "id": "108", "created_timestamp": "1639827437833", ... },
{ "id": "107", "created_timestamp": "1639825389806", ... },
{ "id": "106", "created_timestamp": "1639825389796", ... },
{ "id": "105", "created_timestamp": "1639825389768", ... },
...
]
}
My question is "How do I convert the created_timestamp to a valid date using python" ?.
You might play with timestamps on this resource
And in your case could use methods like:
timestamp = int('timestamp_string')
datetime.fromtimestamp(timestamp, tz=None)
date.fromtimestamp(timestamp)
From the datetime standard library. But integers after the first line are already well comparable if the task is to distinguish differences between the timestamps.

Google Slides API reports Invalid requests[0].updateTableCellProperties: Invalid field: table_cell_properties

Trying to troubleshoot an error message my app gets after sending a batchUpdate request to Google Slides API
Invalid requests[19].updateTableCellProperties: Invalid field: table_cell_properties
The 19th request in the batch is the only updateTableCellProperties request I have. If I removing the 19th request from the batch, everything works fine.
Other requests which I run in this batchUpdate with no issues are are insertTableRows, deleteTableRow, insertText, updateParagraphStyle, updateTextStyle, updateTableColumnProperties. They all work on the same table, so I use the same objectId, but depending on the request I have to specify it as tableObjectId instead of objectId.
Unsure if I am generating a wrong request for the only updateTableCellProperties request I have, or if there is a problem in the Google Slides ruby gem itself, I tried sending just this updateTableCellProperties request from the Google Slides API explorer which has some validation on the request structure. So I sent this updateTableCellProperties batchUpdate request
{
"requests": [
{
"updateTableCellProperties": {
"objectId": "gf9d8fea71f_22_1",
"tableRange": {
"location": {
"columnIndex": 0,
"rowIndex": 1
}
},
"fields": "tableCellProperties",
"tableCellProperties": {
"tableCellBackgroundFill": {
"solidFill": {
"color": {
"themeColor": "LIGHT1"
}
}
}
}
}
}
]
}
And I got this error:
{
"error": {
"code": 400,
"message": "Invalid requests[0].updateTableCellProperties: Invalid field: table_cell_properties",
"status": "INVALID_ARGUMENT"
}
}
Why is this updateTableCellProperties request reported as invalid? I am also confused by the output of the error message as it mentions table_cell_properties in snake case, while the documentation only mentions tableCellProperties in camel case, and my request also only mentions tableCellProperties in camel case. I am only aware of the ruby gems translating between snake case and camel case, but this is not relevant to the API Explorer.
The error Invalid field: table_cell_properties originates from the erroneously specified fields property
See documentation:
fields
At least one field must be specified. The root tableCellProperties is implied and should not be specified. A single "*" can be used as short-hand for listing every field.
So you need to modify fields
from
"fields": "tableCellProperties"
to
"fields": "tableCellBackgroundFill.solidFill.color"
or to
"fields": "*"
There is a second problem with your request:
When specifying the table range, it is required to set the properties rowSpan and columnSpan.
A complete, correct request would be:
{
"requests": [
{
"updateTableCellProperties": {
"objectId": "gf9d8fea71f_22_1",
"tableRange": {
"location": {
"columnIndex": 0,
"rowIndex": 1
},
"rowSpan": 1,
"columnSpan": 1
},
"fields": "tableCellBackgroundFill.solidFill.color",
"tableCellProperties": {
"tableCellBackgroundFill": {
"solidFill": {
"color": {
"themeColor": "LIGHT1"
}
}
}
}
}
}
]
}

Twitter API 2.0 - Unable to fetch user.fields

I am using API version 2.0 and unable to fetch the user.fields results. All other parameters seem to be returning results correctly. I'm following this documentation.
url = "https://api.twitter.com/2/tweets/search/all"
query_params = {
"query": "APPL",
"max_results": "10",
"tweet.fields": "created_at,lang,text,author_id",
"user.fields": "name,username,created_at,location",
"expansions": "referenced_tweets.id.author_id",
}
response = requests.request("GET", url, headers=headers, params=query_params).json()
Sample result:
{
'author_id': '1251347502013521925',
'text': 'All conspiracy. But watch for bad news on Apple. Such a vulnerable stocktechnically for the biggest market cap # $2.1T ( Thanks Jay). This is the glue for the bulls. But, they stopped innovating when Steve died, built a fancy office and split the stock. $appl',
'lang': 'en',
'created_at': '2021-06-05T02:33:48.000Z',
'id': '1401004298738311168',
'referenced_tweets': [{
'type': 'retweeted',
'id': '1401004298738311168'
}]
}
As you can see, the following information is not returned: name, username, and location.
Any idea how to retrieve this info?
Your query does actually return the correct data. I tested this myself.
A full example response will be structured like this:
{
"data": [
{
"created_at": "2021-06-05T02:33:48.000Z",
"lang": "en",
"id": "1401004298738311168",
"text": "All conspiracy. But watch for bad news on Apple. Such a vulnerable stocktechnically for the biggest market cap # $2.1T ( Thanks Jay). This is the glue for the bulls. But, they stopped innovating when Steve died, built a fancy office and split the stock. $appl",
"author_id": "1251347502013521925",
"referenced_tweets": [
{
"type": "retweeted",
"id": "1401004298738311168"
}
]
}
],
"includes": {
"users": [
{
"name": "Gary Casper",
"id": "1251347502013521925",
"username": "Hisel1979",
"created_at": "2020-07-11T13:39:58.000Z"
}
]
}
}
The sample result you provided comes from within the data object. However, the expanded object data will be nested in the includes object (in your case name, username, and location). The corresponding user object can be referenced via the author_id field.

Is it possible to move a Shape from a slide to another?

I use the Google Slides API on a NodeJS server to edit a presentation and I can't find anything in the documentation on moving an object to another slide, a Shape for example.
Answer:
You have to do this by getting the shape from the response of presentations.pages.get, removing it, and inserting it with presentations.batchUpdate.
More Information:
In order to 'move' an object from one slide to another using the API, you in fact have to make two requests: one to remove the current object, and one to insert it into the new slide.
Firstly, you will need to make a request to presentations.pages.get in order to get all PageElement objects in the page. As per the documentation, a Shape is an instance of a PageElement object which represents a shape on a slide.
The response of presentations.pages.get will be a Page resource:
{
"objectId": string,
"pageType": enum (PageType),
"pageElements": [
{
object (PageElement)
}
],
"revisionId": string,
"pageProperties": {
object (PageProperties)
},
// Union field properties can be only one of the following:
"slideProperties": {
object (SlideProperties)
},
"layoutProperties": {
object (LayoutProperties)
},
"notesProperties": {
object (NotesProperties)
},
"masterProperties": {
object (MasterProperties)
}
}
The Shape will be contained within the response['pageElements'] resource from this request and will be of the form:
{
"objectId": string,
"size": {
object (Size)
},
"transform": {
object (AffineTransform)
},
"title": string,
"description": string,
// Union field element_kind can be only one of the following:
"elementGroup": {
object (Group)
},
"shape": {
"shapeType": enum (Type),
"text": {
object (TextContent)
},
"shapeProperties": {
object (ShapeProperties)
},
"placeholder": {
object (Placeholder)
}
},
}
Once you have obtained the Shape object out of the response you get from presentations.pages.get, you will need to then create a CreateShapeRequest out of the retrieved properties:
{
"objectId": string,
"elementProperties": {
object (PageElementProperties)
},
"shapeType": enum (Type)
}
And a DeleteObjectRequest which can be used to remove the Shape on the previous slide:
{
"objectId": string
}
The DeleteObjectRequest and CreateShapeRequest can be both contained inside the same batchUpdate request. The request body should be of the form:
{
"requests": [
{
object (Request)
}
],
"writeControl": {
object (WriteControl)
}
}
The full documentation for the batchUpdate method can be seen here.
References:
Shapes | Slides API | Google Developers
REST Resource: presentations.pages | Slides API | Google Developers
Requests | Slides API | Google Developers
Method: presentations.batchUpdate | Slides API | Google Developers

Youtube ContentID getting ownership info through the API using AppsScript

I am trying to get get ownership information against AssetIDs through the Youtube ContentID API.
I can see the data that I need through the API Explorer but cant seem to drill down the data using dot notation.
Here is the output from the API explorer:
{
"kind": "youtubePartner#asset",
"id": "A146063471697194",
"type": "music_video",
"ownership": {
"kind": "youtubePartner#rightsOwnership",
"general": [
{
"ratio": 100,
"owner": "Indmusic",
"type": "exclude"
}
]
},
"ownershipEffective": {
"kind": "youtubePartner#rightsOwnership",
"general": [
{
"ratio": 100,
"owner": "Indmusic",
"type": "exclude"
}
]
}
}
When accessing the "owner" I receive undefined instead of the listed value.
var url2 = _.sprintf('https://www.googleapis.com/youtube/partner/v1/assets/%s?fetchMetadata=effective&fetchOwnership=effective&key=%s',id,API_KEY);
var result2 = JSON.parse(UrlFetchApp.fetch(url2, getUrlFetchOptions()).getContentText());
Logger.log(result2.ownership.general.owner);
returns undefined
I have tried both ownershipEffective and ownership and they are both undefined.
I can log data from result2.ownership.general but nothing below that.
You can tell that general is an array by the [brackets] in:
"general": [
{
"ratio": 100,
"owner": "Indmusic",
"type": "exclude"
}
]
Try:
Logger.log(result2.ownership.general[0].owner);
general, having been declared an array, requires a position [0] even though there is only 1 item in the array.

Resources