### Install http-server Package Source: https://developers.google.com/workspace/docs/api/quickstart/js Install the http-server package globally to serve your web application locally. This is a prerequisite for running the quickstart. ```bash npm install http-server ``` -------------------------------- ### Install Python Client Library Manually Source: https://developers.google.com/workspace/docs/api/how-tos/libraries Install the Python client library by downloading, unpacking, and running the setup script. ```bash python setup.py install ``` -------------------------------- ### Install Python Client Library with Setuptools Source: https://developers.google.com/workspace/docs/api/how-tos/libraries Use easy_install with setuptools to install or upgrade the google-api-python-client library. ```bash easy_install --upgrade google-api-python-client ``` -------------------------------- ### Run Python Quickstart Sample Source: https://developers.google.com/workspace/docs/api/quickstart/python Execute this command in your working directory to build and run the Python quickstart application. The first run will prompt for authorization. ```bash python3 quickstart.py ``` -------------------------------- ### Install Node.js Client Libraries Source: https://developers.google.com/workspace/docs/api/quickstart/nodejs Install the necessary Google API client libraries for Node.js using npm. This command installs the core 'googleapis' library and the '@google-cloud/local-auth' library for local authentication. ```bash npm install googleapis@105 @google-cloud/local-auth@2.1.0 --save ``` -------------------------------- ### Install Python Client Library with Pip Source: https://developers.google.com/workspace/docs/api/how-tos/libraries Use pip to install or upgrade the google-api-python-client library. This is the preferred method for Python installations. ```bash pip install --upgrade google-api-python-client ``` -------------------------------- ### Run the Node.js Sample Source: https://developers.google.com/workspace/docs/api/quickstart/nodejs Execute the Node.js quickstart application from your terminal. The first time it runs, it will prompt for authorization via your Google Account. ```bash node . ``` -------------------------------- ### Install Google Client Library for Python Source: https://developers.google.com/workspace/docs/api/quickstart/python Install the necessary Google client libraries for Python using pip. This is the first step to using Google Workspace APIs. ```bash python3 -m pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib ``` -------------------------------- ### Build and Run Go Quickstart Source: https://developers.google.com/workspace/docs/api/quickstart/go Execute this command in your working directory to build and run the Go sample application. The first time it runs, it will prompt for authorization. ```bash go run quickstart.go ``` -------------------------------- ### Resource-Level Field Selection Examples Source: https://developers.google.com/workspace/docs/api/how-tos/performance These examples show how to select specific fields from a single resource response. Fields are specified relative to the resource itself. ```text title ``` ```text author/uri ``` ```text links/*/href ``` -------------------------------- ### Install Ruby Client Library with RubyGems Source: https://developers.google.com/workspace/docs/api/how-tos/libraries Install the google-api-client gem using RubyGems. You may need to prepend 'sudo' depending on your system configuration. ```bash gem install google-api-client ``` -------------------------------- ### Full Resource Response Example Source: https://developers.google.com/workspace/docs/api/how-tos/performance An example of a full resource response, showing various fields including nested objects and arrays. Many fields are omitted for brevity. ```JSON { "kind": "demo", ... "items": [ { "title": "First title", "comment": "First comment.", "characteristics": { "length": "short", "accuracy": "high", "followers": ["Jo", "Will"], }, "status": "active", ... }, { "title": "Second title", "comment": "Second comment.", "characteristics": { "length": "long", "accuracy": "medium" "followers": [ ], }, "status": "pending", ... }, ... ] } ``` -------------------------------- ### Python: Setup for Google Docs API Source: https://developers.google.com/workspace/docs/api/samples/extract-text?hl=zh-CN This Python code snippet shows the initial setup for accessing the Google Docs API. It defines the necessary scopes, discovery document, and placeholder for document ID and credentials. Ensure you have a valid `token.json` file or implement the OAuth flow. ```Python # Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Recursively extracts the text from a Google Doc. """ import os.path import googleapiclient.discovery as discovery from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.errors import HttpError # If modifying these scopes, delete the file token.json. SCOPES = 'https://www.googleapis.com/auth/documents.readonly' DISCOVERY_DOC = 'https://docs.googleapis.com/$discovery/rest?version=v1' DOCUMENT_ID = 'YOUR_DOCUMENT_ID' def get_credentials(): """Gets valid user credentials from storage. If nothing has been stored, or if the stored credentials are invalid, the OAuth 2.0 flow is completed to obtain the new credentials. """ creds = None # The file token.json stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.json', 'w') as token: token.write(creds.to_json()) return creds def main(): try: creds = get_credentials() service = discovery.build('docs', 'v1', credentials=creds) # Prints the title of the sample document. document = service.documents().get(documentId=DOCUMENT_ID).execute() print(f"Document title: {document.get('title')}") except HttpError as error: print(f'An error occurred: {error}') document = None return document if __name__ == '__main__': main() ``` -------------------------------- ### Start Local Web Server Source: https://developers.google.com/workspace/docs/api/quickstart/js Start a local web server using http-server on port 8000. This server will host your JavaScript application and allow it to communicate with the Google Docs API. ```bash npx http-server -p 8000 ``` -------------------------------- ### HTML Structure and JavaScript for Google Docs API Quickstart Source: https://developers.google.com/workspace/docs/api/quickstart/js This snippet includes the HTML for the quickstart page and the JavaScript code to handle authentication, API initialization, and fetching document titles. Ensure you replace placeholders with your actual client ID and API key. ```html Google Docs API Quickstart

Google Docs API Quickstart



    
    
    
  

```

--------------------------------

### Partial Response Example

Source: https://developers.google.com/workspace/docs/api/how-tos/performance

This is an example of a partial response received after a request with a valid `fields` parameter. It includes only the fields specified in the request.

```json
{
  "kind": "demo",
  "items": [
    {
      "title": "First title",
      "characteristics": {
        "length": "short"
      }
    }, {
      "title": "Second title",
      "characteristics": {
        "length": "long"
      }
    },
    ...
  ]
}
```

--------------------------------

### Collection-Level Field Selection Examples

Source: https://developers.google.com/workspace/docs/api/how-tos/performance

These examples demonstrate how to select specific fields from a collection response. The `fields` parameter accepts a comma-separated list of fields relative to the root of the response.

```text
items
```

```text
etag,items
```

```text
items/title
```

```text
context/facets/label
```

```text
items/pagemap/*/title
```

--------------------------------

### Go Quickstart Application

Source: https://developers.google.com/workspace/docs/api/quickstart/go

This Go program authenticates with the Google Docs API, retrieves a document by its ID, and prints its title. Ensure you have a 'credentials.json' file and a 'token.json' will be generated upon first run.

```go
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/docs/v1"
	"google.golang.org/api/option"
)

// Retrieves a token, saves the token, then returns the generated client.
func getClient(config *oauth2.Config) *http.Client {
	tokFile := "token.json"
	tok, err := tokenFromFile(tokFile)
	if err != nil {
		tok = getTokenFromWeb(config)
		saveToken(tokFile, tok)
	}
	return config.Client(context.Background(), tok)
}

// Requests a token from the web, then returns the retrieved token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
	authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
	fmt.Printf("Go to the following link in your browser then type the " +
		"authorization code: \n%v\n", authURL)

	var authCode string
	if _, err := fmt.Scan(&authCode); err != nil {
		log.Fatalf("Unable to read authorization code: %v", err)
	}

	tok, err := config.Exchange(oauth2.NoContext, authCode)
	if err != nil {
		log.Fatalf("Unable to retrieve token from web: %v", err)
	}
	return tok
}

// Retrieves a token from a local file.
func tokenFromFile(file string) (*oauth2.Token, error) {
	f, err := os.Open(file)
	defer f.Close()
	if err != nil {
		return nil, err
	}
	tok := &oauth2.Token{}
	err = json.NewDecoder(f).Decode(tok)
	return tok, err
}

// Saves a token to a file path.
func saveToken(path string, token *oauth2.Token) {
	fmt.Printf("Saving credential file to: %s\n", path)
	f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	defer f.Close()
	if err != nil {
		log.Fatalf("Unable to cache OAuth token: %v", err)
	}
	json.NewEncoder(f).Encode(token)
}

func main() {
	ctx := context.Background()
	b, err := os.ReadFile("credentials.json")
	if err != nil {
		log.Fatalf("Unable to read client secret file: %v", err)
	}

	// If modifying these scopes, delete your previously saved token.json.
	config, err := google.ConfigFromJSON(b, "https://www.googleapis.com/auth/documents.readonly")
	if err != nil {
		log.Fatalf("Unable to parse client secret file to config: %v", err)
	}
	client := getClient(config)

	srv, err := docs.NewService(ctx, option.WithHTTPClient(client))
	if err != nil {
		log.Fatalf("Unable to retrieve Docs client: %v", err)
	}

	// Prints the title of the requested doc:
	// https://docs.google.com/document/d/195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE/edit
	docId := "195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE"
	doc, err := srv.Documents.Get(docId).Do()
	if err != nil {
		log.Fatalf("Unable to retrieve data from document: %v", err)
	}
	fmt.Printf("The title of the doc is: %s\n", doc.Title)
}

```

--------------------------------

### Node.js Quickstart Application

Source: https://developers.google.com/workspace/docs/api/quickstart/nodejs

This Node.js script authenticates with Google using local credentials and fetches the title of a specified Google Document. Ensure you have a 'credentials.json' file in your working directory for authentication.

```javascript
import path from 'node:path';
import process from 'node:process';
import {authenticate} from '@google-cloud/local-auth';
import {google} from 'googleapis';

// The scope for reading Google Docs.
const SCOPES = ['https://www.googleapis.com/auth/documents.readonly'];
// The path to the credentials file.
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json');

/**
 * Prints the title of a sample doc: 
 * https://docs.google.com/document/d/195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE/edit
 */
async function printDocTitle() {
  // Authenticate with Google and get an authorized client.
  const auth = await authenticate({
    scopes: SCOPES,
    keyfilePath: CREDENTIALS_PATH,
  });

  // Create a new Docs API client.
  const docs = google.docs({version: 'v1', auth});
  // Get the document.
  const result = await docs.documents.get({
    documentId: '195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE',
  });
  // Print the title of the document.
  console.log(`The title of the document is: ${result.data.title}`);
}

await printDocTitle();

```

--------------------------------

### Partial Resource Response Example

Source: https://developers.google.com/workspace/docs/api/how-tos/performance

A 200 OK response to a partial response request, containing only the 'kind' and specified fields from the 'items' array.

```JSON
{
  "kind": "demo",
  "items": [{
    "title": "First title",
    "characteristics": {
      "length": "short"
    }
  }, {
    "title": "Second title",
    "characteristics": {
      "length": "long"
    }
  },
  ...
  ]
}
```

--------------------------------

### Get Google Docs API and OAuth2 client libraries

Source: https://developers.google.com/workspace/docs/api/quickstart/go

Download the necessary Go client libraries for the Google Docs API and OAuth2 authentication.

```bash
go get google.golang.org/api/docs/v1
go get golang.org/x/oauth2/google

```

--------------------------------

### Update Ruby Client Library

Source: https://developers.google.com/workspace/docs/api/how-tos/libraries

Update an existing installation of the google-api-client gem to the latest version.

```bash
gem update -y google-api-client
```

--------------------------------

### get

Source: https://developers.google.com/workspace/docs/api/reference/rest/v1/documents

Retrieves a document. The document is returned in its current state.

```APIDOC
## get

### Description
Retrieves a document. The document is returned in its current state.

### Method
GET

### Endpoint
/v1/documents/{documentId}

### Parameters
#### Path Parameters
- **documentId** (string) - Required - The ID of the document to retrieve.

### Response
#### Success Response (200)
- **documentId** (string) - The ID of the document.
- **title** (string) - The title of the document.
- **body** (object) - The body of the document.
- **revisionId** (string) - The revision ID of the document.

#### Response Example
{
  "documentId": "12345abcde",
  "title": "My Existing Document",
  "body": {
    "content": [
      {
        "paragraph": {
          "elements": [
            {
              "textRun": {
                "content": "Hello, world!\n",
                "textStyle": {}
              }
            }
          ],
          "structureLevel": 0
        }
      }
    ]
  },
  "revisionId": "2"
}
```

--------------------------------

### Python Quickstart for Google Docs API

Source: https://developers.google.com/workspace/docs/api/quickstart/python

This Python script demonstrates how to authenticate with the Google Docs API and retrieve the title of a specified document. Ensure you have a 'credentials.json' file and have deleted 'token.json' if re-authenticating.

```python
import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = ["https://www.googleapis.com/auth/documents.readonly"]

# The ID of a sample document.
DOCUMENT_ID = "195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE"


def main():
  """Shows basic usage of the Docs API.
  Prints the title of a sample document.
  """
  creds = None
  # The file token.json stores the user's access and refresh tokens, and is
  # created automatically when the authorization flow completes for the first
  # time.
  if os.path.exists("token.json"):
    creds = Credentials.from_authorized_user_file("token.json", SCOPES)
  # If there are no (valid) credentials available, let the user log in.
  if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
      creds.refresh(Request())
    else:
      flow = InstalledAppFlow.from_client_secrets_file(
          "credentials.json", SCOPES
      )
      creds = flow.run_local_server(port=0)
    # Save the credentials for the next run
    with open("token.json", "w") as token:
      token.write(creds.to_json())

  try:
    service = build("docs", "v1", credentials=creds)

    # Retrieve the documents contents from the Docs service.
    document = service.documents().get(documentId=DOCUMENT_ID).execute()

    print(f"The title of the document is: {document.get('title')}")
  except HttpError as err:
    print(err)


if __name__ == "__main__":
  main()

```

--------------------------------

### Python: Google Docs Text Extraction Setup

Source: https://developers.google.com/workspace/docs/api/samples/extract-text

Sets up the Google Docs API client, including authentication and scope definition. This snippet handles credential management and API discovery.

```python
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. 
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, 
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
# See the License for the specific language governing permissions and 
# limitations under the License.

"""
Recursively extracts the text from a Google Doc.
"""
import os.path

import googleapiclient.discovery as discovery
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = 'https://www.googleapis.com/auth/documents.readonly'
DISCOVERY_DOC = 'https://docs.googleapis.com/$discovery/rest?version=v1'
DOCUMENT_ID = 'YOUR_DOCUMENT_ID'


def get_credentials():
  """Gets valid user credentials from storage.

  If nothing has been stored, or if the stored credentials are invalid, 
  the OAuth 2.0 flow is completed to obtain the new credentials.

  Returns:
      Credentials, the obtained credential.
  """
  creds = None
  # The file token.json stores the user's access and refresh tokens, and is
  # created automatically when the authorization flow completes for the first
  # time.
  if os.path.exists('token.json'):
    creds = Credentials.from_authorized_user_file('token.json', SCOPES)
  # If there are no (valid) credentials available, let the user log in.
  if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
      creds.refresh(Request())
    else:
      flow = InstalledAppFlow.from_client_secrets_file(
          'credentials.json', SCOPES)
      creds = flow.run_local_server(port=0)
    # Save the credentials for the next run
    with open('token.json', 'w') as token:
      token.write(creds.to_json())
  return creds


def add_current_and_child_tabs(tab, all_tabs):
  """Adds the provided tab to the list of all tabs, and recurses through and
  adds all child tabs.

```

--------------------------------

### Documents Resource Methods

Source: https://developers.google.com/workspace/docs/api/concepts/document

The `documents` resource provides methods to interact with Google Docs. Key methods include `create` for new documents, `get` for retrieving document content, and `batchUpdate` for performing multiple updates atomically. Both `get` and `batchUpdate` require a `documentId`, while `create` returns the ID of the newly created document.

```APIDOC
## API Methods

The `documents` resource provides methods you use to invoke the Docs API. The following methods let you create, read, and update Docs documents:

* Use the `documents.create` method to create a document.
* Use the `documents.get` method to retrieve the contents of a specified document.
* Use the `documents.batchUpdate` method to atomically perform a set of updates on a specified document.

The `documents.get` and `documents.batchUpdate` methods require a `documentId` as a parameter to specify the target document. The `documents.create` method returns an instance of the created document, from which you can read the `documentId`. For more information about Docs API requests and response methods, see Requests and responses.
```

--------------------------------

### get

Source: https://developers.google.com/workspace/docs/api/reference/rest/v1/documents

Retrieves a document. You can specify fields to retrieve for a more efficient response.

```APIDOC
## get

### Description
Retrieves a document. You can specify fields to retrieve for a more efficient response.

### Method
GET

### Endpoint
/v1/documents/{documentId}

### Parameters
#### Path Parameters
- **documentId** (string) - Required - The ID of the document to retrieve.

#### Query Parameters
- **fields** (string) - Optional - Specifies which fields of the Document to return. See [FieldMask](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask).

### Response
#### Success Response (200)
- **documentId** (string) - The ID of the document.
- **title** (string) - The title of the document.

#### Response Example
{
  "documentId": "12345",
  "title": "My Existing Document"
}
```

--------------------------------

### Example Document JSON Output

Source: https://developers.google.com/workspace/docs/api/samples/output-json

This JSON represents a sample Google Workspace document, including its title, revision ID, and structured content with paragraphs, headings, and lists.

```json
{
  "title": "Test mule",
  "revisionId": "np_INheZiecEMA",
  "suggestionsViewMode": "SUGGESTIONS_INLINE",
  "documentId": "18AI89WMd4eI6TFI4VrbmD_srVWJYH2avsXpC_amtLZs",
  "tabs": [{
    "tabProperties": {
      "tabId": "t.0",
      "title": "Tab 1",
      "index": 0
    },
    "documentTab": {
      "body": {
        "content": [{
          "endIndex": 1,
          "sectionBreak": {
            "sectionStyle": {
              "columnSeparatorStyle": "NONE",
              "contentDirection": "LEFT_TO_RIGHT",
              "sectionType": "CONTINUOUS"
            }
          }
        }, { 
          "startIndex": 1,
          "endIndex": 75,
          "paragraph": {
            "elements": [{
              "startIndex": 1,
              "endIndex": 75,
              "textRun": {
                "content": "This is an ordinary paragraph. It is the first paragraph of the document.\n",
                "textStyle": {
                }
              }
            }],
            "paragraphStyle": {
              "namedStyleType": "NORMAL_TEXT",
              "direction": "LEFT_TO_RIGHT"
            }
          }
        }, { 
          "startIndex": 75,
          "endIndex": 102,
          "paragraph": {
            "elements": [{
              "startIndex": 75,
              "endIndex": 102,
              "textRun": {
                "content": "Here\u0027s a level one heading\n",
                "textStyle": {
                }
              }
            }],
            "paragraphStyle": {
              "headingId": "h.tzrthsds4pvi",
              "namedStyleType": "HEADING_1",
              "direction": "LEFT_TO_RIGHT"
            }
          }
        }, { 
          "startIndex": 102,
          "endIndex": 219,
          "paragraph": {
            "elements": [{
              "startIndex": 102,
              "endIndex": 171,
              "textRun": {
                "content": "This is another paragraph. Formatting within this paragraph includes ",
                "textStyle": {
                }
              }
            }, { 
              "startIndex": 171,
              "endIndex": 190,
              "textRun": {
                "content": "these words in bold",
                "textStyle": {
                  "bold": true
                }
              }
            }, { 
              "startIndex": 190,
              "endIndex": 207,
              "textRun": {
                "content": " and these words ",
                "textStyle": {
                }
              }
            }, { 
              "startIndex": 207,
              "endIndex": 217,
              "textRun": {
                "content": "in italics",
                "textStyle": {
                  "italic": true
                }
              }
            }, { 
              "startIndex": 217,
              "endIndex": 219,
              "textRun": {
                "content": ".\n",
                "textStyle": {
                }
              }
            }],
            "paragraphStyle": {
              "namedStyleType": "NORMAL_TEXT",
              "direction": "LEFT_TO_RIGHT"
            }
          }
        }, { 
          "startIndex": 219,
          "endIndex": 248,
          "paragraph": {
            "elements": [{
              "startIndex": 219,
              "endIndex": 248,
              "textRun": {
                "content": "This is a bulleted list item\n",
                "textStyle": {
                }
              }
            }],
            "paragraphStyle": {
              "namedStyleType": "NORMAL_TEXT",
              "direction": "LEFT_TO_RIGHT",
              "indentFirstLine": {
                "magnitude": 18.0,
                "unit": "PT"
              },
              "indentStart": {
                "magnitude": 36.0,
                "unit": "PT"
              }
            },
            "bullet": {
              "listId": "kix.v1x94gs10mnc",
              "textStyle": {
                "underline": false
              }
            }
          }
        }, { 
          "startIndex": 248,
          "endIndex": 308,
          "paragraph": {
            "elements": [{
              "startIndex": 248,
              "endIndex": 308,
              "textRun": {
                "content": "And this is another one, which has a numbered list under it\n",
                "textStyle": {
                }
              }
            }],
            "paragraphStyle": {
              "namedStyleType": "NORMAL_TEXT",
              "direction": "LEFT_TO_RIGHT",
              "indentFirstLine": {
                "magnitude": 18.0,
                "unit": "PT"
              },
              "indentStart": {
                "magnitude": 36.0,
                "unit": "PT"
              }
            }
          }
        }]
      }
    }
  }]
}
```

--------------------------------

### Java Quickstart for Google Docs API

Source: https://developers.google.com/workspace/docs/api/quickstart/java

This Java code demonstrates how to authenticate with the Google Docs API using OAuth 2.0 and retrieve the title of a specified document. It requires a `credentials.json` file and sets up a local server for authorization.

```java
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.docs.v1.Docs;
import com.google.api.services.docs.v1.DocsScopes;
import com.google.api.services.docs.v1.model.Document;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

/* class to demonstrate use of Docs get documents API */
public class DocsQuickstart {
  /**
   * Application name.
   */
  private static final String APPLICATION_NAME = "Google Docs API Java Quickstart";
  /**
   * Global instance of the JSON factory.
   */
  private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
  /**
   * Directory to store authorization tokens for this application.
   */
  private static final String TOKENS_DIRECTORY_PATH = "tokens";
  private static final String DOCUMENT_ID = "195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE";

  /**
   * Global instance of the scopes required by this quickstart.
   * If modifying these scopes, delete your previously saved tokens/ folder.
   */
  private static final List SCOPES = 
      Collections.singletonList(DocsScopes.DOCUMENTS_READONLY);
  private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

  /**
   * Creates an authorized Credential object.
   *
   * @param HTTP_TRANSPORT The network HTTP Transport.
   * @return An authorized Credential object.
   * @throws IOException If the credentials.json file cannot be found.
   */
  private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT)
      throws IOException {
    // Load client secrets.
    InputStream in = DocsQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
    if (in == null) {
      throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
    }
    GoogleClientSecrets clientSecrets = 
        GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

    // Build flow and trigger user authorization request.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) 
        .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
        .setAccessType("offline")
        .build();
    LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
    Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
    //returns an authorized Credential object.
    return credential;
  }

  public static void main(String... args) throws IOException, GeneralSecurityException {
    // Build a new authorized API client service.
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    Docs service = new Docs.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
        .setApplicationName(APPLICATION_NAME)
        .build();

    // Prints the title of the requested doc:
    // https://docs.google.com/document/d/195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE/edit
    Document response = service.documents().get(DOCUMENT_ID).execute();
    String title = response.getTitle();

    System.out.printf("The title of the doc is: %s\n", title);
  }
}
```

--------------------------------

### Example Document URL with ID

Source: https://developers.google.com/workspace/docs/api/how-tos/overview

A sample URL structure showing where the unique Document ID is located within a Google Docs URL.

```text
https://docs.google.com/document/d/DOCUMENT_ID/edit
```

--------------------------------

### Batch Update Text Style

Source: https://developers.google.com/workspace/docs/api/how-tos/format-text

This example demonstrates how to perform multiple text styling operations, including setting bold and italic fonts, changing font size and color, and adding hyperlinks, using a single batchUpdate call.

```APIDOC
## Batch Update Text Style

### Description
This operation allows for multiple text styling modifications within a document. It supports setting font styles (bold, italic), font family, font size, foreground color, and hyperlinks for specified ranges of text.

### Method
`batchUpdate`

### Endpoint
`docsService.documents().batchUpdate("DOCUMENT_ID", body).execute()`

### Parameters
#### Request Body
- **requests** (array) - Required - A list of `Request` objects, where each object specifies a text styling operation.
  - **updateTextStyle** (object) - Required - Defines the text style update operation.
    - **textStyle** (object) - Required - Specifies the desired text styles.
      - **bold** (boolean) - Optional - Sets the text to bold.
      - **italic** (boolean) - Optional - Sets the text to italic.
      - **weightedFontFamily** (object) - Optional - Specifies the font family.
        - **fontFamily** (string) - Required - The name of the font family.
      - **fontSize** (object) - Optional - Specifies the font size.
        - **magnitude** (number) - Required - The font size value.
        - **unit** (string) - Required - The unit of the font size (e.g., "PT").
      - **foregroundColor** (object) - Optional - Sets the foreground color of the text.
        - **color** (object) - Required - The color object.
          - **rgbColor** (object) - Required - The RGB color.
            - **red** (number) - Required - Red component (0.0-1.0).
            - **green** (number) - Required - Green component (0.0-1.0).
            - **blue** (number) - Required - Blue component (0.0-1.0).
      - **link** (object) - Optional - Sets a hyperlink for the text.
        - **url** (string) - Required - The URL for the hyperlink.
    - **range** (object) - Required - Defines the range of text to format.
      - **startIndex** (integer) - Required - The starting index of the text range.
      - **endIndex** (integer) - Required - The ending index of the text range.
      - **tabId** (string) - Optional - Identifies the tab containing the text.
    - **fields** (string) - Required - Specifies which fields in `textStyle` are being updated.

### Request Example (Python)
```python
requests = [
    {
        'updateTextStyle': {
            'range': {
                'startIndex': 1,
                'endIndex': 5,
                'tabId': 'TAB_ID'
            },
            'textStyle': {
                'bold': True,
                'italic': True
            },
            'fields': 'bold,italic'
        }
    },
    {
        'updateTextStyle': {
            'range': {
                'startIndex': 6,
                'endIndex': 10,
                'tabId': 'TAB_ID'
            },
            'textStyle': {
                'weightedFontFamily': {
                    'fontFamily': 'Times New Roman'
                },
                'fontSize': {
                    'magnitude': 14,
                    'unit': 'PT'
                },
                'foregroundColor': {
                    'color': {
                        'rgbColor': {
                            'blue': 1.0,
                            'green': 0.0,
                            'red': 0.0
                        }
                    }
                }
            },
            'fields': 'foregroundColor,weightedFontFamily,fontSize'
        }
    },
    {
        'updateTextStyle': {
            'range': {
                'startIndex': 11,
                'endIndex': 15,
                'tabId': 'TAB_ID'
            },
            'textStyle': {
                'link': {
                    'url': 'www.example.com'
                }
            },
            'fields': 'link'
        }
    }
]

result = service.documents().batchUpdate(
    documentId='DOCUMENT_ID', body={'requests': requests}).execute()
```

### Response
#### Success Response (200)
- **replies** (array) - A list of replies corresponding to the requests made.
- **writeControl** (object) - Control information for the document update.

#### Response Example (Python)
```python
# Response structure will vary based on the specific updates performed.
# Example of a potential response structure:
{
  "replies": [
    { "updateTextStyle": { "range": { "startIndex": 1, "endIndex": 5 } } },
    { "updateTextStyle": { "range": { "startIndex": 6, "endIndex": 10 } } },
    { "updateTextStyle": { "range": { "startIndex": 11, "endIndex": 15 } } }
  ],
  "writeControl": {
    "requiredRevisionId": "some-revision-id"
  }
}
```
```

--------------------------------

### Batch Response with Write Control

Source: https://developers.google.com/workspace/docs/api/how-tos/batch

This example shows a typical batch response from the Docs API, indicating how subrequests were applied and including write control information. Empty objects signify no direct response from specific subrequests.

```json
{
   "replies":[
      {},
      {}
   ],
   "writeControl":{
      "requiredRevisionId":`REQUIRED_REVISION_ID`
   },
   "documentId":`DOCUMENT_ID`
}
```

--------------------------------

### Create a Bulleted List from Paragraphs (Python)

Source: https://developers.google.com/workspace/docs/api/how-tos/lists

This Python snippet shows how to achieve the same list creation functionality as the Java example. It inserts text and then applies bullet formatting to a range of paragraphs using a specified bullet preset.

```python
requests = [
        {
        'insertText': {
            'location': {
                'index': 1,
                'tabId': TAB_ID
            },
            'text': 'Item One\n',
        }}, {
        'createParagraphBullets': {
            'range': {
                'startIndex': 1,
                'endIndex':  50,
                'tabId': TAB_ID
            },
            'bulletPreset': 'BULLET_ARROW_DIAMOND_DISC',
        }
    }
]

result = service.documents().batchUpdate(
    documentId=DOCUMENT_ID, body={'requests': requests}).execute()
```

--------------------------------

### Get Document Content Without Suggestions (Java)

Source: https://developers.google.com/workspace/docs/api/how-tos/suggestions

Retrieve a document's content with all suggestions rejected by setting the SuggestionsViewMode to PREVIEW_WITHOUT_SUGGESTIONS. This is useful for previewing the document as it would appear without any suggested changes.

```Java
final string SUGGEST_MODE = "PREVIEW_WITHOUT_SUGGESTIONS";
Document doc =
    service
        .documents()
        .get(DOCUMENT_ID)
        .setIncludeTabsContent(true)
        .setSuggestionsViewMode(SUGGEST_MODE)
        .execute();
```

--------------------------------

### Batch Update with WriteControl

Source: https://developers.google.com/workspace/docs/api/how-tos/best-practices

Use WriteControl to ensure state consistency when performing batch updates. This example demonstrates how to include the requiredRevisionId to prevent updates on outdated documents.

```json
{
  "requests": [
    {
      "insertText": {
        "text": "New text.",
        "location": {
          "index": 1
        }
      }
    }
  ],
  "writeControl": {
    "requiredRevisionId": "YOUR_REVISION_ID"
  }
}
```

--------------------------------

### Get Document Content Without Suggestions (Python)

Source: https://developers.google.com/workspace/docs/api/how-tos/suggestions

Retrieve a document's content with all suggestions rejected by setting the SuggestionsViewMode to PREVIEW_WITHOUT_SUGGESTIONS. This is useful for previewing the document as it would appear without any suggested changes.

```Python
SUGGEST_MODE = "PREVIEW_WITHOUT_SUGGESTIONS"
result = (
  service.documents()
  .get(
      documentId=DOCUMENT_ID,
      includeTabsContent=True,
      suggestionsViewMode=SUGGEST_MODE,
  )
  .execute()
)
```

--------------------------------

### Batch Request to Insert Text and Update Style

Source: https://developers.google.com/workspace/docs/api/how-tos/batch

This example demonstrates a batch request to insert text and then update the style of a portion of that text. It requires specifying the tab ID and a required revision ID for write control.

```json
{
   "requests":[
      {
         "insertText":{
            "location":{
               "index":1,
               "tabId":TAB_ID
            },
            "text":"Hello World"
         }
      },
      {
         "updateTextStyle":{
            "range":{
               "startIndex":1,
               "endIndex":6
            },
            "textStyle":{
               "bold":true,
               "foregroundColor":{
                  "color":{
                     "rgbColor":{
                        "blue":1
                     }
                  }
               }
            },
            "fields":"bold,foreground_color"
         }
      }
   ],
   "writeControl": {
      "requiredRevisionId": "REQUIRED_REVISION_ID"
  }
}
```

--------------------------------

### get

Source: https://developers.google.com/workspace/docs/api/reference/rest/v1/documents

Gets the latest version of the specified document.

```APIDOC
## get

### Description
Gets the latest version of the specified document.

### Method
GET (Assumed based on 'get' operation)

### Endpoint
/v1/documents/{documentId} (Assumed based on path and method name)

### Parameters
#### Path Parameters
- **documentId** (string) - Required - The ID of the document to retrieve.

### Request Body
(Not applicable for GET requests)

### Response
(No specific response documented in the source)
```

--------------------------------

### Initialize Java Project Structure

Source: https://developers.google.com/workspace/docs/api/quickstart/java

Use these commands to create a basic Java project structure and initialize Gradle.

```bash
gradle init --type basic
mkdir -p src/main/java src/main/resources 

```

--------------------------------

### get

Source: https://developers.google.com/workspace/docs/api/reference/rest

Gets the latest version of the specified document. Use this method to retrieve the content and metadata of a Google Doc.

```APIDOC
## GET /v1/documents/{documentId}

### Description
Gets the latest version of the specified document.

### Method
GET

### Endpoint
/v1/documents/{documentId}

### Parameters
#### Path Parameters
- **documentId** (string) - Required - The ID of the document to retrieve.
```

--------------------------------

### Create a working directory

Source: https://developers.google.com/workspace/docs/api/quickstart/go

Create a new directory for your project.

```bash
mkdir quickstart

```

--------------------------------

### Initialize Go module

Source: https://developers.google.com/workspace/docs/api/quickstart/go

Initialize a new Go module for your project.

```bash
go mod init quickstart

```

--------------------------------

### Change to the working directory

Source: https://developers.google.com/workspace/docs/api/quickstart/go

Navigate into the newly created project directory.

```bash
cd quickstart

```

--------------------------------

### Run the Java Sample Application

Source: https://developers.google.com/workspace/docs/api/quickstart/java

Execute this command in your terminal to run the Java sample. The first execution will prompt for authorization.

```bash
gradle run

```