Convert cURL to Google Apps Script - http

I am trying to convert a cURL command to a Google Apps Script PUT request.
I came up with the below google script but it does not seem to work. When I change the URL of both of these to RequestBin in order to probe what the server side is getting, RequestBin shows that the raw source of both of these come through as exactly the same. Yet, only the cURL command is able to perform the desired action (update a file on github) when I change it back to the github URL.
curl -i -X PUT -H 'Authorization: token yadayda' -d '{"path":"mygeojson.json","message":"Initial Commit","committer":{"name":"Sidd","email":"siddsubra#gmail.com"},"content":"bXkgbmV3IGZpbGUgY29udGVudHM=","sha":"0d5a690c8fad5e605a6e8766295d9d459d65de42","branch":"master"}' https://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json
cURL Command
And this is the Google Script
function mainscript() {
var sha = getSHA();
var authenticationToken = "yadayada";
var url = "http://api.github.com/repos/teku45/GeoJSON-Update/contents/mygeojson.json";
var headers = {
"Authorization" : "token " + authenticationToken,
};
var payload = {
"path": "mygeojson.json",
"message": "Initial Commit",
"committer":{
"name": "Sidd",
"email": "siddsubra#gmail.com"
},
"content": "bXkgbmV3IGZpbGUgY29udGVudHM=",
"sha": sha,
"branch": "master"
};
var options = {
"headers" : headers,
"method" : "PUT",
"payload" : JSON.stringify(payload)
};
Logger.log(options);
Logger.log(UrlFetchApp.fetch(url, options));
}
Google Apps Script

I recently did a script that call a request to a API from scrapy cloud, and had a dificulty to convert curl to App Script request too.
I noticed that payload doesn't worked when i used JSON.stringify, so try remove it from payload:
"payload" : payload
Other observation was the need to use Utilities.base64Encode in authentication token:
headers = {"Authorization":"Basic " + Utilities.base64Encode(authenticationToken + ":" + "")}
See this sample:
url = "https://app.scrapinghub.com/api/run.json"
headers = {"Authorization":"Basic " + Utilities.base64Encode("myToken" + ":" + "")}
payload = {"project":"327107", "spider":"pmp"}
options = {"headers":headers, "payload":payload}
response = UrlFetchApp.fetch(url, options)
data = JSON.parse(response.getContentText())

Related

How would one send an HTTP POST request?

I'm using lua-http for HTTP requests in my Lua script. I'm trying to find a way to send data as a POST request, similar to the -d option of curl.
I've tried new_from_uri:set_body() but I don't think I'm doing it correctly.
request = require "http.request"
headers, stream = assert(request.new_from_uri("https://example.org"):set_body("body text"))
headers, stream = assert(request.new_from_uri("https://example.org"):go())
body = assert(stream:get_body_as_string())
if headers:get ":status" ~= "200" then
error(body)
end
Could someone show me how to do this properly?
I've decided to use luasocket for this instead. Here is the code I'm using:
http = require "socket.http"
body = "body text"
respbody = {
result, respcode, respheaders, respstatus = http.request {
method = "POST",
url = "https://example.org",
source = ltn12.source.string(body),
headers = {
["content-type"] = "application/json", -- change if you're not sending JSON
["content-length"] = tostring(#body)
},
sink = ltn12.sink.table(respbody)
}
respbody = table.concat(respbody)

Attribute provided with invalid value in Google Apps Script

Problem
I want to communicate with api while changing IP address, because the server restricts IP address. So, I add X-Forwarded-For header with UrlFetchApp. However, I get an error "Attribute provided with invalid value: Header:X-Forwarded-For
"
Question
How can I solve this problem? Or is there another way?
function myFetch() {
var url = "https://XXXXXXXXX"
var options = { method: "GET" };
options.headers = {
Authorization: "Bearer " + MY_TOKEN,
"X-Forwarded-For": "XXX.XXX.XXX.XXX"
};
var resp = UrlFetchApp.fetch(url, options);
var json = resp.getContentText();
var data = JSON.parse(json);
return data;
}
Tried → Error
Tried : cURL request.
→Success : I can change IP address, and get data.
curl -X GET \
https://XXXXXXXXX \
-H 'Authorization: Bearer MY_TOKEN' \
-H 'X-Forwarded-For: XXX.XXX.XXX.XXX' \
Tried : Delete X-Forwarded-For header.
→Error : "API key does not allow access from IP XXX.XXX.XXX.XXX"
Tried : I also add Host header.
→Error : "Attribute provided with invalid value: Header:Host".
Does anybody have a solution for my problem?
Best regards,

Is there a way to add a post in wordpress via googlescript?

I have a form in googlescript where I can add a user to a sheet.
Is there a way to implement some lines in that code so the script adds a post on a wordpress page?
I read that it's possible via wp_insert_post , but I have no idea how that works in my case.
EDIT:
As Spencer suggested I tried to do it via WP REST API.
The following code seems to be working .............
function httpPostTemplate() {
// URL for target web API
var url = 'http://example.de/wp-json/wp/v2/posts';
// For POST method, API parameters will be sent in the
// HTTP message payload.
// Start with an object containing name / value tuples.
var apiParams = {
// Relevant parameters would go here
'param1' : 'value1',
'param2' : 'value2' // etc.
};
// All 'application/json' content goes as a JSON string.
var payload = JSON.stringify(apiParams);
// Construct `fetch` params object
var params = {
'method': 'POST',
'contentType': 'application/json',
'payload': payload,
'muteHttpExceptions' : true
};
var response = UrlFetchApp.fetch(url, params)
// Check return code embedded in response.
var rc = response.getResponseCode();
var responseText = response.getContentText();
if (rc !== 200) {
// Log HTTP Error
Logger.log("Response (%s) %s",
rc,
responseText );
// Could throw an exception yourself, if appropriate
}
else {
// Successful POST, handle response normally
Logger.log( responseText );
}
}
But I get the error:
[16-09-28 21:24:29:475 CEST] Response (401.0)
{"code":"rest_cannot_create","message":"Sorry, you are not allowed to
create new posts.","data":{"status":401}}
Means: I have to authenticate first.
I installed the plugin: WP REST API - OAuth 1.0a Server
I setup a new user and got a client key and client user.
But from here I have no clue what to do : /
It is possible. Wordpress has a REST API. I can be found at:
http://v2.wp-api.org/
You will use the UrlFetchApp Service to access this api. Documentation can be found at:
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
Read the docs and try to write some code. It you get stuck post the code that is confusing you here and I'll update this answer.
You should add you authentification in the header :
var headers = {
... ,
'Authorization' : 'Basic ' + Utilities.base64Encode('USERNAME:PASSWORD'),
};
And then add your header in your parameters :
var params = {
'method': 'POST',
'headers': headers,
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
}
And then use UrlfetchApp.fetch
var response = UrlFetchApp.fetch("https://.../wp-json/wp/v2/posts/", params)
Logger.log(response);
You need to pass the basic auth, like this:
// Construct `fetch` params object
var params = {
'method': 'POST',
'contentType': 'application/json',
'payload': payload,
'muteHttpExceptions' : true,
"headers" : {
"Authorization" : "Basic " + Utilities.base64Encode(username + ":" + password)+"",
"cache-control": "no-cache"
}
};
thank you for giving me these important links.
<3
I installed WP REST API and the OAuth plugin.
In the documentation is written:
Once you have WP API and the OAuth server plugins activated on your
server, you’ll need to create a “client”. This is an identifier for
the application, and includes a “key” and “secret”, both needed to
link to your site.
I couldn't find out how to setup a client?
In my GoogleScriptCode according to the WP API I get the error:
{"code":"rest_cannot_create","message":"Sorry, you are not allowed to create new posts.","data":{"status":401}}
Edit: I found it - it's under User/Application
I'll try to figure it out and get back to you later.

Put a custom http header in backbone

I am creating an API with Tastypie and I want to access to the API from Backbone.
To send credentials I use an user_id and a api_key. I do this in android and with curl and this work great, but I can set the http header from backbone.
In curl I use:
curl --dump-header - -H "Accept: application/json" -H "Content-Type: application/json" -H "user_id: 32" -H "api_key: 69950" -X DELETE "http://127.0.0.1:8000/api/v1/deletenote/66/?format=json"
and in android java I use:
HttpDelete requestDELETE = new HttpDelete();
requestDELETE.setHeader("Content-type", "application/json");
requestDELETE.setHeader("Accept", "application/json");
requestDELETE.setHeader(Constants.HEADER_USER_ID, user_id);
requestDELETE.addHeader(Constants.HEADER_API_KEY, key);
Both of them work great, but when I try this in Backbone following the responses that I found in other post from the page, this didn't work.
I am trying this:
var removeNote = new DeleteNoteModel({id:this.model.toJSON().id},{ query:this.model.toJSON().id});
removeNote.destroy({
headers: {'user_id':dataWeb.get("id"),'api_key':dataWeb.get("api_key")}
},{
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
}
);
I'm putting the header when I call to the destroy call, but this don't send anithing to the server.
What I am doing in a wrong mode?
Thanks to all.
Tallmaris answer should fix it for you though I would recommend usign jQuery ajaxSetup method to setup the headers as default values for all ajax requests as I believe you need them all the time anyway right?
Somewhere where you launch the App put in
$.ajaxSetup({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}
});
Thanks to that you'll save yourself a lot of repeated code :) keep it DRY!
(obviously you'd need to ensure that dataWeb is available in the scope of where you launch the app :) )
It seems you are passing two parameters to destroy, pass only one containing the headers and the other options together, unless the brackets order is a typo. Try this:
removeNote.destroy({
headers: {
'user_id':dataWeb.get("id"),
'api_key':dataWeb.get("api_key")
}, // there was an extra close-open curly here...
async:false,
error: function(model, response){
console.log("KO_REMOVE_NOTE");
console.log(response);
},
success : function(model, response){
console.log("OK_REMOVE_NOTE");
console.log(response);
}
});

'#' in URL, used in node.js http.request

I'm presented with an url with an "#" sign in it:
curl http://subdomain:token#localhost:9292/aaa/bbb
works perfectly
But I can't get it to work with node.js http.request, probably because I don't understand what the "#" is doing (and somehow can't find a clear answer on google).
Anyone care to explain?
Here's my current node.js code
var http_options = {
method : "GET"
, url : subdomain + ":" + token + "#" + Config.API.url
, path : "/aaa/bbb"
};
var req = http.request(http_options, function (response) {
// ...
});
req.on('error', function (error) {
console.log('error: ' + error);
});
which produces:
error: ECONNREFUSED
The # is dividing the user / password part from the location part.
the curl line you wrote send a HTTP Authenticate (BASIC authentication) with the request.
curl http://subdomain:token#localhost:9292/aaa/bbb
means: Get localhost:9292/aaa/bbb and do it as user: subdomain password token
I have no idea how to do that in node.js, but you'll figure it out, now that you know what it does.

Resources