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:
(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.
