NodeTips

Smart Stowage: Building a 3D Cargo Digital Twin with Gemini 3

Gists

Abstract

This article details the development of Smart Stowage Optimizer, a web-based digital twin for logistics that bridges the gap between physical safety and artificial intelligence. By integrating Gemini 3 Pro, the system solves the 3D Bin Packing Problem (3DBPP) using advanced spatial reasoning. Built with React 19 and Three.js, the application visualizes physics-aware load stability in real-time, offering a comparative analysis between traditional heuristic algorithms and modern generative AI agents.

Overcoming Tool Space Interference: Bridging Google ADK and A2A SDK via Google Apps Script

Gists

Abstract

This article introduces a Google Apps Script-based Agent2Agent architecture to solve Tool Space Interference. While the provided demonstration utilizes a single server for testing purposes, the architecture is designed for distributed task execution. By running multiple category-specific A2A servers in parallel, users can achieve scalable, high-efficiency agent networks.

Introduction

As the Model Context Protocol (MCP) standardizes LLM connectivity, the Agent2Agent (A2A) paradigm is becoming essential for executing complex, multi-step tasks. However, integrating a high volume of tools often triggers “Tool Space Interference (TSI)"—a phenomenon where verbose metadata saturates context windows and degrades reasoning accuracy. Ref Ref Current industry guidelines suggest a “soft limit” of 20 functions per agent; exceeding this threshold frequently results in hallucinations and logic failures.

Nexus-MCP: A Unified Gateway for Scalable and Deterministic MCP Server Aggregation

Gists

Abstract

Nexus-MCP resolves “Tool Space Interference” in Large Language Models by aggregating multiple MCP servers into a single gateway. Utilizing a strictly deterministic 4-phase workflow—Discovery, Mapping, Schema Verification, and Bridged Execution—it prevents context saturation and tool hallucinations, enabling the use of massive tool ecosystems without sacrificing reasoning accuracy.

Introduction

The integration of Gemini CLI and Google Antigravity with the Model Context Protocol (MCP) has significantly expanded the capabilities of LLM-based agents. However, this expansion introduces a critical performance bottleneck. As the number of available tools grows, Large Language Models (LLMs) suffer from a measurable decline in reasoning accuracy and tool-selection reliability.

Modularizing AI Agents: Integrating Google Apps Script Libraries with Gemini CLI and Antigravity

Gists

Abstract

This article introduces a major update to gas-fakes enabling dynamic loading of Google Apps Script libraries. This enhancement allows developers to build modular, maintainable Model Context Protocol (MCP) servers. We demonstrate this by integrating sophisticated library-based tools with Gemini CLI and Google Antigravity for seamless Google Workspace automation.

Introduction

I recently published an article titled “Power of Google Apps Script: Building MCP Server Tools for Gemini CLI and Google Antigravity in Google Workspace Automation.” In that piece, I demonstrated how to bridge the Model Context Protocol (MCP) with Google Workspace by implementing an MCP server using Google Apps Script (GAS) and gas-fakes. This successfully established a communication channel for sophisticated AI agents—such as the Gemini CLI and Google Antigravity—to interact directly with Workspace data.

Power of Google Apps Script: Building MCP Server Tools for Gemini CLI and Google Antigravity in Google Workspace Automation

Gists

Abstract

This article demonstrates how to build Model Context Protocol (MCP) tools directly using Google Apps Script. By leveraging the gas-fakes CLI, developers can execute Google Apps Script locally to automate Google Workspace via Gemini CLI and Google Antigravity, streamlining development and eliminating the overhead of dynamic tool creation.

Introduction

With the rapid advancement of generative AI, ensuring the security of executing AI-generated scripts is of paramount importance to prevent arbitrary code execution vulnerabilities. Addressing this, I previously published a secure sandbox environment for Google Apps Script (GAS) known as gas-fakes, which emulates the Apps Script environment locally. Ref

A New Era for Google Apps Script: Unlocking the Future of Google Workspace Automation with Natural Language

Gists

Abstract

This article redefines Google Apps Script (GAS) as a central integration hub in the AI era. It introduces the forefront of Google Workspace automation, realized through the fusion of the Model Context Protocol (MCP), Agent2Agent (A2A), and the Gemini CLI ecosystem. I cover everything from data integration bridging local and cloud environments (RAG) and sandbox technologies for safely executing AI-generated GAS, to the coordination of autonomous agents on the newly released Google Antigravity. We will explore next-generation work styles and implementation methods where complex workflows are completed autonomously through simple natural language instructions.

Integrating Google Antigravity: Unlocking the Google Workspace Extension for Gemini CLI

Gists

Abstract

This article demonstrates how to integrate the Google Workspace Extension for Gemini CLI with Google Antigravity. It addresses a Model Context Protocol (MCP) tool naming incompatibility using a custom proxy script, enabling seamless, authenticated automation of Google Workspace tasks directly within the Antigravity IDE environment.

Introduction

Since its release, the Gemini CLI has been rapidly adopted across various development scenarios. Ref Its utility increased significantly with the introduction of Gemini CLI Extensions, which simplify the installation and management of Model Context Protocol (MCP) servers. Ref Most recently, the Google Workspace Extension for Gemini CLI was released by Google, providing an MCP server specifically designed to manage Workspace automation. Ref A distinct advantage of this extension is its streamlined authorization process—authentication runs automatically when the Gemini CLI is launched, making it highly efficient.

Gemini CLI Extension: FileSearchStore-extension

Here introduces a new Gemini CLI extension that integrates File Search feature. This tool establishes a fully managed Retrieval-Augmented Generation (RAG) system directly on the command line.

The extension is designed to simplify the use of the Gemini API’s File Search, a powerful new feature that enables RAG grounded in personal or proprietary knowledge bases. While the underlying API requires scripting, this Node.js-built CLI extension allows users to seamlessly manage File Search stores and generate context-aware content grounded in their private documents without having to leave the terminal interface.

Integrating File Search with the Gemini CLI Extension

Gists

Abstract

This article introduces a Gemini CLI extension that integrates File Search feature. This tool provides a fully managed Retrieval-Augmented Generation (RAG) system directly in your command line, enabling content generation grounded in your private documents and data.

Introduction

The Gemini API recently introduced File Search, a powerful feature that enables Retrieval-Augmented Generation (RAG) using your own documents as a knowledge base. This allows you to generate content grounded in personal or proprietary information. While powerful, leveraging this via API calls requires scripting.

Streamlining Google Apps Script Development with Gemini CLI Extensions and VSCode

Gists

Abstract

This guide explores a powerful, next-level workflow for Google Apps Script (GAS) development by integrating Gemini CLI Extensions with Visual Studio Code (VSCode). This combination streamlines the entire development process, from script creation and local testing in a secure sandbox to deploying and managing projects, all within a unified and efficient environment.

Introduction

Visual Studio Code (VSCode) is widely recognized as a premier source code editor. The release of the Gemini CLI has dramatically transformed script development by bringing advanced AI capabilities directly into the terminal. In particular, combining Gemini CLI with VSCode creates a powerful development ecosystem, highly effective for languages typically executed locally, such as Python, Node.js, Go and so on. Beyond coding, this setup streamlines content creation, including articles and papers, by leveraging AI for drafting and editing. Ref For cloud-based Google Apps Script (GAS) development, the standard approach involves using VSCode alongside Clasp to manage projects locally. Ref Integrating Gemini CLI into this established workflow promises significant synergistic effects. A recent update has further expanded these possibilities by enabling Clasp to function experimentally as a Model Context Protocol (MCP) server, allowing LLMs to directly interact with GAS project structures. Ref Furthermore, to address security concerns when executing AI-generated GAS code, I have introduced a “fake sandbox” environment for safer testing. Ref and Ref With the recent release of Gemini CLI Extensions, which allow for custom AI tools and specialized workflows, combining these assets creates a vastly superior developer environment. In this article, I will introduce next-level Google Apps Script development by leveraging the combined power of Gemini CLI Extensions and VSCode.

A Developer's Guide to Building Gemini CLI Extensions

Gists

Abstract

This guide offers a comprehensive walkthrough of the essential steps and key considerations for developing Gemini CLI extensions. It covers setting up a sample project, configuring the gemini-extension.json file, local testing, and automating dependency management with GitHub Actions, providing developers with the foundational knowledge to create their own custom tools.

Introduction

After the release of Gemini CLI Extensions, a growing community of users is developing a wide range of extensions to enhance their command-line workflows. Ref and Ref This trend is expected to continue and strengthen. As the ecosystem expands, knowing how to develop these extensions becomes increasingly valuable for users who want to create their own custom tools. Many useful articles for understanding Gemini CLI Extensions have already been published. In particular, the articles by Romin Irani are very helpful. Ref In this article, I would like to introduce the core parts I paid attention to when I developed my own extensions (Ref). I hope this article proves useful. As a sample tool in this article, the current time is returned using Node.js.

Gemini CLI Extension: ToolsForMCPServer-extension

ToolsForMCPServer-extension

This Gemini CLI Extension simplifies Google Workspace automation. It installs a local Model Context Protocol (MCP) server that communicates with a powerful, securely authorized backend built on Google Apps Script Web Apps, overcoming previous complex setup and performance bottlenecks.

You can see the details at my repository.

https://github.com/tanaikech/ToolsForMCPServer-extension

Simplified Google Workspace Automation with Gemini CLI Extensions

Gists

Abstract

This project simplifies Google Workspace automation by using a Gemini CLI Extension. It installs a local Model Context Protocol (MCP) server that communicates with a powerful, securely authorized backend built on Google Apps Script Web Apps, overcoming previous complex setup and performance bottlenecks.

Introduction

In order to achieve Google Workspace Automation with seamless authorization and safety, I have published a Model Context Protocol (MCP) server built by Google Apps Script Web Apps. Ref This is very useful because Google Apps Script provides native, secure authorization for Google Workspace APIs like Gmail, Drive, and Calendar. However, there was a bottleneck in the complex installation and a long loading time of the MCP server. Recently, Gemini Extensions have been released. Ref By this, tools and MCP servers can be directly and easily installed from sources like GitHub repositories using a simple command. From this situation, I attempted to implement this simplified installation method on the MCP server built by Google Apps Script Web Apps.

Dynamic Tool Creation for Google Workspace Automation with Gemini CLI

Gists

Abstract

This article presents a method for optimizing Google Workspace automation by dynamically converting frequently used, AI-generated Google Apps Scripts into permanent, reusable tools. By integrating the Gemini CLI with a gas-fakes sandbox via an MCP server, we demonstrate how to securely add and manage these custom tools, reducing operational costs and improving efficiency.

Introduction

When using generative AI to create scripts, ensuring the secure execution of the generated code is critical. This is especially true for applications that manage cloud resources like Google Workspace, where it is paramount to prevent unintended data access or modification. The standard permission model for Google Apps Script often requires broad access, creating a significant security risk when running code from untrusted sources.

A Collaborative Dialogue Between Gemini CLI and Copilot CLI Through MCP

Gists

Abstract

This article introduces a method for integrating Google’s Gemini CLI and GitHub’s Copilot CLI using the Model Context Protocol (MCP). By configuring one CLI as an MCP server, the other can invoke it from a prompt, enabling a powerful, collaborative interaction between the two AI assistants for enhanced development workflows.

Introduction

Recently, GitHub released the Copilot CLI, a command-line interface that brings the power of GitHub Copilot directly to your terminal. It assists with various tasks, including answering questions, writing code, and interacting with GitHub. Concurrently, Google has already introduced the Gemini CLI, an open-source AI agent that integrates the Gemini models into the command line to help developers with coding, problem-solving, and task management.

Secure and Conversational Google Workspace Automation: Integrating Gemini CLI with a gas-fakes MCP Server

Gists

Abstract

This article introduces a method for securely executing AI-generated Google Apps Script. By implementing a “fake-sandbox” using the gas-fakes library as an MCP server, users can empower the Gemini CLI to safely automate Google Workspace tasks with granular, file-specific permissions, avoiding significant security risks.

Introduction

“Have you ever faced a task that isn’t part of your routine but is tedious to do manually, like, ‘I need to add a “[For Review]” prefix to the titles of all Google Docs in a specific folder this afternoon’? Or perhaps you’ve thought, ‘I want to use AI to work with my spreadsheets, but I’m concerned about the security implications of granting a tool full access to my Google Drive’?

Accelerating Gemini CLI: A Node.js Wrapper for Google Apps Script MCP Servers

Gists

Abstract

This article introduces a Node.js wrapper that dramatically reduces the startup time for the Gemini CLI when used with MCP servers built on Google Apps Script. This optimization enhances user experience by accelerating the initialization process, achieving a speed boost of approximately 15 times.

1. Introduction

The Model Context Protocol (MCP) is a vital open standard enabling AI agents to connect with external tools and data sources for complex, real-world tasks. To integrate the Gemini AI agent with Google Workspace, I developed two open-source tools: MCPApp, for managing the MCP server lifecycle, and ToolsForMCPServer, a suite of tools for interacting with services like Gmail and Drive. These are built with Google Apps Script for use with the Gemini CLI.

A Fake-Sandbox for Google Apps Script: A Feasibility Study on Securely Executing Code Generated by Gemini CLI

Gists

Abstract

Generating Google Apps Script (GAS) with Gemini CLI from natural language introduces security risks due to broad permissions. This report investigates a “Fake-Sandbox” using the gas-fakes library, translating GAS calls into granularly-scoped API requests to securely execute scripts created from user prompts.

Introduction

1. Background: Generative AI and the Challenge of Secure Script Execution

The emergence of Generative AI now makes it possible to generate executable scripts directly from natural language instructions, particularly through interfaces like the Gemini CLI. For locally executable languages such as JavaScript (Node.js) and Python, code generated from a simple prompt can be run directly. However, Google Apps Script (GAS) presents a unique challenge as it operates within Google’s server-side infrastructure. Executing locally generated GAS code requires the remote invocation of a server-side function via the scripts.run method of the Apps Script API. This process highlights the critical need for a sandbox environment to manage permissions effectively and mitigate the risks associated with executing code generated from natural language, which can sometimes produce unintended or insecure outcomes.

A Practical Analysis of the Gemini API's URL Context Tool

Gists

Introduction

The Gemini API recently introduced the URL context tool, a feature designed to allow the model to directly fetch and utilize content from specified URLs to ground its responses. Ref

This report provides a practical demonstration of this tool’s capabilities. We will investigate its impact on two critical aspects of AI model interaction: the accuracy of the generated response and the total token consumption, which directly affects API costs.

Gemini API with JSON schema

Gists

Overview

These are sample scripts in Python and Node.js for controlling the output format of the Gemini API using JSON schemas.

Description

In a previous report, “Taming the Wild Output: Effective Control of Gemini API Response Formats with response_mime_type,” I presented sample scripts created with Google Apps Script. Ref Following its publication, I received requests for sample scripts using Python and Node.js. This report addresses those requests by providing sample scripts in both languages.

Executing Google Apps Script with Service Account

Gists

Abstract

One day, you might have a situation where it is required to run Google Apps Script using the service account. Unfortunately, in the current stage, Google Apps Script cannot be directly run with the service account because of the current specification. So, this report introduces a workaround for executing Google Apps Script using the service account.

Introduction

When you want to execute Google Apps Script from outside of Google, as the basic approach, it can be achieved by Google Apps Script API. Ref In order to use Google Apps Script, it is required to link the Google Apps Script project with the Google Cloud Platform project. Ref But, in the current stage, Google Apps Script can be executed by Google Apps Script API with only the access token obtained from OAuth2. Unfortunately, the access token obtained by the service account cannot used for executing Google Apps Script using Google Apps Script API. It seems that this is the current specification on the Google side. However, there might be a case that it is required to execute Google Apps Script using the service account. In this report, I would like to introduce a workaround for executing Google Apps Script using the service account. In this workaround, the Web Apps created by Google Apps Script is used. The Web Apps can be used for executing the preserved functions of doGet and doPost from outside of Google. Ref In this workaround, this Web Apps is used for executing the various functions.

Creating and Deleting Multiple Events in Google Calendar by Batch Requests using Calendar API with Node.js

Gists

These are the sample scripts for creating and deleting multiple events in Google Calendar by batch requests using Calendar API with Node.js.

In the current stage, unfortunately, googleapis for Node.js cannot request batch requests. Ref So, when multiple events are created and deleted in Google Calendar using Node.js, it is required to run the script in a loop. In this case, the process cost becomes high. Ref In this post, I would like to introduce creating and deleting multiple events in Google Calendar using batch request with Node.js.

node module - node-gbatchrequests

Overview

This is a Node.js module to run the batch requests of Google APIs.

Description

In Google APIs, there are APIs where batch requests can be run. The batch requests can run multiple API calls by one API call with the asynchronous process. By this, both the process cost and the quota cost can be reduced. Ref In Node.js, the wonderful module of googleapis for Node.js is existing. But, in the current stage, unfortunately, it seems that the googleapis for Node.js cannot run the batch requests. Ref So, I created this module. This module can achieve batch requests with Node.js. In order to run batch requests, the access token retrieved from googleapis for Node.js can be used.

Updating Array1 with Array2 using Google Apps Script

Gists

This is a sample script for updating Array1 with Array2 using Google Apps Script.

As a sample situation, there are 2 arrays (Array1 and Array2) of the 2-dimensional array. The sample situation can be seen in the above sample Spreadsheet.

  • Conditions
    • When the values of column “A” of Array2 are existing in column “A” of Array1, the rows of Array1 are updated by that of Array2.
    • When the values of column “A” of Array2 are not existing in column “A” of Array1, the rows of Array2 are appended to Array1.
    • When the values of column “A” of Array1 are not existing in column “A” of Array2, the rows of Array1 are deleted.

I sometimes see such questions on Stackoverflow. So, I thought that when this sample script is posted, it might be useful for users.

Sample Script for Resumable Upload to Google Drive using Axios with Node.js

Gists

This is a sample script for the resumable upload using Axios with Node.js.

Sample script

In this sample script, as a sample situation in order to explain the resumable upload, the file data is loaded from the local PC, and the data is uploaded to Google Drive with the resumable upload.

const axios = require("axios");
const fs = require("fs").promises;

async function sample() {
  const filepath = "./###"; // Please set the filename and file path of the upload file.

  const new_access_token = "###"; // Please set your access token.
  const name = "###"; // Please set the filename on Google Drive.
  const mimeType = "###"; // Please set the mimeType of the uploading file. I thought that when this might not be required to be used.

  // 1. Prepare chunks from loaded file data.
  const split = 262144; // This is a sample chunk size.
  const data = await fs.readFile(filepath);
  const fileSize = data.length;
  const array = [...new Int8Array(data)];
  const chunks = [...Array(Math.ceil(array.length / split))].map((_) =>
    Buffer.from(new Int8Array(array.splice(0, split)))
  );

  // 2. Retrieve endpoint for uploading a file.
  const res1 = await axios({
    method: "POST",
    url: "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable",
    headers: {
      Authorization: `Bearer ${new_access_token}`,
      "Content-Type": "application/json",
    },
    data: JSON.stringify({ name, mimeType }),
  });
  const { location } = res1.headers;

  // 3. Upload the data using chunks.
  let start = 0;
  for (let i = 0; i < chunks.length; i++) {
    const end = start + chunks[i].length - 1;
    const res2 = await axios({
      method: "PUT",
      url: location,
      headers: { "Content-Range": `bytes ${start}-${end}/${fileSize}` },
      data: chunks[i],
    }).catch(({ response }) =>
      console.log({ status: response.status, message: response.data })
    );
    start = end + 1;
    if (res2?.data) console.log(res2?.data);
  }
}

sample();

Testing

When this sample script is run, the following result is obtained.

Converting A1Notation to GridRange and vice versa using Google Apps Script without any Scopes

Gists

This is a sample script for converting A1Notation to GridRange and vice versa using Google Apps Script without any scopes.

A1Notation and GridRange are often used with Sheets API. I have posted a sample script for converting A1Notation to GridRange before. Ref But, in that case, I used the method of Spreadsheet service (SpreadsheetApp). By this, in order to use the script, it is required to authorize the scopes. In this sample script, A1Notation can be converted to GridRange and vice versa with no scopes. Also, this sample script can be used for Javascript and Node.js.

Simple Script of Resumable Upload with Google Drive API for Axios

Gists

This is a simple sample script for achieving the resumable upload to Google Drive using Axios. In order to achieve the resumable upload, at first, it is required to retrieve the location, which is the endpoint of upload. The location is included in the response headers. After the location was retrieved, the file can be uploaded to the location URL.

In this sample, a text data is uploaded with the resumable upload using a single chunk.

Downloading and Uploading File to Google Drive without Saving File with Stream and Resumable Upload using Node.js

Gists

This is a sample script of Node.js for downloading the data and uploading the data to Google Drive with the resumable upload without saving it as a file. The downloaded data is uploaded to Google Drive with the stream.

Sample script

Before you use this, please set the variables of accessToken, url, fileSize, mimeType and filename. In this case, fileSize is required to set because the data is uploaded with the resumable upload.

Sample Scripts for Creating New Event with Google Meet Link to Google Calendar using Various Languages

Gists

This is the sample scripts for creating new event with Google Meet link to Google Calendar using various languages. When I saw the official document of “Add video and phone conferences to events”, in the current stage, I can see only the sample script for Javascript. But I saw the several questions related to this for various languages. So I published the sample scripts for creating new event with Google Meet link to Google Calendar using various languages.

Retrieving All Values from All Sheets from URL of 2PACX- of Web Published Google Spreadsheet using Node.js

Gists

This is a sample script for retrieving all values from all sheets from URL of 2PACX- of Web Published Google Spreadsheet using Node.js.

In this post, it supposes that the Google Spreadsheet has already been published for Web. Ref

Before you use this sample script, please install SheetJS js-xlsx.

Flow

The flow of this method is as follows.

  1. Retrieve XLSX data from the URL of web published Google Spreadsheet as the buffer data.
    • The URL is like https://docs.google.com/spreadsheets/d/e/2PACX-###/pubhtml.
  2. XLSX data is parsed with SheetJS js-xlsx.
  3. Retrieve all values from all sheets.

Sample script

Please set spreadsheetUrl.

Uploading Files of multipart/form-data to Google Drive using Drive API with Node.js

Gists

These are the sample scripts for uploading files of multipart/form-data to Google Drive using Drive API with Node.js. In this case, googleapis for Node.js is not used.

In these sample script, the maximum file size is 5 MB. Please be careful this. When you want to upload the files more than 5 MB, please check this report.

Sample script 1

This sample script uploads a file using the modules of fs and request. Before you use this script, please prepare your access token for uploading the file.

Retrieving Difference Between 2 Arrays using Google Apps Script

Gists

This is a sample script for retrieving the difference between 2 arrays, which are the old values and the new values, using Google Apps Script. In my environment, I sometimes have the situation that it is required to retrieve the difference between 2 arrays. So I prepared this as a sample script. I think that this can be also used at Javascript and Node.js. If this was also useful for your situation, I’m glad.

Updated: GetFileList for golang, Javascript, Node.js and Python

Updated: GetFileList for golang, Javascript, Node.js and Python

This is the libraries to retrieve the file list with the folder tree from the specific folder of own Google Drive and shared Drives.

Updated: node module - google-drive-getfilelist

node module - google-drive-getfilelist was updated to v1.0.4

  • v1.0.4 (May 14, 2020)

    1. Shared drive got to be able to be used. The file list can be retrieved from both your Google Drive and the shared drive.

      • For example, when the folder ID in the shared Drive is used id of resource, you can retrieve the file list from the folder in the shared Drive.

You can get this from https://github.com/tanaikech/node-getfilelist

You can also get this from https://www.npmjs.com/package/google-drive-getfilelist

Simple Script of Resumable Upload with Google Drive API for Node.js

Gists

This is a simple sample script for achieving the resumable upload to Google Drive using Node.js. In order to achieve the resumable upload, at first, it is required to retrieve the location, which is the endpoint of upload. The location is included in the response headers. After the location was retrieved, the file can be uploaded to the location URL.

In this sample, a PNG file is uploaded with the resumable upload using a single chunk.

Libraries of gdoctableapp for golang, Node.js and python were updated to v110

Libraries of gdoctableapp for golang, Node.js and python were updated to v1.1.0

Libraries of gdoctableapp for golang, Node.js and python were updated to v105

Libraries of gdoctableapp for golang, Node.js and python were updated to v1.0.5

Update History

  • v1.0.5 (January 21, 2020)

    • When the inline objects and tables are put in the table. An error occurred. This bug was removed by this update.
  • I got the pull request at here.

Music Streaming Player for Discord with Google Drive using Node.js

Gists

Overview

This is a sample script for the music streaming player for Discord with Google Drive using Node.js.

Description

This sample script can achieve to play the music when uses the voice channel on Discord. The music files are put in the specific folder of Google Drive. This script downloads all music files and plays the music files at the voice channel with the stream.

Usage

1. Register BOT to Discord

At first, please register your BOT to Discord. And please retrieve the token.

Creating a Table to Google Document by Retrieving Values from Google Spreadsheet for Node.js

Gists

This is a sample script for creating a table to Google Document by retrieving values from Google Spreadsheet for Node.js.

Before you use this script, please install Node.js module of node-gdoctableapp.

$ npm install --save-dev gdoctableapp

or

$ npm install --global gdoctableapp

Sample script:

This sample script uses Service Account.

In this sample script, the values are retrieved from Sheet1!A1:C5 of Spreadsheet, and new table is created to the Document using the values.

node module - node-gdoctableapp

Overview

This is a Node.js module to manage the tables on Google Document using Google Docs API.

Description

Google Docs API has been released. When I used this API, I found that it is very difficult for me to manage the tables on Google Document using Google Docs API. Although I checked the official document, unfortunately, I thought that it’s very difficult for me. So in order to easily manage the tables on Google Document, I created this library.

Retrieving Access Token using Service Account for Node.js without using googleapis

Gists

This is a sample Node.js script to retrieve access token from Service Account of Google without using googleapis.

const cryptor = require('crypto');
const request = require('request');

const privateKey = "###"; // private_key of JSON file retrieved by creating Service Account
const clientEmail = "###"; // client_email of JSON file retrieved by creating Service Account
const scopes = ["https://www.googleapis.com/auth/drive.readonly"]; // Sample scope

const url = "https://www.googleapis.com/oauth2/v4/token";
const header = {
  alg: "RS256",
  typ: "JWT",
};
const now = Math.floor(Date.now() / 1000);
const claim = {
  iss: clientEmail,
  scope: scopes.join(" "),
  aud: url,
  exp: (now + 3600).toString(),
  iat: now.toString(),
};

const signature = Buffer.from(JSON.stringify(header)).toString('base64') + "." + Buffer.from(JSON.stringify(claim)).toString('base64');

var sign = cryptor.createSign('RSA-SHA256');
sign.update(signature);
const jwt = signature + "." + sign.sign(privateKey, 'base64');

request({
  method: "post",
  url: url,
  body: JSON.stringify({
    assertion: jwt,
    grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
  }),
}, (err, res, body) => {
  if (err) {
    console.log(err);
    return;
  }
  console.log(body);
});

Creating New Google Docs and Overwriting Existing Google Docs by Text with Node.js without using googleapis

Gists

There are 2 sample scripts.

  1. Create new Spreadsheet using a text value as CSV data.
  2. Overwrite the existing Google Document using a text value.

When you use these script, please enable Drive API and retrieve your access token.

Create New Spreadsheet using Text Value

const request = require('request');

const textData = "a1, b1, c1, d1, e1"; // This is used as CSV data.
const orgMimeType = "text/csv";
const orgFileName = "sample.csv";
const accessToken = "###"; // Access token
const metadata = {
  name: "convertedSampleCSV",
  mimeType: "application/vnd.google-apps.spreadsheet",
};

const url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart";
const boundary = "xxxxxxxxxxx";
var data = "--" + boundary + "\r\n";
  data += "Content-Disposition: form-data; name=\"metadata\"\r\n";
  data += "Content-Type: application/json; charset=UTF-8\r\n\r\n";
  data += JSON.stringify(metadata) + "\r\n";
  data += "--" + boundary + "\r\n";
  data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + orgFileName + "\"\r\n";
  data += "Content-Type: " + orgMimeType + "\r\n\r\n";

var payload = Buffer.concat([
  Buffer.from(data, "utf8"),
  new Buffer(textData, 'binary'),
  Buffer.from("\r\n--" + boundary + "--", "utf8"),
]);

const options = {
  method: 'post',
  url: url,
  headers: {
    "Content-Type": "multipart/related; boundary=" + boundary,
    'Authorization': 'Bearer ' + accessToken,
  },
  body: payload,
};
request(options, (error, response, body) => {
  console.log(body);
});

Overwrite Existing Google Document using Text Value

This can be used when you don’t want to update the existing Google Docs without changing the file ID.

Sample Script for Executing with Synchronous Process using Node.js

Gists

This is a sample script for executing with the synchronous process using Node.js.

Sample script

function work(e) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(e);
            resolve("ok" + e);
        }, 1000);
    });
}

async function main() {
    var ar = [1, 2, 3, 4, 5];
    for (var i = 0; i < ar.length; i++) {
        console.log('start' + ar[i]);
        await work(ar[i]).then((res) => console.log(res));
        console.log('end' + ar[i]);
    }
}

main(); // Run main().

Result

start1
1
ok1
end1
start2
2
ok2
end2
start3
3
ok3
end3
start4
4
ok4
end4
start5
5
ok5
end5

Directly Using Access Token by googleapis for Node.js

Gists

This sample script is for directly using the refreshed access token by googleapis for Node.js. When oauth2Client.refreshAccessToken((err, tokens) => {}); is used to retrieve the refreshed access token, the following error occurs.

DeprecationWarning: The refreshAccess Token method has been deprecated, and will be removed in the 3.0 release of goo gle-auth-library. Please use the getRequestHeaders method instead.

It is required to use getRequestHeaders(). But I couldn’t find the sample script using getRequestHeaders(). So I created this sample script. If this was useful for you, I’m glad.

node module - google-drive-getfilelist

Overview

This is a Node.js module to retrieve the file list with the folder tree from the specific folder of Google Drive.

Description

When I create applications for using Google Drive, I often retrieve a file list from a folder in the application. So far, I had created the script for retrieving a file list from a folder for each application. Recently, I thought that if there is the script for retrieving the file list with the folder tree from the folder of Google Drive as a module, it will be useful for me and other users. So I created this.

Create Folder Tree of Google Drive using Node.js

Gists

This is a sample script for retrieving a folder tree using Node.js. In this sample, you can set the top of folder for the folder tree. In generally, the folder tree is created by retrieving folders from the top folder in order. For example, when Google Apps Script is used, the script becomes like this. But when Drive API is used for this situation, if there are a lot of folders in the top folder, a lot of APIs are required to be called. So in this sample, I have tried to create the folder tree by a small number of API calls as possible.

Send mails from Gmail using Nodemailer

Gists

This is a sample script for sending e-mails from gmail using Nodemailer. In order to use this, please retrieve the folloing parameters before run this script.

  1. gmail address
  2. client ID
  3. client Secret
  4. Refresh token
    • Please include https://mail.google.com/ in the scope.
  5. Enable gmail API at API console.
  6. Install Nodemailer
const nodemailer = require('nodemailer');

var auth = {
    type: 'oauth2',
    user: '### your gmail address ###',
    clientId: '### client ID ###',
    clientSecret: '### client secret ###',
    refreshToken: '### refresh token ###',
};

var mailOptions = {
    from: '#####',
    to: '#####',
    subject: 'sample subject',
    text: 'sample text',
    html: '<b>sample html</b>',
};

var transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: auth,
});

transporter.sendMail(mailOptions, (err, res) => {
    if (err) {
        return console.log(err);
    } else {
        console.log(JSON.stringify(res));
    }
});

Reference :

Downloading Files Under Specific Folder using Node.js

Gists

This sample script is for downloading files under a specific folder using Node.js. It can download files with Google Docs and others.

This sample supposes as follows. So please confirm it.

  • quickstart is used and default quickstart works fine.

In order to use this sample, please carry out as follows.

  1. Replace listFiles() of the default quickstart to this sample.
  2. Set folderid. This script can retrieve files in the folder with folderid.
  3. Delete drive-nodejs-quickstart.json. I think that there is the file at .credentials in your home directory.
  4. Change the SCOPE from var SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']; to var SCOPES = ['https://www.googleapis.com/auth/drive.readonly'];.
  5. Run script, retrieve the code and authorize.

Script :

function listFiles(auth) {
  var folderid = "### folder ID ###"; // Folder ID. This script downloads files in the folder with this folder ID.
  var outputExtension = "pdf"; // Extension of output file. This is adapted to only Google Docs.

  var outputMimeType = mime.lookup(outputExtension);
  var service = google.drive('v3');
  service.files.list({
    auth: auth,
    q: "'" + folderid + "' in parents and trashed=false",
    fields: "files(id, name, mimeType)"
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    response.files.forEach(function(e){
      if (e.mimeType.includes("application/vnd.google-apps")) {
        var dlfile = fs.createWriteStream(e.name + "." + outputExtension);
        service.files.export({
          auth: auth,
          fileId: e.id,
          mimeType: outputMimeType
        }).on('end', function() {
          console.log("'%s' was downloaded as %s.", e.name, outputExtension);
        }).on('error', function(err) {
          console.error(err);
          return process.exit();
        }).pipe(dlfile);
      } else {
        var dlfile = fs.createWriteStream(e.name);
        service.files.get({
          auth: auth,
          fileId: e.id,
          alt: 'media'
        }).on('end', function() {
          console.log("'%s' was downloaded as %s.", e.name, mime.extension(e.mimeType));
        }).on('error', function(err) {
          console.error(err);
          return process.exit();
        }).pipe(dlfile);
      }
    });
  });
}

Uploading Files to OneDrive Using Node.js

Gists

Upload contents for an item on OneDrive

In order to use this script, please retrieve client id, client secret and refresh token before. About this, you can see the detail information at https://gist.github.com/tanaikech/d9674f0ead7e3320c5e3184f5d1b05cc.

1. Simple item upload

This is for the simple item upload is available for items with less than 4 MB of content. The detail information is https://dev.onedrive.com/items/upload_put.htm.

var fs = require('fs');
var mime = require('mime');
var request = require('request');

var file = './sample.zip'; // Filename you want to upload on your local PC
var onedrive_folder = 'SampleFolder'; // Folder name on OneDrive
var onedrive_filename = 'sample.zip'; // Filename on OneDrive

request.post({
    url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
    form: {
        redirect_uri: 'http://localhost/dashboard',
        client_id: onedrive_client_id,
        client_secret: onedrive_client_secret,
        refresh_token: onedrive_refresh_token,
        grant_type: 'refresh_token'
    },
}, function(error, response, body) {
    fs.readFile(file, function read(e, f) {
        request.put({
            url: 'https://graph.microsoft.com/v1.0/drive/root:/' + onedrive_folder + '/' + onedrive_filename + ':/content',
            headers: {
                'Authorization': "Bearer " + JSON.parse(body).access_token,
                'Content-Type': mime.getType(file), // When you use old version, please modify this to "mime.lookup(file)",
            },
            body: f,
        }, function(er, re, bo) {
            console.log(bo);
        });
    });
});

2. Resumable item upload

This is for the resumable item upload is provided for large files or when a resumable transfer may be necessary. The detail information is https://dev.onedrive.com/items/upload_large_files.htm.