Google App Script error 404: Response not defined - post

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

Related

Flutter multipart request along name value pair to server

I have to send to multipart request to server along with name value pair to server i mean id along with it. Can you please help me how to send id along with multipart files.
Upload() async {
var stream = new https.ByteStream(DelegatingStream.typed(Files[0].openRead()));
var length = await Files[0].length();
var stream1 = new https.ByteStream(DelegatingStream.typed(Files[1].openRead()));
var length1 = await Files[1].length();
var stream2 = new https.ByteStream(DelegatingStream.typed(Files[2].openRead()));
var length2 = await Files[2].length();
var uri = Uri.parse(openurl);
var request = new https.MultipartRequest("POST", uri);
var multipartFile1 = new https.MultipartFile('XX', stream, length,
filename: basename(Files[0].path));
var multipartFile2 = new https.MultipartFile('YY', stream1, length1,
filename: basename(Files[0].path));
var multipartFile3 = new https.MultipartFile('ZZ', stream2, length2,
filename: basename(Files[0].path));
//contentType: new MediaType('image', 'png'));
request.files.add(multipartFile1);
request.files.add(multipartFile2);
request.files.add(multipartFile3);
request.fields.addAll(other)
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
Thanks in advance
Sathish
I just had a problem similar to this. I had to upload an image along a key-value pair. I realize that I could upload the key-value pair using request.fields:
var request = new http.MultipartRequest("POST", uri);
request.fields['description'] = 'description';
request.fields['File-Name'] = 'FILENAME.jpg';
request.fields['qr_size'] = '3';

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.

How to make ol.source.ImageWMS send POST request

In our project, we're using OpenLayers-3's ol.source.ImageWMS to show image provided by Mapserver WMS. Since we're using Mapserver runtime substitution, our request can become quite long, which could cause a problem for a GET request.
Is there a way to make ol.source.ImageWMS send POST request?
I answer this just for the reference based on this Openlayers dev thread, hopefully it will help someone in the future!. I needed to pass a very long CQL request to a Geoserver wms, and GET was limited in size, so I used POST like the following:
var POSTWMSLayer = new ol.layer.Image({
source: new ol.source.ImageWMS({
url: 'https://test.server.com/geoserver/wms',
params: {
'LAYERS': 'firstworkspace:states',
'CQL_FILTER':'gid IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,3159)
},
serverType: 'geoserver',
imageLoadFunction: function (image, src) {
var img = image.getImage();
if (typeof window.btoa === 'function') {
var urlArray = src.split("?");
var url = urlArray[0];
var params = urlArray[1];
var xhr = new XMLHttpRequest();
xhr.onload = function (e) {
if (this.status === 200) {
var uInt8Array = new Uint8Array(this.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var type = xhr.getResponseHeader('content-type');
if (type.indexOf('image') === 0) {
img.src = 'data:' + type + ';base64,' + window.btoa(data);
}
}
};
xhr.open('POST', url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.responseType = 'arraybuffer';
xhr.send(params);
} else {
img.src = src;
}
}
})
});
Actually the httprequest is the problem, use Httprequest Post method instead of get method in ol.source.ImageWMS?
Get request can not pass long string parameters. For big parameters we need to pass request with post method.
Now the bottleneck is that the post method is not supported in openlayers 3 whereas in old version it had support for post method.
Note: This is old OpenLayers code
var query = new OpenLayers.Layer.WMS.Post("My Layer",
'http://192.168.6.51:8090/geoserver/VP/wms', {
LAYERS : 'Namespace:LayerName',
sld_body : strSld_body,
format : 'image/jpeg',
transparent : 'true'
},
{
unsupportedBrowsers: [],
isBaseLayer: false,
yx : {'EPSG:4326' : true}
} );
In openlayers 3 there may be a workaround.

NetworkError: 403 Forbidden - http://www.googleapis.com/fusiontables/v1/query? 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).

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