UrlFetchApp Token Authorization - google-apps-script

I am trying to fetch a URL using GScript's UrlFetchApp. The URL requires Token API Key to be passed in request header.
url = 'https://freshsales.io/search?q=abc';
var options = {
'method' : 'get',
'headers':{
'Authorization': "Token token=XYZ"
}
};
var response = UrlFetchApp.fetch(url, options);
This does not fetch me the expected response, as pasted below:
Freshsales
window.NREUM||(NREUM={});NREUM.info={"beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net","licenseKey":"","applicationID":"33348835,33348834","transactionName":"e11YEBQJXVlXER1LUllAVQxJFVRUQABaF0RdU0QHDg==","queueTime":1,"applicationTime":30,"agent":""}
(window.NREUM||(NREUM={})).loader_config={xpid:"VQcDVl5UDxADV1JWDwkEUw==",licenseKey:"",applicationID:"33348835"};window.NREUM||(NREUM={}),__nr_require=function(t,n,e){function
r(e){if(!n[e]){var
o=n[e]={exports:{}};t[e][0].call(o.exports,function(n){var
o=t[e][1][n];return r(o||n)},o,o.exports)}return
n[e].exports}if("function"==typeof __nr_require)return
__nr_require;for(var o=0;o0&&(p-=1)}),s.on("internal-error",function(t){i("ierr",[t,c.now(),!0])})},{}],3:[function(t,n,e){t("loader").features.ins=!0},{}],4:[function(t,n,e){function
r(t){}if(window.performance&&window.performance.timing&&window.performance.getEntriesByType){var
o=t("ee"),i=t("handle"),a=t(9),s=t(8),c="learResourceTimings",f="addEventListener",u="resourcetimingbufferfull",d="bstResource",l="resource",p="-start",h="-end",m="fn"+p,w="fn"+h,v="bstTimer",g="pushState",y=t("loader");y.features.stn=!0,t(7),"addEventListener"in window&&t(5);var x=NREUM.o.EV;o.on(m,function(t,n){var e=t[0];e
instanceof x&&(this.bstStart=y.now())}),o.on(w,function(t,n){var
e=t[0];e instanceof
x&&i("bst",[e,n,this.bstStart,y.now()])}),a.on(m,function(t,n,e){this.bstStart=y.now(),this.bstType=e}),a.on(w,function(t,n){i(v,[n,this.bstStart,y.now(),this.bstType])}),s.on(m,function(){this.bstStart=y.now()}),s.on(w,function(t,n){i(v,[n,this.bstStart,y.now(),"requestAnimationFrame"])}),o.on(g+p,function(t){this.time=y.now(),this.startPath=location.pathname+location.hash}),o.on(g+h,function(t){i("bstHist",[location.pathname+location.hash,this.startPath,this.time])}),f
in
window.performance&&(window.performance["c"+c]?window.performancef:window.performancef),documentf,documentf,documentf}},{}],5:[function(t,n,e){function
r(t){for(var
n=t;n&&!n.hasOwnProperty(u);)n=Object.getPrototypeOf(n);n&&o(n)}function
o(t){s.inPlace(t,[u,d],"-",i)}function i(t,n){return t[1]}var
a=t("ee").get("events"),s=t("wrap-function")(a,!0),c=t("gos"),f=XMLHttpRequest,u="addEventListener",d="removeEventListener";n.exports=a,"getPrototypeOf"in
Object?(r(document),r(window),r(f.prototype)):f.prototype.hasOwnProperty(u)&&(o(window),o(f.prototype)),a.on(u+"-start",function(t,n){var
e=t[1],r=c(e,"nr#wrapped",function(){function
t(){if("function"==typeof e.handleEvent)return
e.handleEvent.apply(e,arguments)}var n={object:t,"function":e}[typeof
e];return
n?s(n,"fn-",null,n.name||"anonymous"):e});this.wrapped=t[1]=r}),a.on(d+"-start",function(t){t[1]=this.wrapped||t[1]})},{}],6:[function(t,n,e){function
r(t,n,e){var r=t[n];"function"==typeof r&&(t[n]=function(){var
t=i(arguments),n={};o.emit(e+"before-start",[t],n);var
a;n[m]&&n[m].dt&&(a=n[m].dt);var s=r.apply(this,t);return
o.emit(e+"start",[t,a],s),s.then(function(t){return
o.emit(e+"end",[null,t],s),t},function(t){throw
o.emit(e+"end",[t],s),t})})}var
o=t("ee").get("fetch"),i=t(22),a=t(21);n.exports=o;var
s=window,c="fetch-",f=c+"body-",u=["arrayBuffer","blob","json","text","formData"],d=s.Request,l=s.Response,p=s.fetch,h="prototype",m="nr#context";d&&l&&p&&(a(u,function(t,n){r(d[h],n,f),r(l[h],n,f)}),r(s,"fetch",c),o.on(c+"end",function(t,n){var
e=this;if(n){var
r=n.headers.get("content-length");null!==r&&(e.rxSize=r),o.emit(c+"done",[null,n],e)}else
o.emit(c+"done",[t],e)}))},{}],7:[function(t,n,e){var
r=t("ee").get("history"),o=t("wrap-function")(r);n.exports=r;var
i=window.history&&window.history.constructor&&window.history.constructor.prototype,a=window.history;i&&i.pushState&&i.replaceState&&(a=i),o.inPlace(a,["pushState","replaceState"],"-")},{}],8:[function(t,n,e){var
r=t("ee").get("raf"),o=t("wrap-function")(r),i="equestAnimationFrame";n.exports=r,o.inPlace(window,["r"+i,"mozR"+i,"webkitR"+i,"msR"+i],"raf-"),r.on("raf-start",function(t){t[0]=o(t[0],"fn-")})},{}],9:[function(t,n,e){function
r(t,n,e){t[0]=a(t[0],"fn-",null,e)}function
o(t,n,e){this.method=e,this.timerDuration=isNaN(t[1])?0:+t[1],t[0]=a(t[0],"fn-",this,e)}var
i=t("ee").get("timer"),a=t("wrap-function")(i),s="setTimeout",c="setInterval",f="clearTimeout",u="-start",d="-";n.exports=i,a.inPlace(window,[s,"setImmediate"],s+d),a.inPlace(window,[c],c+d),a.inPlace(window,[f,"clearImmediate"],f+d),i.on(c+u,r),i.on(s+u,o)},{}],10:[function(t,n,e){function
r(t,n){d.inPlace(n,["onreadystatechange"],"fn-",s)}function o(){var
t=this,n=u.context(t);t.readyState>3&&!n.resolved&&(n.resolved=!0,u.emit("xhr-resolved",[],t)),d.inPlace(t,g,"fn-",s)}function
i(t){y.push(t),h&&(b?b.then(a):w?w(a):(E=-E,O.data=E))}function
a(){for(var t=0;t
I tested the same via python (code below) and it works perfectly.
url = "https://freshsales.io/search?q=abe"
payload = {}
headers = {
'Authorization': 'Token token=XYZ'
}
response = requests.request("GET", url, headers=headers, data = payload)
Response from Python code:
[
{
"id": "1000705745",
"name": "MKnight",
"email": "mknight#xxx.gov",
"owner": {
"id": 1000002014,
"name": "Tim"
},
"updated_at": "2020-02-13T04:57:29Z",
"primary_sales_account_name": "City of XYZ",
"type": "contact"
} ]
Any thoughts on what i may be missing here ?

Add the contentType that you can accept to force the returned content type from the server:
headers:{
Accept: "application/json",
Authorization: "Token token=XYZ"
}

Related

Safaricom Daraja: Duplicate json key detected

I am implementing Lipa na M-Pesa online by Safaricom. However, when I make the request, I get an error saying duplicate json keys detected.
The Payload:
payload = {
"BusinessShortCode": 174379,
"Password": "the password",
"Timestamp": "20220817050503",
"TransactionType": "CustomerPayBillOnline",
"Amount": 5,
"PartyA": 254714895622,
"PartyB": 174379,
"PhoneNumber": 254714895622,
"CallBackURL": "https://58fa-102-68-78-50.in.ngrok.io/api/v1/payments/callback/",
"AccountReference": "Payment",
"TransactionDesc": "Payment for K"
}
The headers:
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer access_token",
}
The request:
response = requests.request("POST", 'https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest', headers=headers, data=payload)
The response I get:
{
'responseId': '82699-21939686',
'responseCode': '400',
'responseDesc': 'Duplicate json key detected'
}
What could be the cause of this error and how can I go about solving it?
The issue is in the header, the request passes the Content-Type by default,
getting rid of it fixes the problem.
Although it is provided for in Safaricom's M-pesa Daraja code sample for python, Try changing this part so that it would be; renaming body=payload to json=payload
response = requests.request("POST",your-url, headers=headers, json=payload)
instead of
response = requests.request("POST", url , headers=headers, data=payload)
Removing Content-Type from the header as suggested gave me another error;
{'requestId': '12345-12345-1',
'errorCode': '400.002.02',
'errorMessage': 'Bad Request - Invalid BusinessShortCode'}
worked for me hope it does for you
The following works
import requests
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer DWbh63zkq7ZLagmNCSwnyvjA2kBQ'
}
payload = {
"BusinessShortCode": 174379,
"Password": "MTc0Mzc5YmZiMjc5ZjlhYTliZGJjZjE1OGU5N2RkNzFhNDY3Y2QyZTBjODkzMDU5YjEwZjc4ZTZiNzJhZGExZWQyYzkxOTIwMjIxMjIyMDUyOTQ5",
"Timestamp": "20221222052949",
"TransactionType": "CustomerPayBillOnline",
"Amount": 1,
"PartyA": 254712345678,
"PartyB": 174379,
"PhoneNumber": 254712345678,
"CallBackURL": "example.com/path",
"AccountReference": "CompanyXLTD",
"TransactionDesc": "Payment of X"
}
response = requests.request("POST", 'example.com/mpesa/stkpush/v1/processrequest', headers = headers, json = payload)
print(response.text.encode('utf8'))

can't using post on google script

hi iam trying to make post using google script , but it does not work,
original site here: https://billing.te.eg/ar-eg , it like you inquiry with code (ex:055) and number (ex:3020100) and it return bill
I try this before using python and it work but it don't work on google script
here is the code working using python:
import json
import requests
url = "https://billing.te.eg/api/Account/Inquiry"
data = {
"AreaCode": "055", # <-- change this
"PhoneNumber": "3020100", # <-- change this
"PinCode": "",
"InquiryBy": "telephone",
"AccountNo": "",
}
with requests.session() as s:
# load cookies
s.get("https://billing.te.eg/ar-eg", verify=False)
resp = s.post(url, data=data, verify=False).json()
print(json.dumps(resp, indent=4))
and this is the code i trying in google script but didn't work :
function landBill() {
var url = "https://billing.te.eg/api/Account/Inquiry"
var data = {"AreaCode": "055", "PhoneNumber": "3020105", "PinCode": "", "InquiryBy": "telephone",
"AccountNo": "", };
var options = {
'method' : 'post',
'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data),
'muteHttpExceptions': true,
};
var res = UrlFetchApp.fetch(url,options)
var cont = res.getContentText()
Logger.log(cont)
}
On the python code you are doing 2 requests, a GET and a POST
Since they are within a Session object cookies returned by the website are being automatically managed.
That concept however does not exist in built-in libraries of Apps Script, given that it has to be done manually.
Sample Code:
function myFunction() {
// =================== GET ===================
//initiating a request object for the first GET request
var request1 = {
'url': 'https://billing.te.eg/ar-eg',
'method' : 'get',
'muteHttpExceptions': true,
'validateHttpsCertificates': false,
};
// Adding ('validateHttpsCertificates': false,) since it is the equivalent of (verify=false) in the python code
var resGet = UrlFetchApp.fetchAll([request1]); //storing the response to digest cookies
// Digesting the cookies returned by the server (excluding cookies attributes) and adding them to an array to be reused in the POST
var cookies = [];
for (response of resGet) {
var headers = response.getAllHeaders();
for (cookie of headers['Set-Cookie']){
cookies.push(cookie.split(";")[0]);
}
}
// =================== POST ===================
// declaring the payload for the POST
var postData = {
"AreaCode": "055",
"PhoneNumber": "3020100",
"PinCode": "",
"InquiryBy": "telephone",
"AccountNo": "",
};
//Initiating a request object for the POST request and injecting the stored cookies into the HTTP headers
var request2 = {
'url': "https://billing.te.eg/api/Account/Inquiry",
'method' : 'post',
'contentType': 'application/x-www-form-urlencoded',
'muteHttpExceptions': true,
'validateHttpsCertificates': false,
'headers' : {
'Cookie': (cookies.join("; ") + ";"),
},
'payload' : postData,
};
//Storing the POST response
var resPost = UrlFetchApp.fetchAll([request2]);
//Printing POST response content to console
console.log(resPost[0].getContentText());
}

How to fix Invalid JSON payload error from the Google Ads API

I'm trying to pull a report from the Google Ads API into Google sheets and I can't get the API to recognize my query as a query
Here's the code and error I'm getting:
function basicReport() {
var query = {
"query" : "SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
};
var body = JSON.stringify(query);
var head = {
'Developer-token' : "<Dev token>",
'login-customer-id' : <Manager ID>,
'Authorization' : "Bearer <Auth token>",
};
var options = {
'method' : 'POST',
'content-type': 'application/json',
'headers' : head,
'payload' : body,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch('https://googleads.googleapis.com/v4/customers/<Customer ID>/googleAds:searchStream', options);
var json = response.getContentText();
var data = JSON.parse(json);
But I constantly get the error:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"{\"query\":\"SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id\"}\": Cannot bind query parameter. Field '{\"query\":\"SELECT campaign' could not be found in request message.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"description": "Invalid JSON payload received. Unknown name \"{\"query\":\"SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id\"}\": Cannot bind query parameter. Field '{\"query\":\"SELECT campaign' could not be found in request message."
I've run the query in OAuth playground (https://developers.google.com/oauthplayground) and it worked there, so I know the query is ok.
I've tried passing the body as an object not a string, but then I get a 500 error.
In case anyone else is looking for this - I did solve it.
When set in the header, Content-Type has a dash, when set in the options, contentType does not.
function basicReport() {
var query = {
"query" : "SELECT campaign.name, campaign.status FROM campaign ORDER BY campaign.id"
};
var body = JSON.stringify(query);
var head = {
'developer-token' : "<Dev token>",
'login-customer-id' : "<Manager ID>",
'authorization' : "Bearer <Auth token>",
'accept' : 'application/json'
'Content-Type': 'application/json',
};
var options = {
'method' : 'POST',
'headers' : head,
'payload' : body,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch('https://googleads.googleapis.com/v4/customers/<Customer ID>/googleAds:searchStream', options);
var json = response.getContentText();
var data = JSON.parse(json);
Logger.log(data);

Using Linkedin API with google apps script?

aloha all,
Im create a integration with linkedin and google apps script, for post in company page.
All is good, in terms of oauth2, i have the tokens, but the problem is the body request, look:
var payload = {"visibility": {"code": "anyone"},"comment": "Testing a full company share!","content": {"submitted-­url": "https://www.google.com","title": "Test Share with Content","description": "content description","submitted‐image-­url": "https://www.wired.com/wp-content/uploads/2015/09/google-logo.jpg"}};
var headers = {Authorization': 'Bearer ' + Service.getAccessToken()};
var options = {method:'post',headers:headers,payload:payload,muteHttpExceptions:true};
var response = UrlFetchApp.fetch("https://api.linkedin.com/v1/companies/2414183/shares?format=json", options);
THE REQUES IS GOOD, BECAUSE I USE APIGEE FOR TEST MY JSON REQUEST. THIS IS THE RESPONSE OF THE SERVER:
[16-12-12 22:38:13:411 EST] {
"errorCode": 0,
"message": "Couldn't parse share document: error: Unexpected element: CDATA",
"requestId": "XNZ80U0LCX",
"status": 400,
"timestamp": 1481600293335
}
IN SEVERAL FORUMS SAY THAT THE HEARDER I SHOUD PUT:
'Content-Type': 'application/json', 'x-li-format': 'json'
BUT WHEN PUT THIS CODE ON HEADER THE ERROR OF SERVER IS:
[16-12-12 22:40:00:344 EST] {
"errorCode": 0,
"message": "Couldn't parse Json body: Unexpected character ('v' (code 118)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n at [Source: java.io.StringReader#c3576e8; line: 1, column: 2]",
"requestId": "YQFPJKZTMC",
"status": 400,
"timestamp": 1481600400231
}
THANKS ALL
For payload you need to provide valid JSON e.g.:
var payload = JSON.stringify(object):
Not:
var payload = object;
I'd also add the content type to the headers, setting it to application/json:
var options = {
'contentType': 'application/json',
'payload': JSON.stringify(payload)
};
UrlFetchApp.fetch('https://www.example.com', options);
One change... Per the Linkedin developer docs:
If you opt to provide a JSON-formatted body, make sure your HTTP request includes the following headers:
Content-Type: application/json
x-li-format: json
https://developer.linkedin.com/docs/share-on-linkedin

GAS: Error when using UrlFetchApp

I am using the senotp serverside api to verify a number. When it is run using soap ui with the same content there's no error. But when I do it with UrlFetchApp it gives the error:
{"status":"error","response":{"code":"INVALID_REQUEST_BODY"}}
whereas the correct response should be:
{
"status": "success",
"response": {
"code": "OTP_SENT_SUCCESSFULLY",
"oneTimePassword": "34859"
}
}
The code I used is as foll0ws:
var payload =
{
"countryCode": "94",
"mobileNumber": "0766075555",
"getGeneratedOTP": true
};
var header=
{
"application-Key":"application_key_value"
};
var options =
{
"method" : "POST",
"headers":header,
"muteHttpExceptions": true,
"contentType":"application/json",
"payload" : payload
};
var request=UrlFetchApp.getRequest("https://sendotp.msg91.com/api/generateOTP", options)
Logger.log(request)
var response=UrlFetchApp.fetch("https://sendotp.msg91.com/api/generateOTP", options);
Logger.log(response);
I am not sure what is the problem here. Please help me debug it or let me know what is the problem with the code.
It seems as if using payload in GAS fetchService automatically results in contentType : application/x-www-form-urlencoded or contentType : multipart/form-data.
See documentention: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)
Unfortunately, I have not yet found a workaround.