google docs api ReplaceImageRequest best way to get imageObjectId?

Viewed 76

I have created a template document and are processing the template on a node.js service. First I make a copy of the template (using drive api) then I use documents.batchUpdate() to replace {{text-tags}} with real data. However, I am also generating some images on the fly which I need to go in the processed document as well.

Using documents.batchUpdate() I can send a ReplaceImageRequest (documentation) which does exactly what I want. However, I am struggling to find a good way to get or set the imageObjectId.

Here's my template document example (view link): https://docs.google.com/document/d/1KPLqHr1gmN97mJNjmxbQL0i2m1WIaZZ0ww9dsDndqlw/edit?usp=sharing

This is what the document look like:

enter image description here

(the triangle is the supposed to be the placeholder image, the one which I need its' imageObjectId)

Using documents.get({ documentId }) I have inspected the documents data.body.content to be:

[
   {
      "endIndex":1,
      "sectionBreak":{
         "sectionStyle":{
            "columnSeparatorStyle":"NONE",
            "contentDirection":"LEFT_TO_RIGHT",
            "sectionType":"CONTINUOUS"
         }
      }
   },
   {
      "startIndex":1,
      "endIndex":13,
      "paragraph":{
         "elements":[
            {
               "startIndex":1,
               "endIndex":13,
               "textRun":{
                  "content":"Some header\n",
                  "textStyle":{
                     
                  }
               }
            }
         ],
         "paragraphStyle":{
            "headingId":"h.rcwrhpqmmkza",
            "namedStyleType":"HEADING_1",
            "alignment":"CENTER",
            "direction":"LEFT_TO_RIGHT"
         }
      }
   },
   {
      "startIndex":13,
      "endIndex":14,
      "paragraph":{
         "elements":[
            {
               "startIndex":13,
               "endIndex":14,
               "textRun":{
                  "content":"\n",
                  "textStyle":{
                     
                  }
               }
            }
         ],
         "paragraphStyle":{
            "namedStyleType":"NORMAL_TEXT",
            "alignment":"CENTER",
            "direction":"LEFT_TO_RIGHT"
         }
      }
   },
   {
      "startIndex":14,
      "endIndex":29,
      "paragraph":{
         "elements":[
            {
               "startIndex":14,
               "endIndex":29,
               "textRun":{
                  "content":"Some paragraph\n",
                  "textStyle":{
                     
                  }
               }
            }
         ],
         "paragraphStyle":{
            "namedStyleType":"NORMAL_TEXT",
            "alignment":"CENTER",
            "direction":"LEFT_TO_RIGHT"
         }
      }
   },
   {
      "startIndex":29,
      "endIndex":30,
      "paragraph":{
         "elements":[
            {
               "startIndex":29,
               "endIndex":30,
               "textRun":{
                  "content":"\n",
                  "textStyle":{
                     
                  }
               }
            }
         ],
         "paragraphStyle":{
            "namedStyleType":"NORMAL_TEXT",
            "alignment":"CENTER",
            "direction":"LEFT_TO_RIGHT"
         }
      }
   },
   {
      "startIndex":30,
      "endIndex":31,
      "paragraph":{
         "elements":[
            {
               "startIndex":30,
               "endIndex":31,
               "textRun":{
                  "content":"\n",
                  "textStyle":{
                     
                  }
               }
            }
         ],
         "paragraphStyle":{
            "namedStyleType":"NORMAL_TEXT",
            "alignment":"CENTER",
            "direction":"LEFT_TO_RIGHT"
         }
      }
   },
   {
      "startIndex":31,
      "endIndex":33,
      "paragraph":{
         "elements":[
            {
               "startIndex":31,
               "endIndex":32,
               "inlineObjectElement":{
                  "inlineObjectId":"kix.pp3rfsxtvnmt",
                  "textStyle":{
                     
                  }
               }
            },
            {
               "startIndex":32,
               "endIndex":33,
               "textRun":{
                  "content":"\n",
                  "textStyle":{
                     
                  }
               }
            }
         ],
         "paragraphStyle":{
            "namedStyleType":"NORMAL_TEXT",
            "alignment":"CENTER",
            "direction":"LEFT_TO_RIGHT"
         }
      }
   }
]

I interpret it as the element with startIndex: 31 to be the image, although it would have been nice if it would have a property such as "image" like tables does, that would provide a bit more robust way to scrape the document for images.... Anyway, by trial and error I have found out that "inlineObjectId":"kix.pp3rfsxtvnmt" is the imageObjectId.

So my current way of getting the documents images, is be filtering the list of elements and only keep items that has a property on ...inlineObjectElement.inlineObjectId

  const orderedImageElementList = doc.data.body.content.filter(e => !R.isNil(R.path(['paragraph', 'elements', 0, 'inlineObjectElement', 'inlineObjectId'], e)));
  const imageIdList = orderedImageElementList.map(ie => ie.paragraph.elements[0].inlineObjectElement.inlineObjectId);
  const replaceImageRequest = [
    {
      replaceImage: {
        imageObjectId: imageIdList[0],
        uri: imageUrl,
        imageReplaceMethod: 'CENTER_CROP'
      }
    }
  ];

This is IMO not a very ideal way of retrieving the id for a number of reasons. What if the template is edited, and more images are inserted here and there? Then the order of the ids will shift and I will have to change the code. What if other kinds of elements also have property called inlineObjectId structured out in a similar manner? I would end up trying to replace a wrong kind of element with an image and get an error.

I haven't been able to find a way to define the imageObjectId in my template, but ideally I would have the option to manually define the ids with a proper naming, like 'barChartImage123' and use that in my code, so I wouldn't have to scrape and analyze the document content and "guess" which element might be the one I want to replace.

I am hoping that there would be a better way than my current approach.

0 Answers
Related