I am trying to shorten URLs from Google Apps Script, but I keep getting 404 errors and I don't know why. Please help.
function shortenUrl(longUrl){
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify({
"long_url": longUrl,
}),
// 'muteHttpExceptions': true,
'headers': {'Authorization': 'Bearer ' + BITLY_TOKEN,
// 'Host': 'https://api-ssl.bitly.com',
'Content-Type': 'application/json'}
};
return UrlFetchApp.fetch("https://api-ssl.bitly.com/v4/shorten HTTP/1.1", options).getContentText();
}
How about this modification?
Modified script:
function shortenUrl(longUrl){
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify({
"long_url": longUrl,
}),
// 'muteHttpExceptions': true,
'headers': {'Authorization': 'Bearer ' + BITLY_TOKEN} // Modified
};
return UrlFetchApp.fetch("https://api-ssl.bitly.com/v4/shorten", options).getContentText(); // Modified
}
For above script, please confirm whether BITLY_TOKEN is declared, again.
References:
Class UrlFetchApp
Bitly API (4.0.0)
Related
I have this code to use saved API token and use it on other test, but it doesn't work (I get this error message : Reference Error : access_token is not defined: so I need to save my generated token and use it on all my API test
const API_STAGING_URL = Cypress.env('API_STAGING_URL')
describe('Decathlon API tests', () => {
it('Get token',function(){
cy.request({
method:'POST',
url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
headers:{
authorization : 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
}}).then((response)=>{
expect(response.status).to.eq(200)
const access_token = response.body.access_token
cy.log(access_token)
cy.log(this.access_token)
})
cy.log(this.access_token)
}),
it('Create Cart',function(){
cy.request({
method:'POST',
url: `${API_STAGING_URL}`+"/api/v1/cart",
headers:{
Authorization : 'Bearer ' + access_token,
"Content-Type": 'application/json',
"Cache-Control": 'no-cache',
"User-Agent": 'PostmanRuntime/7.29.2',
"Accept": '*/*',
"Accept-Encoding": 'gzip, deflate, br',
"Connection": 'keep-alive',
"Postman-Token": '<calculated when request is sent>'
},
}}).then((response)=>{
//Get statut 200
expect(response.status).to.eq(200)
//Get property headers
})})
})
This is a scoping issue - access_token does not exist outside of the block where it is created. Filip Hric has a great blog post on using variables with Cypress. My favorite strategy would be to store the value in a Cypress environment variable.
const API_STAGING_URL = Cypress.env('API_STAGING_URL');
describe('Decathlon API tests', () => {
it('Get token', function () {
cy.request({
method: 'POST',
url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
headers: {
authorization: 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
}
}).then((response) => {
expect(response.status).to.eq(200);
Cypress.env('access_token', response.body.access_token);
cy.log(Cypress.env('access_token'));
});
});
it('Create Cart', function () {
cy.request({
method: 'POST',
url: `${API_STAGING_URL}` + '/api/v1/cart',
headers: {
Authorization: `Bearer ${Cypress.env('access_token')}`,
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'User-Agent': 'PostmanRuntime/7.29.2',
Accept: '*/*',
'Accept-Encoding': 'gzip, deflate, br',
Connection: 'keep-alive',
'Postman-Token': '<calculated when request is sent>'
}
}).then((response) => {
// Get statut 200
expect(response.status).to.eq(200);
// Get property headers
});
});
});
Another approach would be to create the access_token in a hook and then you can access it in a it() block.
There are a few ways to do it.
Using variable:
let text
beforeEach(() => {
cy.wrap(null).then(() => {
text = "Hello"
})
})
it("should have text 'Hello'", function() {
// can access text variable directly
cy.wrap(text).should('eq', 'Hello')
})
Using an alias:
beforeEach(() => {
cy.wrap(4).as("Number")
})
it("should log number", function() {
// can access alias with function() and this keyword
cy.wrap(this.Number).should('eq', 4)
})
Here is a working example.
First, I have to apologize for my poor English skill I am using Google Apps Script.
I'm trying to get JSON data from AJAX link but sometimes error occurs
Unexpected token < in JSON at position 4
I know the problem here is the data return form "HTML" while i expect "JSON"
I trying
My Script
async function getJSON () {
const myHeaders = {
'cache' : 'no-cache',
'pragma': 'no-cache',
'Cache-Control': 'no-cache',
'accept': 'text',
'dataType' : 'text',
'contentType': 'application/json; charset=utf-8',
};
const myInit = {
muteHttpExceptions: true,
method: 'GET',
headers: myHeaders,
};
const url = "https://www.xxxx.xxx/xxxxxxx/?ajax=xxxxxxx"
const content = await UrlFetchApp.fetch(url ,myInit).getContentText();
const obj = JSON.parse(content);
....
...
}
The problem as you say is that sometimes the response is an HTML, which generates that when the JSON.parse function is called, an error arises because the response does not contain a valid JSON.
This error comes from the server, so there is not much you can do about it. One way to handle the error is with a try-catch block, which is common practice in asynchronous fetch.
For example:
async function getJSON() {
try {
const myHeaders = {
'cache': 'no-cache',
'pragma': 'no-cache',
'Cache-Control': 'no-cache',
'accept': 'text',
'dataType': 'text',
'contentType': 'application/json; charset=utf-8',
};
const myInit = {
muteHttpExceptions: true,
method: 'GET',
headers: myHeaders,
};
const url = "https://www.xxxx.xxx/xxxxxxx/?ajax=xxxxxxx"
const content = await UrlFetchApp.fetch(url, myInit).getContentText();
const obj = JSON.parse(content);
// ...
} catch (err) {
console.log({
err
})
}
}
I am trying to call FreshChat API from google apps script. GET request of outbound-messages is working fine but POST request is failing with error
Exception: Request failed for http://api.in.freshchat.com returned code 400. Truncated server response: {"success":false,"errorCode":0,"errorMessage":"HTTP 405 Method Not Allowed","errorData":null,"errorName":null} (use muteHttpExceptions option to examine full response)
Below are the details of request
function myFunctiontest() {
var url = "http://api.in.freshchat.com/v2/outbound-messages/whatsapp";
var headersPOST = {
'Authorization': 'Bearer XXXXXX',
'Content-Type': 'application/json',
'Accept': 'application/json'
};
var bodyPayload = {"from": {"phone_number": "+XXXXXX"},"provider": "whatsapp","to": [{"phone_number": "+XXXXX"}],"data": {"message_template": {"storage": "none","template_name": "XXXXXX","namespace": "XXXXX","language": {"policy": "deterministic","code": "en"},"template_data": [{"data": "XXXXX"}]}}};
var options = {
'method': 'post',
'contentType': 'application/json',
'headers': headersPOST,
'payload': JSON.stringify(bodyPayload),
'muteHttpExceptions':true
};
var response = UrlFetchApp.fetch(url, options);
console.log(response.getAllHeaders());
Logger.log(JSON.parse(response.getContentText()));
}
Same headers are working for GET request. Also same post request is working from POSTMAN.
Freshchat support helped for solving the issue.
There are two major changes
use https instead of http
Added contentType inside headers.
function myFunctiontest() {
var url = "https://api.in.freshchat.com/v2/outbound-messages/whatsapp";
var headersPOST = 'Bearer XXXXXX';
var bodyPayload = {"from": {"phone_number": "+XXXXXX"},"provider": "whatsapp","to": [{"phone_number": "+ XXXXX"}],"data": {"message_template": {"storage": "none","template_name": "XXXXXX","namespace": "XXXXX","language": {"policy": "deterministic","code": "en"},"template_data": [{"data": "XXXXX"}]}}};
var options = {
method: 'POST',
//content-type: 'application/json',
headers: { Authorization: headersPOST, 'content-type': 'application/json'},
payload: JSON.stringify(bodyPayload),
muteHttpExceptions:true
};
var response = UrlFetchApp.fetch(url, options);
var text = response.getResponseCode();
}
Hey Stackoverflow fellows!
I have been trying to writing an automation for my google sheets using an api from bit.ly to shorten my tons of link. Right now, I am at the fundamental stage and trying to log what the api return to me. Could you guys help an see what is wrong with the code? I am expecting the 200 returning back to me but it keep returning 403 forbidden to me.
var form =
{"long_url": "https://dev.bitly.com", "domain": "bit.ly", "group_guid": "MY GROUP ID" };
var option = {'header':'Authorization: Bearer{MY TOKEN}',
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(form)
};
var response = UrlFetchApp.fetch('https://api-ssl.bitly.com/v4/shorten', option);
Logger.log (response);
}
P.S. I tried to further expand the code by using adding title (succeeded) and customized link (short half // after bit.ly/ ). The second part keep return me 404. Or should I use Post/custom_bitlinks instead?
Here is my current code:
function bitlyori (i, title){
var form = {
"group_guid": "MINE",
"domain": "bit.ly",
"long_url": i,
"title" : title
};
const MY_TOKEN = "MINE";
const option = {
headers: { Authorization: `Bearer ${MY_TOKEN}` },
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(form),
};
var result = UrlFetchApp.fetch('https://api-ssl.bitly.com/v4/bitlinks', option);
return (JSON.parse(result.getContentText()));
}
function bitly(url,title,custom) {
var temp = bitlyori(url, title);
var form_2 = {
"custom_bitlinks": [temp] ,
};
const MY_TOKEN = "MINE";
const option_2 = {
headers: { Authorization: `Bearer ${MY_TOKEN}` },
method: 'patch',
payload: form_2};
var temp_link = 'https://api-ssl.bitly.com/v4/bitlinks/'+ JSON.stringify(temp)["id"];
var result_2 = UrlFetchApp.fetch(temp_link, option_2);
return (JSON.parse(result_2.getContentText()));
}
Headers should be a object with key "headers" inside options:
const MY_TOKEN = "dfjkgsa";
const option = {
headers: { Authorization: `Bearer ${MY_TOKEN}` },
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(form),
};
See:
Urlfetchapp ยง Advanced parameters
I'm stuck at this point of my code wherein I have successfully called the Sheets API using PUT request, but it's not rendering on the Google Sheet.
Here is my code where I use both PUT and GET requests to see if the data changed:
background.js
chrome.identity.getAuthToken({ 'interactive': true }, getToken);
function getToken(token) {
console.log('this is the token: ', token);
var params = {
"range":"Sheet1!A1:B1",
"majorDimension": "ROWS",
"values": [
["Hi","Crush"]
],
}
let init = {
method: 'PUT',
async: true,
data: params,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
},
'contentType': 'json',
};
fetch(
"https://sheets.googleapis.com/v4/spreadsheets/1efS6aMlPFqHJJdG8tQw-BNlv9WbA21jQlufsgtMsUmw/values/Sheet1!A1:B1?valueInputOption=USER_ENTERED",
init)
.then((response) => console.log(response))
let request = {
method: 'GET',
async: true,
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
},
'contentType': 'json',
};
fetch(
"https://sheets.googleapis.com/v4/spreadsheets/1efS6aMlPFqHJJdG8tQw-BNlv9WbA21jQlufsgtMsUmw/values/Sheet1!A1:B1",
request)
.then((response) => response.json())
.then(function(data) {
console.log(data)
});
}
Here's the screenshot of my Google Sheet, the data didn't change. The status of the PUT request is 200 and it seems the data is still Hello World in A1:B1:
Here's the log:
Do you have any idea what's missing here?
How about this modification? Please modify the object of init as follows.
From:
data: params,
To:
body: JSON.stringify(params),
Reference:
Using Fetch