Create a post in Blogger with Google Apps Script - google-apps-script

So far I haven't found a good code to create posts in Blogger with Google Script.
In the API Console I got the following credentials:
Client ID
Client Secret
API key
Also, libraries were added to the Google Script:
OAuth2 library → MswhXl8fVhTFUH_Q3UOJbXvxhMjh3Sh48
Blogger library → M2CuWgtxF1cPLI9mdRG5_9sh00DPSBbB3
I tried some codes, and this is the current one:
function create_blog_post() {
var payload =
{
"kind": "blogger#post",
"blog": {
"id": "12345........" // YOUR_BLOG_ID
},
"title": "New post",
"content": "With content..."
};
var headers = {
"Authorization": "Bearer " + getService().getAccessToken(), // ← THIS IS WRONG
"X-HTTP-Method-Override": "PATCH"
};
var options =
{
"method" : "post",
"headers" : { "Authorization" : "Bearer" + getService().getAccessToken()},
"contentType" : "application/json",
"payload" : '{ "kind": "blogger#post", "blog": { "id": "12345........" }, "title": "New post", "content": "With content..." }'
};
try {
var result = UrlFetchApp.fetch(
"https://www.googleapis.com/blogger/v3/blogs/12345......../posts", options);
Logger.log(result);
} catch (e) {Logger.log(e);}
}
Please help me solve this with the simplest code possible.

Required reading:
ScriptApp#getOauthToken
Blogger §post#insert
UrlFetchApp#fetch
Editing manifest#Setting explicit scopes
Switch to standard GCP
API Library
Issue:
Usage of asynchronous client side browser samples in the synchronous server side.
Solution:
It is possible to access Blogger api from Google apps script using UrlFetchApp
Full OAuth flow can be bypassed using oauth token provided by ScriptApp
Include scopes in the appsscript.json manifest file.
Switch to a standard GCP and enable the blogger api
Snippet:
function createBlogPost(){
var postUrl = "https://www.googleapis.com/blogger/v3/blogs/blogId/posts";
var blogId = /*"YOUR_BLOG_ID"*/;
postUrl = postUrl.replace("blogId",blogId);
var options = {
method:"post",
contentType:"application/json",
headers: { Authorization: "Bearer "+ ScriptApp.getOAuthToken()},
muteHttpExceptions: true,
payload: JSON.stringify({
title: "Hello from Apps Script!",
content: "This post is automatically created by Apps script"
})
}
var res = UrlFetchApp.fetch(postUrl, options).getContentText();
console.log(res);//or Logger.log(res)
}
Manifest scopes:
"oauthScopes": [
"https://www.googleapis.com/auth/blogger",
"https://www.googleapis.com/auth/script.external_request"
]

Related

Authentication error when attempting to fetch google analytics 4 with app script

I would like to connect a community connector to a google analytics 4 account so that I can easily modify the data and send it to data studio. However, My code is returning an authentication error:
{ error:
{ code: 401,
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
status: 'UNAUTHENTICATED' } }
I have included the token, but I am unsure if I am making the correct url call or if there is some other issue that I am unaware of. I don't believe I need an API key to connect from community connector to a google API, but I may be wrong. I did create an API key but the result was the same.
function testFetch(){
var url = "https://analyticsdata.googleapis.com/v1alpha:runReport"
var token = ScriptApp.getOAuthToken();
var options = {
"method" : 'POST',
"entity": { "propertyId": "263290444" },
"dateRanges": [{ "startDate": "2020-12-01", "endDate": "2021-03-01" }],
"dimensions": [{ "name": "country" }],
"metrics": [{ "name": "activeUsers" }],
'muteHttpExceptions': true,
headers: {
Authorization: 'Bearer' + token,
},
};
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(response.getContentText());
}
Here is a small guide on how to do what you are trying to achieve:
Set explicit OAuth scopes (see documentation) to your Apps Script project manifest (appsscript.json). In this case you need to add the following:
{
...
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/analytics.readonly"
}
}
Then you need to separate the method parameters from the fetch options. The fetch options need to be stringified and added to payload. You also need to set the contentType to JSON.
const options = {
entry: { propertyId: "263290444"},
// etc.
}
const response = UrlFetchApp.fetch(
'https://analyticsdata.googleapis.com/v1alpha:runReport',
{
method: 'POST',
muteHttpExceptions: true,
headers: {
'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`
},
contentType: 'application/json; charset=utf-8',
payload: JSON.stringify(options)
}
)
After that, you may use the response as you were doing before.
Note that Bearer and the token need to be separated by a space, which your code does not have. It's hard to see because of the concatenation and that why I usually use template literals (see documentation).
References
Authorization scopes | Set explicit scopes (Google Apps Script Guides)
UrlFetchApp.fetch(url, params) (Google Apps Script Reference)
Template literals (MDN)

How to get Log with Stackdriver Logging API

I'm developing a chatbot using Dialogflow and I need to get full conversation log from it.
I checked this page and I guessed it is able to achieve it by using Stackdriver Logging api.
I referred below page and I tried, however using this api, it occurs 403 error.
https://cloud.google.com/logging/docs/reference/v2/rest/v2/logs/list
Did I use this in a wrong way?
How can I resolve this problem?
This is the error message.
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"status": "PERMISSION_DENIED"
}
}
This is my code where calling the api.
I used Google Apps Script.
function getLogs() {
//XXXXXXXX is my project_id
var output = UrlFetchApp.fetch('https://logging.googleapis.com/v2/projects/XXXXXXXX/logs');
Logger.log(output)
}
I've resolved this way.
Add my api key to http request.
var options = {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}};
var logs = UrlFetchApp.fetch("https://logging.googleapis.com/v2/projects/XXXXXXXX/logs?key=my_api_key", options)
Add scope to appscript.json.
"oauthScopes": ["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/script.external_request"]
Then I found logs.list methond is not appropriate for my goal so I need to change to v2.entries method.
function getLogs(){
var options = {
method: "post",
contentType: "application/json",
headers: {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()},
payload: JSON.stringify({
resourceNames: ['projects/XXXXXXX'],
filter: "timestamp >= searchdate",
orderBy: "timestamp desc",
pageSize: 1,
}),
}
var logs = UrlFetchApp.fetch("https://logging.googleapis.com/v2/entries:list?key=my_api_key", options);
Logger.log(logs);
}

Apps Script API returning 404 error for existing project. Error returned as HTML rather than JSON

I was attempting to run an Apps Script function using the Apps Script API. I set up the script in the console, and created an oauth client ID for the script. I configured the authorisation screen and deployed the script as API executable. I tested the api function calling in the same script but got a 404 error saying:
The Requested URL /v1/scripts/{{my_script_id}}:run was not found on this server.
The response came back as HTML. I also noticed that the script seems to make it's own client ID when it's called from the API.
I tried disabling and re-enabling the API which didn't work. I think it may be a problem with the calling application not being in the same project but I'm not sure how to do that as the Google documentation is unclear.
function trigger(){
var bogus = DriveApp.getRootFolder();
var argument = ["Value0", "Value1", "Value2", "Value3", "Value4", "Value5"];
// https://www.googleapis.com/auth/script.external_request
// https://www.googleapis.com/auth/spreadsheets
var postRequest = {
"Content-Type": "application/json",
"headers": { "Authorization" : "Bearer " + ScriptApp.getOAuthToken()},
"function": "setStatus",
"muteHttpExceptions": true,
"parameters": [argument],
"devMode": false
};
try{
var response = UrlFetchApp.fetch("https://script.googleapis.com/v1/scripts/{{my_script_id}}:run", postRequest);
Logger.log(response);
}catch(err){
Logger.log(err);
}
}
I expected some form of error in the form of JSON or maybe even for the function to run, what I got was a HTML document which displayed a 404 error when displayed.
You're not POSTing the request. Default .fetch method is GET.
Add this in postRequest object:
method: "POST",
payload is also missing from your postRequest.
Snippet:
var postRequest = {
"method":"POST", //added
"contentType": "application/json", //key changed
"headers": { "Authorization" : "Bearer " + ScriptApp.getOAuthToken()},
"muteHttpExceptions": true,
"payload": JSON.stringify({ //added
"function": "setStatus",
"parameters": argument, //removed []
"devMode": false
})
};
References:
UrlfetchApp
Script:run

Is there a way to enable advanced google services in the Google Developers Console by script?

again!
I created an embedded in spreadsheet script that use UrlShortener.Url.insert feature. My client wants to be able to make a new instances of this spreadsheet to share it with colleagues. I've implemented this feature, but when I begin to test new instance it's turned out that I have to enable URL Shortener API in my Google Developers Console.
I wonder if I can bypass this manual work using my script or only I can do is to provide client with instructions how to do it?
Update:
Sandy Good recomends to use UrlFetch.fetch() to get the short link, but this code:
function test_short_link() {
var options =
{
'longUrl': 'http://www.google.com/',
'muteHttpExceptions': true
};
var result = UrlFetchApp.fetch("https://www.googleapis.com/urlshortener/v1/url",
options);
Logger.log(result);
}
returns this:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required parameter: shortUrl",
"locationType": "parameter",
"location": "shortUrl"
}
],
"code": 400,
"message": "Required parameter: shortUrl"
}
}
Looks like this topic
And this code
function test_short_link() {
var options =
{
'longUrl': 'http://www.google.com/',
'muteHttpExceptions': true,
'method':'post'
};
var result = UrlFetchApp.fetch("https://www.googleapis.com/urlshortener/v1/url",
options);
Logger.log(result);
}
bring us:
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "userRateLimitExceededUnreg",
"message": "User Rate Limit Exceeded. Please sign up",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "User Rate Limit Exceeded. Please sign up"
}
}
Edit: No there is no way to access the Google Dev console through any method beside the website itself.
Here is the method to do this by UrlFetchApp. You need to pass the options in payload parameter, not in the UrlFetchApp options object. You also need to pass the current users OAuth token in the header. Of course you will need to modify this code as it hard codes the longUrl and does no error checking.
function ShortenUrl(){
var url = "https://www.googleapis.com/urlshortener/v1/url"
var payload = {"longUrl":"www.google.com"};
var parameters = { method : 'post',
headers : {'Authorization': 'Bearer '+ScriptApp.getOAuthToken()},
payload:JSON.stringify(payload),
contentType:'application/json',
muteHttpExceptions:true};
var response = UrlFetchApp.fetch(url, parameters);
Logger.log(response);
}
This can be done perfectly. Try this code:
function ShortenUrl(){
var url = 'https://www.googleapis.com/urlshortener/v1/url';
var apiKey = 'AIzBlNS-3HZdxKgwj-x30';
url += '?key=' + apiKey;
var payload = {"longUrl":"www.google.com"};
var parameters = { method : 'post',
payload:JSON.stringify(payload),
contentType:'application/json',
muteHttpExceptions:true};
var response = UrlFetchApp.fetch(url, parameters);
Logger.log(response);
}

How to use google url shortner api by UrlFetchApp.fetch correctly?

I spent a lot of time reading google manuals and other resources and didn't find out what I'm doing wrong when trying to get short url using this script:
function test_short_link() {
var apiKey, post_url, options, result;
post_url = "https://www.googleapis.com/urlshortener/v1/url";
apiKey = 'xxx';//here is real apiKey
post_url += '?key=' + apiKey;
var options =
{ 'method':'post',
'headers' : {'Content-Type' : 'application/json'},
"resource": {"longUrl": "https://google.com/"},
'muteHttpExceptions': true
}
result = UrlFetchApp.fetch(post_url, options);
Logger.log(result);
}
I did various modifications but it returns:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required",
"locationType": "parameter",
"location": "resource.longUrl"
}
],
"code": 400,
"message": "Required"
}
}
It drives me mad!
Please help! What is wrong with this code?
You will need to modify this code as it hard codes the longUrl and does no error checking. Some of the important parts are that the API options are sent in the payload of the UrlFetchApp options object and that you need to pass the current users OAuth token in the header.
function ShortenUrl(){
var url = "https://www.googleapis.com/urlshortener/v1/url"
var payload = {"longUrl":"www.google.com"};
var parameters = { method : 'post',
headers : {'Authorization': 'Bearer '+ScriptApp.getOAuthToken()},
payload:JSON.stringify(payload),
contentType:'application/json',
muteHttpExceptions:true};
var response = UrlFetchApp.fetch(url, parameters);
Logger.log(response);
}
There is also an advanced Google service to do it more simply.
You'll need to activate it from the script editor ressource menu (see illustrations below.)
Code is as simple as that :
function shortenUrl(longUrl) {
var toShorten = UrlShortener.newUrl().setLongUrl(longUrl);
var shortened = UrlShortener.Url.insert(toShorten);
return shortened.id;
}
Just use it as in this test function below :
function test(){
var shortUrl = shortenUrl("http://stackoverflow.com/questions/tagged/google-apps-script");
Logger.log(shortUrl);
}