I'm trying to insert a page break before certain text.
I tried the solution in this post: Replace a text keyword with a "Page Break" element in Apps Script
Which adds the page break after the text, played around with the code and couldn't get it to add it before. As a workaround I was trying to append a paragraph text after I append the page Break, but couldn't get it work.
I believe your goal as follows.
You want to insert the pagebreak before a text word in Google Document using Google Apps Script.
In this case, I would like to propose the following sample script using Google Docs API. At Google Docs API, the page can be inserted to the middle of text using index. So I thought that this direction might be a bit simple and the process cost might be able to be also reduced. The flow of this script is as follows.
Retrieve all contents from Google Document using the method of "documents.get" in Docs API.
Create the request body for using the method of "documents.batchUpdate" in Docs API.
Request the request body to the method of "documents.batchUpdate" in Docs API.
Sample script:
Please copy and paste the following script to the script editor of Google Document, and please set searchPattern. And, please enable Google Docs API at Advanced Google services.
function myFunction() {
const searchText = "{{page break}}"; // Please set text. This script inserts the pagebreak before this text.
// 1. Retrieve all contents from Google Document using the method of "documents.get" in Docs API.
const docId = DocumentApp.getActiveDocument().getId();
const res = Docs.Documents.get(docId);
// 2. Create the request body for using the method of "documents.batchUpdate" in Docs API.
let offset = 0;
const requests = res.body.content.reduce((ar, e) => {
if (e.paragraph) {
e.paragraph.elements.forEach(f => {
if (f.textRun) {
const re = new RegExp(searchText, "g");
let p = null;
while (p = re.exec(f.textRun.content)) {
ar.push({insertPageBreak: {location: {index: p.index + offset}}});
}
}
})
}
offset = e.endIndex;
return ar;
}, []).reverse();
// 3. Request the request body to the method of "documents.batchUpdate" in Docs API.
Docs.Documents.batchUpdate({requests: requests}, docId);
}
In this sample script, const searchPattern = "{{page break}}" is used as the text for inserting the pagebreak. Please modify this for your actual situation.
Result:
When above script is run, the following result is obtained.
From:
To:
References:
Method: documents.get
Method: documents.batchUpdate
InsertPageBreakRequest
Added:
I confirmed that google-docs-api is also included in your tags of your question. So I proposed a sample script for using Google Docs API. But from your following replying, it seems that you wanted to use Google Docs API without enabling Google Docs API at Advanced Google services. I couldn't notice about this from your question and tags.
is there a way of doing this without having to enable the Google Docs API in the Apps Script environment? I get a Reference Error for Docs.Documents.get(docId) if I don't.
About your replying, I add one more sample script. In this sample script, Google Docs API is used with UrlFetchApp. So Google Docs API of Advanced Google services is not used. But, in this case, Google Docs API is required to be enabled at API console. So I propose 2 patterns for this.
Please link GCP to GAS project and enable Google Docs API at API console.
Please enable Google Docs API at Advanced Google services once and save the GAS project. Here, please wait for minutes. And then, please disable Google Docs API at Advanced Google services. In the current stage, it seems that even when Google Docs API is disabled at Advanced Google services, Google Docs API is not disabled at API console. But I'm not sure whether this is the permanent situation. But, now, I thought that this might be able to be used for this your situation.
Sample script:
Before you use this script, please enable Google Docs API at API console by doing one of them as I proposed above and run the script.
function myFunction() {
const searchText = "{{page break}}"; // Please set text. This script inserts the pagebreak before this text.
// 1. Retrieve all contents from Google Document using the method of "documents.get" in Docs API.
const accessToken = ScriptApp.getOAuthToken();
const docId = DocumentApp.getActiveDocument().getId();
const url1 = "https://docs.googleapis.com/v1/documents/" + docId;
const response1 = UrlFetchApp.fetch(url1, {headers: {authorization: "Bearer " + accessToken}});
const res = JSON.parse(response1.getContentText());
// 2. Create the request body for using the method of "documents.batchUpdate" in Docs API.
let offset = 0;
const requests = res.body.content.reduce((ar, e) => {
if (e.paragraph) {
e.paragraph.elements.forEach(f => {
if (f.textRun) {
const re = new RegExp(searchText, "g");
let p = null;
while (p = re.exec(f.textRun.content)) {
ar.push({insertPageBreak: {location: {index: p.index + offset}}});
}
}
})
}
offset = e.endIndex;
return ar;
}, []).reverse();
// 3. Request the request body to the method of "documents.batchUpdate" in Docs API.
const url2 = `https://docs.googleapis.com/v1/documents/${docId}:batchUpdate`;
UrlFetchApp.fetch(url2, {method: "post", payload: JSON.stringify({requests: requests}), contentType: "application/json", headers: {authorization: "Bearer " + accessToken}});
// DocumentApp.getActiveDocument(); // This is used for automatically adding a scope of https://www.googleapis.com/auth/documents by the script editor.
}
Note:
When an error related to Google Docs API occurs, please enable Google Docs API at API console again.
Related
In my google sheet I have some data in it. Later I published my sheet as .csv format.
Pls find my sheet here, below are the Cell Values
C1 = tdsyltt = 'ఈరోజు ( బుధవారం ) క్విజ్ సిలబస్' ;
C2 = tdsyl = 'హబక్కూకు 1 & యాకోబు 2, 3' ;
C4 = document.getElementById("tdsyltt).innerHTML = tdsyltt ;
C5 = document.getElementById("tdsyl").innerHTML = tdsyl ;
And using my published URL I have developed a web app
code.gs
const doGet = _ => ContentService.createTextOutput(UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/e/2PACX-1vReY-tDEwKYjTiSjsfAN42qjFUwMv_OD3_64bFdGrgL-2p3otc13elLcCq3pkb5xqhTA-bW3QXobpqh/pub?gid=1861615717&single=true&range=c1:c5&output=csv").getContentText()).setMimeType(ContentService.MimeType.JAVASCRIPT);
In the web app output 1st line is ok,
but for 2nd, 3rd and 4th line there are Extra 2 Apostrophes coming at the starting and ending of the lines.
Here is My Web App
How to fix this ..?
Modification points:
In this case, how about directly retrieving the values from Spreadsheet using Spreadsheet service instead of UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/e/2PACX-1vReY-tDEwKYjTiSjsfAN42qjFUwMv_OD3_64bFdGrgL-2p3otc13elLcCq3pkb5xqhTA-bW3QXobpqh/pub?gid=1861615717&single=true&range=c1:c5&output=csv").getContentText()? I thought that the reason of your current issue might be due to exporting the Spreadsheet as CSV data. When the Spreadsheet service is used, the values can be retrieved.
In your previous question, I said "In this answer, your Spreadsheet is used. Of course, you can directly set the script in Web Apps.". Ref In your this question, I thought that this can be used.
In your sample Spreadsheet, document.getElementById("tdsyltt).innerHTML = tdsyltt ; is required to be document.getElementById("tdsyltt").innerHTML = tdsyltt ;. Please be careful about this.
When these points are reflected in your script, how about the following modification?
Modified script:
const doGet = _ => {
const spreadsheetId = "###"; // Please set your Spreadsheet ID.
const ss = SpreadsheetApp.openById(spreadsheetId);
const sheet = ss.getSheetByName("SYLLABUSC");
const html = sheet.getRange("C1:C6").getDisplayValues().filter(([c]) => c).join("\n");
// console.log(html); // When you directly run this function with the script editor, you can see the created value in the log.
return ContentService.createTextOutput(html).setMimeType(ContentService.MimeType.JAVASCRIPT);
}
From your Spreadsheet, in this sample script, I used "C1:C6" of "SYLLABUSC" sheet. So, please modify this for your actual situation.
Note:
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
Try a way to solve this by changing the spreadsheet Publishing Format from csv to tsv then it will work.
Code.gs
const doGet = _ => ContentService.createTextOutput(UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/e/2PACX-1vReY-tDEwKYjTiSjsfAN42qjFUwMv_OD3_64bFdGrgL-2p3otc13elLcCq3pkb5xqhTA-bW3QXobpqh/pub?gid=1861615717&single=true&range=c1:c5&output=tsv").getContentText()).setMimeType(ContentService.MimeType.JAVASCRIPT);
Anyone figured out a way to get number of video views with YouTube API into Google Docs?
Up until recently I was successfully using the method outlined in the YouTube View Count in Google Spreadsheet blog post by David Toy.
But it stopped working recently and I began to get the below error:
Request failed for https://gdata.youtube.com/feeds/api/videos/Prv2-9U39K8?v=2&alt=json returned code 410.
Truncated server response: <errors xmlns='http://schemas.google.com/g/2005'>
<error><domain>GData</domain><code>NoLongerAvailableException</code>
<internalReason>No longer avai...
(use muteHttpExceptions option to examine full response) (line 2, file "Code")
Has anyone run into this? If so any ideas on how to fix it would be really helpful.
Thanks!
The script from that blog post uses v2 of the API which has now been deprecated and switched off. The new version would be:
function getYoutubeViews(videoId){
var url = "https://www.googleapis.com/youtube/v3/videos?part=statistics&id=" + videoId;
url = url + "&key={YOUR-API-KEY}";
var videoListResponse = UrlFetchApp.fetch(url);
var json = JSON.parse(videoListResponse.getContentText());
return json["items"][0]["statistics"]["viewCount"];
}
In order to make this work you will need an API key. Here is the guide on the YouTube developers site which explains how to get the key. Once you have obtained your key simply replace {YOUR-API-KEY} in the code above with it.
To call the function from a Google spreadsheet, select a cell and enter: =getYoutubeViews("{YOUR-VIDEO-ID}"). For instance, =getYoutubeViews("IiPJsI8pl8Q").
If I use next function to get google output:
function myFunction() {
var post_url, result;
post_url = "http://www.google.com/search?q=stack+overflow";
result = UrlFetchApp.fetch(post_url);
Logger.log(result);
}
doesn't work.
P.S.
Sorry, I have to eхplore some dependences.
I take an example
function scrapeGoogle() {
var response = UrlFetchApp.fetch("http://www.google.com/search?q=labnol");
var myRegexp = /<h3 class=\"r\">([\s\S]*?)<\/h3>/gi;
var elems = response.getContentText().match(myRegexp);
for(var i in elems) {
var title = elems[i].replace(/(^\s+)|(\s+$)/g, "")
.replace(/<\/?[^>]+>/gi, "");
Logger.log(title);
}
}
and it works, than I begin to do some modifications and noticed that when I have some error in code it gives me an error
Request failed for http://www.google.com/search?q=labnol returned code
503.
So I did some researches without error's and it solution works. But when I began to form it to the function in lib it begans to throw me an error of 503 each time!
I'm very amazing of such behavior...
Here is short video only for fact. https://youtu.be/Lem9eiIVY0I
P.P.S.
Oh! I've broke some violations, so the google engine send me to stop list
so I run this:
function scrapeGoogle() {
var options =
{
'muteHttpExceptions': true
}
var response = UrlFetchApp.fetch("http://www.google.com/search?q=labnol", options);
Logger.log(response);
}
and get
About this pageOur systems have detected unusual traffic from your computer network. This page checks to see if it's really you sending the requests, and not a robot. Why did this happen?
As I see I have to use some special google services to get the search output and not to be prohibited?
You can use simple regex to extract Google search results.
var regex = /<h3 class=\"r\">([\s\S]*?)<\/h3>/gi;
var items = response.getContentText().match(regex);
Alternatively, you can use the ImportXML function in sheets.
=IMPORTXML(GOOGLE_URL, "//h3[#class='r']")
See: Scrape Google Search with Sheets
I want to use Google Feed API from a server (Node.js). I have already installed the googleapis module. My code is:
// parts omitted
var googleapis = require('googleapis');
// parts omitted
googleapis.discover('feeds').execute(function(err, client) {
var feed = new google.feeds.Feed('http://rss.lemonde.fr/c/205/f/3050/index.rss');
});
// parts omitted
But Node.js console tells me that "google is not defined". Any idea of the problem and solution?
to access Google Feed API using Node.js, you should try the google-feed-api module as explained here:
https://www.npmjs.org/package/google-feed-api
Hope it helps!
Edit:
I tried this with your URL and worked fine:
var gfeed = require('google-feed-api');
var feed = new gfeed.Feed('http://rss.lemonde.fr/c/205/f/3050/index.rss');
feed.listItems(function(items){
console.log(items);
});
It's because google is literally not defined. I don't know very much about that module, but I think that instead of using the google var you should use client , because that's what the execute function returns.
So the code would be:
// parts omitted
var googleapis = require('googleapis');
// parts omitted
googleapis.discover('feeds').execute(function(err, client) {
var feed = new client.feeds.Feed('http://rss.lemonde.fr/c/205/f/3050/index.rss');
});
// parts omitted
You now have to pay to use the google translate api. I'm happy to pay for the service but I can't find a way to use the tts. This is what I'm doing
var GoogleTranslate = function(){
var key = "myapikey"
this.speak = function(words) {
var url = "http://translate.google.com/translate_tts?tl=es&q=" + escape(words) + "&key=" + key
new Audio(url).play();
}
}
but when I do new GoogleTranslate().speak("hola")
The requests to http://translate.google.com/translate_tts never return a response. How do I get this working?
I haven't tried your code yet, so I'm not sure if you should be waiting for the sound to load before you can play it (most likely), but I've written an article about this service recently. The part that matters here is the following:
...if your browser forwards a Referer header with any value other than an empty string (meaning it tells the service which page you clicked the link on) then [Google] will return a 404 (Not Found) http error...
Read the entire article here: Embedding text-to-speech into HTML5 games
So in fact, the service is still there, you just need to hide your referer header. One way to do that is through creating a small gateway script. There's the source for one right in the article.