anomaly
anomaly

Reputation: 23

Drive API - Update/Create Google Doc from a string - Node.js

I am using Drive API v3 (Node.js), to create a Google Doc with some data. Later, I also want to have the possibility of "appending" new data to the existing Google Doc.

I have written the following code to create a new Google Doc in a certain folder:

          var content = "Content to be written in file"
          var fileMetadata = {
            name: filename,
            parents: [rootFolderId]
          };
          var media = {
            mimeType: 'application/vnd.google-apps.document',
            body: content  // In the form of string
          };
          drive.files.create({
            resource: fileMetadata,
            multipart: media,
            fields: 'id', 
          })
          .then(function (response) {
              // Handle the response
              console.log(response.data.name, "File created")
            },
            function (err) {
              console.error(err);
          })

My question is, how can I create the Doc, and initialise it with a string? I want it to be readable on Drive. Right now, a binary file is getting created, with 'No preview available'.

Also, I want to have a function to update this doc (append) with a string. Like this:

         var media = {
            mimeType: 'application/vnd.google-apps.document',
            body: content_to_be_appended // in the form of string
          };
         drive.files.update({
            fileId: existingDocID,
            resource: fileMetadata,
            multipart: media,
            fields: 'id, name'
          })

Any help would be greatly appreciated! Thanks!

Upvotes: 1

Views: 1546

Answers (2)

aryzing
aryzing

Reputation: 5867

From the Media Uploads example for [email protected], you can create a Google Document with a given title and content inside a given folder with

const drive = google.drive({ version: 'v3', auth });

const filename = '<filename>';
const parentFolderId = '<parent-folder-id>';
const content = '<file-content>';

const requestBody = {
  name: filename,
  parents: [parentFolderId],
  mimeType: 'application/vnd.google-apps.document',
};
const media = {
  mimeType: 'text/plain',
  body: content,
};

await drive.files.create({
  requestBody,
  media,
  fields: 'id',
});

To perform modifications on the document, best use the Docs API. It offers fine control over the document modifications.

If you're looking for a simple solution to update a Google Document's content using the Drive API, a slightly coarser approach to using the Docs API is

drive = google.drive({ version: 'v3', auth });

const fileId = '<file-id>';
const newContent = '<new content>';
const media = {
  mimeType: 'text/plain',
  body: newContent,
};

await drive.files.update({
  fileId,
  media,
});

For appending text to a document using the Drive API, you can use something along the lines of

const drive = google.drive({ version: 'v3', auth });

const fileId = '<file-id>';
const contentToAppend = '<new content>';

const { data: prevContent } = await drive.files.export({
  fileId,
  mimeType: 'text/plain',
});

const newContent = prevContent + contentToAppend;

const media = {
  mimeType: 'text/plain',
  body: newContent,
};

await drive.files.update({
  fileId,
  media,
});

Upvotes: 0

Tanaike
Tanaike

Reputation: 201428

I believe your goal as follows.

  • Your question has the following 2 questions.
    1. You want to know the method for creating new Google Document including the text data.
    2. You want to know the method for adding more text data to the existing Google Document.
  • You want to achieve this using Drive API with googleapis for Node.js.
  • You have already been able to get and put the file using Drive API.

Answer for question 1:

In this answer, new Google Document is created by including the text data using Drive API.

Modification points:

  • In this case, it is required to convert the text to the stream type.
  • When the text is converted to Google Document, mimeType is required to be included in fileMetadata.

When above points are reflected to your script, it becomes as follows.

Modified script:

From:
var content = "Content to be written in file"
var fileMetadata = {
  name: filename,
  parents: [rootFolderId]
};
var media = {
  mimeType: 'application/vnd.google-apps.document',
  body: content  // In the form of string
};
To:
const stream = require("stream");

var filename = "sample filename";  // Please set the filename of created Google Document.
var rootFolderId = "root";  // Please set the folder ID.
var content = "Content to be written in file";

var bufferStream = new stream.PassThrough();
bufferStream.end(Uint8Array.from(Buffer.from(content, "binary")));
var fileMetadata = {
  name: filename,
  parents: [rootFolderId],
  mimeType: "application/vnd.google-apps.document",
};
var media = {
  mimeType: "text/plain",  // <--- Added
  body: bufferStream
};
  • In this case, stream module is used.

Answer for question 2:

In this answer, more text data is added to the existing Google Document using Drive API.

Modification points:

  • In this case, it is required to do the following flow.
    1. Retrieve all texts data from the existing Google Document.
    2. Add more text data to the retrieved texts.
    3. Update the existing Google Document using the updated text data.
      • In this case, the method of "Files: update" in Drive API is used.

The sample script is as follows.

Sample script:

const documentId = "###"; // Please set the Google Document ID of the existing Google Document.
drive.files.export(
  {
    fileId: documentId,
    mimeType: "text/plain",
  },
  { responseType: "stream" },
  (err, { data }) => {
    if (err) {
      console.log(err);
      return;
    }
    let buf = [];
    data.on("data", (e) => buf.push(e));
    data.on("end", () => {
      const stream = require("stream");

      const content = "\n" + "Added text data";  // Here, the text data is added to the existing text in Document.

      buf.push(Buffer.from(content, "binary"));
      const bufferStream = new stream.PassThrough();
      bufferStream.end(Uint8Array.from(Buffer.concat(buf)));
      var media = {
        body: bufferStream,
      };
      drive.files.update(
        {
          fileId: documentId,
          resource: {},
          media: media,
          fields: "id",
        },
        function (err, file) {
          if (err) {
            console.error(err);
            return;
          }
          console.log(file.data.id);
        }
      );
    });
  }
);
  • In this sample script, I used const content = "\n" + "Added text data"; for adding more text data. If you don't want to insert the line break for this, please remove "\n".

Note:

  • In order to add more text data, I think that you can also use Docs API. But in your goal, Drive API is used. So I proposed the method for using Drive API.

References:

Upvotes: 2

Related Questions