NetworkError: 403 Forbidden - http://www.googleapis.com/fusiontables/v1/query? google fusion tables - google-fusion-tables

I am wondering what is wrong in my code to be producing the following error message:
NetworkError: 403 Forbidden - http://www.googleapis.com/fusiontables/v1/query?
I believe that I am properly referencing the new SQL V1 API and the tables I am referencing are base tables that allow data to be exported.
Code Snippet
function getEcoliData(beachID) {
//local namespace
var rows = [];
var items = [];
var queryURL = "http://www.googleapis.com/fusiontables/v1/query?sql=";
var queryTail = '&jsonCallback=?';
var whereClause = "WHERE 'Beach_ID' = " + beachID;
var query = "SELECT 'Sample_Date', 'Average_E.coli_Density','Recreational_Water_Quality_Guideline' FROM 1-ZORhnuDELDxO1FsmzJ60K3JzWOYOKvsHibrQeo " + whereClause + " ORDER BY 'Sample_Date' DESC";
var queryText = encodeURI(query);
infoWindow = new google.maps.InfoWindow();
$.ajax({
type: "GET",
url: queryURL + queryText + queryTail,
cache: false,
dataType: 'jsonp',
jsonCallback: 'jsonCallback',
success: function (data) {
rows = data.tables.rows;
for (var i = 0; i < rows.length; i++) {
items.push(rows[i]);
}
return items;
},
error: function () {
alert("Data is not available for this location at the present time, please check back at a later time. Thank you.");
}
});
}
any suggestions are welcomed. Thanks in advance.
Michael

use https:// instead of http:// . You also need to send a valid key via the URL(be sure that you've activated the Fusion-Tables-API-service inside the API-console before you use the key).

Related

Google App Script error 404: Response not defined

My code is supposed to get some data from google sheet and POST to a system via external API.I, however, keep running into the error 404 when I run the code.
On debug, it indicates that response is not defined. Here is the potion of the code with the issue. Am I missing something?
function postLeave(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
// used getLastRow() function [1] to narrow the array to have only cells with data.
var range = sheet.getRange("K2:K"+sheet.getLastRow()).getValues();
var searchString = "";
for (var i = 0; i<range.length; i++) {
if(range[i][0] == searchString) {
var lastRow = sheet.getRange(2+i,1,1,10).getValues();
var userid = sheet.getRange("I2:I" + sheet.getLastRow()).getValues();
var data = {
//'user_id': lastRow[0][8],
"leave_type_id":lastRow[0][9],
"date":lastRow[0][7],
"hours":lastRow[0][6],
};
var payload = JSON.stringify(data);
var options = {
'method': 'POST',
'Content-Type': 'application/json',
'payload' : data,
};
var url = 'https://api.10000ft.com/api/v1/users/' + userid + '/time_entries?auth=key;
var response = UrlFetchApp.fetch(url).getContentText();
if (response === 200) {
//var json = JSON.parse(response);
sheet.getRange(2+i, 11).setValue(1);
}
else {
sheet.getRange(2+i, 11).setValue(0);
Logger.log(response)
}
}
}
}
Documentation
Challenge with endpoints.
https://github.com/10Kft/10kft-api/blob/master/sections/assignables.md
https://github.com/10Kft/10kft-api/blob/master/sections/leave-types.md
https://github.com/10Kft/10kft-api/blob/master/sections/time-entries.md
How about this modification?
Modification points:
Content-Type cannot be directly used to the option of UrlFetchApp.fetch().
var payload = JSON.stringify(data); is not used.
options is not used at var response = UrlFetchApp.fetch(url).getContentText();. In this case, it requests to the URL with the GET method.
var url = 'https://api.10000ft.com/api/v1/users/' + userid + '/time_entries?auth=key; is not enclosed by '.
Unfortunately, from the official document, I couldn't understand if it is required to send this data in json data or form data. So I proposed following 2 patterns. Please check them.
Modified script 1:
In this modified script, the data is sent as json data. Please set each variables. And also please set key.
From:
var payload = JSON.stringify(data);
var options = {
'method': 'POST',
'Content-Type': 'application/json',
'payload' : data,
};
var url = 'https://api.10000ft.com/api/v1/users/' + userid + '/time_entries?auth=key;
var response = UrlFetchApp.fetch(url).getContentText();
To:
var payload = JSON.stringify(data);
var options = {
'method': 'POST',
'contentType': 'application/json',
'payload' : payload,
};
var key = "###"; // <--- Please set your key.
var url = 'https://api.10000ft.com/api/v1/users/' + userid + '/time_entries?auth=' + encodeURIComponent(key);
var response = UrlFetchApp.fetch(url, options).getContentText();
Modified script 2:
In this modified script, the data is sent as form data. Please set each variables. And also please set key.
From:
var payload = JSON.stringify(data);
var options = {
'method': 'POST',
'Content-Type': 'application/json',
'payload' : data,
};
var url = 'https://api.10000ft.com/api/v1/users/' + userid + '/time_entries?auth=key;
var response = UrlFetchApp.fetch(url).getContentText();
To:
var options = {
'method': 'POST',
'payload' : data,
};
var key = "###"; // <--- Please set your key.
var url = 'https://api.10000ft.com/api/v1/users/' + userid + '/time_entries?auth=' + encodeURIComponent(key);
var response = UrlFetchApp.fetch(url, options).getContentText();
Note:
In above modified scripts, it supposes that each value in data object and key are correct.
Reference:
Class UrlFetchApp

SAPUI5 oData.V2 How to invoke a function after everything in a batch request is done?

I have an issue while making an SAPUI5 odata V2 batch request :
var that = this;
var oServiceModel = that.getModel("oServiceModel");
odataMod = this.getModel("Service");
odataMod.setUseBatch(true);
var aData = oServiceModel.getData();
var stupidService = _.filter(aData, function (ae) {
return ae.Info === "-N/A";
});
var i = 0 ;
_.forEach(stupidService, function (sap) {
oGlobalBusyDialog.setText("Deleting service :" + sap.ObjectID);
oGlobalBusyDialog.setTitle("Deleting Service");
oGlobalBusyDialog.open();
that.removeService(sap).then(function () {
if (i === 615) {
oGlobalBusyDialog.close();
}
}).catch(function () {});
});
my Delete function is like this:
removeService: function (service) {
var that = this;
return new Promise(
function (resolve, reject) {
odataMod.remove('/ProjectTaskServiceCollection(\'' + service.ObjectID + '\')/', {
success: function (oData) {
resolve(oData);
},
error: function (oResult) {
that.handleError(oResult);
oGlobalBusyDialog.close();
reject(oResult);
}
});
});
What's happening ,is that if I'm trying to delete 500 entry, and if 200 entry cannot be deleted, the error message gets displayed 200 times
How to make it in a way to only display the error message once ?
Also, I want to turn off the batch request once everything is done odataMod.setUseBatch(false); how to do it ?
*EDIT: *
I've manage to do :
var aDeffGroup = odataMod.getDeferredGroups();
//add your deffered group
aDeffGroup.push("deletionGroup");
for (var s = 0; s < 5; s++) {
odataMod.remove('/ProjectTaskServiceCollection(\'' + stupidService[s].ObjectID + '\')/', {
//pass groupid to remove method.
groupId: "deletionGroup"
});
}
odataMod.submitChanges({
// your deffered group id
groupId: "deletionGroup",
success: function() {
//Get message model data from Core and it contains all errors
// Use this data to show in dialog or in a popover or set this to your local model see below code
var aErrorData = sap.ui.getCore().getMessageManager().getMessageModel();
console.log(aErrorData);
}
});
yet stills my console.log(aErrorData); still prints multiple error message
Instead of doing individual deletion odata calls. Add these all remove methods in a single group, then call odatamod.submitChanges() method.
Example:
//get all deffered groups
var aDeffGroup = odataMod.getDeferredGroups();
//add your deffered group
aDeffGroup.push("deletionGroup");
//set it back again to odatamodel
odataMod.setDeferredGroups(aDeffGroup);
odataMod.remove('/ProjectTaskServiceCollection(\'' + service.ObjectID + '\')/', {
//pass groupid to remove method.
groupId: "deletionGroup"});
odataMod.submitChanges({
// your deffered group id
groupId:"deletionGroup",
success: function() {
//Get message model data from Core and it contains all errors
// Use this data to show in dialog or in a popover or set this to your local model see below code
var aErrorData = sap.ui.getCore().getMessageManager().getMessageModel();
});

Filter ODATA Model in sapui5 and bind with tilecontainer

I"m binding my tile container in xml view as
<TileContainer id="idsolutionContainer" tiles="{ path: 'dlCourses>/DLES_COURSE_CONTENT' }">
<tiles>
<dles:DLESScoreTile name="{dlCourses>LJ_TITLE}" topicId="{dlesScore>ID}" topic="{dlCourses>LJ_SOLUTION}" dles="{dlCourses>DLES}" id="tileDLESCourse" press=".handleCourseClick"></dles:DLESScoreTile>
</tiles>
</TileContainer>`
and on the backend on inint fucntion I'm trying to filter by LJ_SOLUTION but it doesn't work. it gives me all the courses. I'm getting LJ_SOLUTION from query string that's why i'm not filtring on front end.
the code is as
var coursePath = "/DLES_COURSE_CONTENT";
var filterByName = new sap.ui.model.Filter('LJ_SOLUTION', 'EQ', 'Analytics')
//sPath = "/DLES_SOLUTION_CONTENT?$filter=LJ_SOLUTION eq '" + sId + "')";
var courses = oView.getModel("dlCourses");
var courseData = oModel.getData(coursePath);
oView.bindElement({
path: coursePath,
filters: [ new sap.ui.model.Filter("LJ_SOLUTION",sap.ui.model.FilterOperator.EQ, "Analytics") ],
model: "dlCourses",
events: {
dataRequested: function() {
oView.setBusy(true);
},
dataReceived: function() {
oView.setBusy(false);
}
}
});
The network tab...
there is another request batch I don't understand completely but the request query is as
var oView = this.getView();
var oSolutionJourneyList = oView.byId("idsolutionContainer");
var oBinding = oSolutionJourneyList.getBinding("tiles");
if (oBinding) {
var oFilter = new sap.ui.model.Filter("LJ_SOLUTION", 'EQ', 'Analytics');
oBinding.filter([oFilter]);
}
Please remove the code “var courseData = oModel.getData(coursePath);”
because this loads the entire model. The bindElement will also create a request to load the required data only. Then, check the request which is created by bindElement to see if the path for “LJ_Solution” is correct.

unable to upload files using UploadCollection in SAPUI5

I am receiving 403 Forbidden error when I try to upload a file using UploadCollection.
The code in my view.js is:
var oOUpload = new sap.m.UploadCollection("oinspupload",{
multiple : true,
sameFilenameAllowed : true,
instantUpload : false,
uploadUrl : "/sap/opu/odata/sap/ZACCBILL_SRV/FileSet",
/* uploadComplete : function(oEvent){
//alert ("File Uploaded successfully");
// oController.fileUpload(oEvent);
}, */
fileDeleted : function(oEvent){
oController.fileDelete(oEvent);
},
fileRenamed : function(oEvent){
alert ("File renamed successfully");
//oController.fileRename(oEvent);
}
});
The code in my view.controller is:
OData.request({
requestUri : sServiceUrl,
method : "GET",
headers :
{
"X-Requested-With" : "XMLHttpRequest",
"Content-Type" : "application/atom+xml",
"DataServiceVersion" : "2.0",
"Authorization" : AuthToken,
"X-CSRF-Token" : "Fetch"
}
},
function(data, response) {
debugger;
if(sap.ui.Device.browser.chrome || sap.ui.Device.browser.msie || sap.ui.Device.browser.safari){
header_xcsrf_token = response.headers['x-csrf-token'];
}else if(sap.ui.Device.browser.firefox){
header_xcsrf_token = response.headers['X-CSRF-Token'];
}
xcsrf_token_ref.header_xcsrf_token = header_xcsrf_token;
csrftoken = xcsrf_token_ref.header_xcsrf_token;
debugger;
uploadattachments(xcsrf_token_ref);
},
function(err) {
debugger;
var request = err.request; // the request that was sent.
var response = err.response; // the response that was received.
alert("Error in Get -- Request "
+ request + " Response "
+ response);
});
function uploadattachments(token){
debugger;
var uploader;
uploader= sap.ui.getCore().byId("oinspupload");
var aItems = uploader.getItems();
var slug, sequence;
for (i = 0; i < aItems.length; i++) {
sequence = i + 1;
slug = "CONTAINERID1000040100;STATUSIB;SEQUENCE" + sequence+ ";FILENAMECamera.png" ;
uploader.addHeaderParameter(new sap.m.UploadCollectionParameter({name: "slug", value: slug }));
debugger;
uploader.addHeaderParameter(new sap.m.UploadCollectionParameter({name: "X-Csrf-Token", value: token.header_xcsrf_token }));
uploader.upload();
}
}
Please don't mind the missing parenthesis as the code above is not the complete code.
The above code works fine with fileuploader. I am sure the issue is that the uploadcollection is not passing the fetched CSRF Token properly but I am unable to figure out what's wrong.
Finally Found the solution myself with the help of the following blog
http://scn.sap.com/community/developer-center/front-end/blog/2016/03/29/using-the-uploadcollection-to-uploaddownload-archivelink-files-via-gateway
Upload Collection only works with instantUpload as true and does not work with instantUpload as false as of version 1.32.X. UploadCollection is Buggy and is yet to be rectified in the future versions. Also the CSRF token validation needs to be done in the change event. Below is the code:
View.js
var oOUpload = new sap.m.UploadCollection("oinspupload",{
multiple : true,
sameFilenameAllowed : false,
instantUpload : true,
uploadUrl : "/sap/opu/odata/sap/ZACCBILL_SRV/FileSet",
fileDeleted : function(oEvent){
oController.fileDelete(oEvent);
},
fileRenamed : function(oEvent){
alert ("File renamed successfully");
},
change: function(oEvent) {
debugger;
csrftoken = xcsrf_token_ref.header_xcsrf_token;
var oUploadCollection = oEvent.getSource();
var oCustomerHeaderToken = new sap.m.UploadCollectionParameter({
name : "x-csrf-token",
value : csrftoken
});
oUploadCollection.addHeaderParameter(oCustomerHeaderToken);
},
});
All header params must be added from "change" function. If you add it after, they won't be recieved on Backend.
Also, It is possible upload files with instantUpload=false. You only need bind uploadUrl parameter with a paremeter of view's model, and dynamically, it will change when you change the url.
For example:
View element:
<UploadCollection instantUpload="false" uploadUrl="{ResourceModel>/sServiceUrl}"/>
Controller onInitFunction:
var resourcemodel = this.getOwnerComponent().getModel("ZGW_PURCHREQ_01_SRV");
var oDataResource = {
sServiceUrl: resourcemodel.sServiceUrl + "/FileSet"
};
var jsonResource = new JSONModel(oDataResource);
this.getView().setModel(jsonResource, "ResourceModel");
When you fire upload, it will send a petition to uploadUrl defined on "sServiceUrl" of "ResourceModel".
Other option is set upload url and/or new header params before fire upload function with:
var oUploadCollection = this.getView().byId("UploadCollection");
var sServiceUrl = resourcemodel.sServiceUrl + "/FileSet";
var headerBanfn = null;
for (var i = 0; i < oUploadCollection._aFileUploadersForPendingUpload.length; i++) {
headerBanfn = new sap.ui.unified.FileUploaderParameter({
name: "banfn",
value: "123456"
});
oUploadCollection._aFileUploadersForPendingUpload[i].setUploadUrl(sServiceUrl);
oUploadCollection._aFileUploadersForPendingUpload[i].addHeaderParameter(headerBanfn);
}
oUploadCollection.upload();
I hope it was useful.

Making a POST request to Tumblr's API inside a Chrome Extension

I'm trying to make a text post to Tumblr using their API and chrome_ex_oauth.
API: http://www.tumblr.com/docs/en/api/v2#posting
chrome_ex_oauth: http://code.google.com/chrome/extensions/tut_oauth.html
The whole process of getting authorized works. What I can't get to work is doing a POST. I'm doing the following:
Edit: I've updated the code to reflect Rob W's correct suggestion about the body field
var stringify = function (parameters) {
var params = [];
for(var p in parameters) {
params.push(encodeURIComponent(p) + '=' +
encodeURIComponent(parameters[p]));
}
return params.join('&');
};
var onAuthorized = function() {
var url = 'http://api.tumblr.com/v2/blog/jindie.tumblr.com/post';
var request = {
'method': 'POST',
'headers':{
'Content-Type':'application/x-www-form-urlencoded'
},
'body': stringify({
'type': 'text',
'state': 'draft',
'title': 'Test post...',
'body': 'Hello, World!'
})
};
oauth.sendSignedRequest(url, function(responseText, xhr){alert(responseText);}, request);
};
oauth.authorize(onAuthorized);
I've been examining the code, and thinking what could be wrong, but I seriously have no idea. Do you?
Do you know where I'm going wrong?
When the documentation doesn't help have a look at the source code, chrome_ex_oauth.js.
You have to use 'body' instead of 'parameters':
var request = {
'method': 'POST',
'body': {
Debugging
In order to find the cause, I followed these steps (annotated my thoughts):
Apparently, the post body is empty. So, the implementation of the API must be wrong.
Ctrl + F sendSignedRequest:
ChromeExOAuth.prototype.sendSignedRequest = function(url, callback, opt_params) {
var method = opt_params && opt_params['method'] || 'GET';
var body = opt_params && opt_params['body'] || null;
var params = opt_params && opt_params['parameters'] || {};
var headers = opt_params && opt_params['headers'] || {};
var signedUrl = this.signURL(url, method, params);
// Hmm...? Where is `params` being passed...?
ChromeExOAuth.sendRequest(method, signedUrl, headers, body, function (xhr) {
if (xhr.readyState == 4) {
callback(xhr.responseText, xhr);
}
});
};
signURL doesn't modify params, so that's not a problem.
Ctrl + F sendRequest:
ChromeExOAuth.sendRequest = function(method, url, headers, body, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(data) {
callback(xhr, data);
}
xhr.open(method, url, true);
if (headers) { . . . }
xhr.send(body); // <-- !!!
};
Got it! body has to be used instead of parameters.
Backtracks the body variable to the request['body'] (see 2).

Resources