I am learning how to code so sorry if this is too basic, but I am getting troubles here:
I've been trying to invoke the Google Natural Language API, to give me information about information on 210 rows of my Google Spreadsheet (the whole table has 211 rows). I would like to save the results on 1 Json File.
I am trying to run a loop with the code below, but I am getting the Json file only with the information corresponding to the 1st row. Tried as well to put the "Driveapp.createFile line of code" inside of the loop function, but then I have many Json files, each one with the information corresponding to one row. And what I would like is 1 Json file, with the corresponding information of the 210 rows.
I would appreciate your help, please.
function analyzeText() {
var client = "Spreadsheet_ID";
var query = SpreadsheetApp.openById(client).getSheetByName("1. Template");
var result = SpreadsheetApp.openById(client).getSheetByName("Teste - Natural Language API");
var lrow = query.getLastRow();
for(var i=2; i<=211;i++)
{
var text = query.getRange(i,211).getValue()
var requestUrl = [
'https://language.googleapis.com/v1beta2/documents:analyzeEntities?key=',
'API_KEY_XXXXXXXXXXXXXXXXXXX'
].join("");
var data = {
"document": {
"language": "en-us",
"type": "PLAIN_TEXT",
"content": text
},
"encodingType": "UTF8"
};
var options = {
method : "POST",
contentType: "application/json",
payload : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(requestUrl, options);
var data = JSON.parse(response);
}
DriveApp.createFile('response3.json', response, MimeType.PLAIN_TEXT);
}
I would suggest you instead of the approach you are taking (using a for loop and the method getValue(), which it's a slow method to call in a loop), consider this one I am giving you with this code:
function analyzeText() {
var clientId = "your-sheet-id";
var ss = SpreadsheetApp.openById(clientId);
var templateSheet = ss.getSheetByName("1. Template");
// .getRange(row, column, numRows) -> From the first row and col, take the next 4 rows
// Modify these arguments depending in where you want to start and how many rows you want
var data = templateSheet.getRange(1, 1, 4).getValues();
// You will get an array 2D, using join you will able to get an string from
// all the elements in that array
var text = data.join();
var requestUrl = [
'https://language.googleapis.com/v1beta2/documents:analyzeEntities?key=',
'API_KEY_XXXXXXXXXXXXXXXXXXX'
].join("");
// Now text will have all your cell values and you only need to do one request
var data = {
"document": {
"language": "en-us",
"type": "PLAIN_TEXT",
"content": text
},
"encodingType": "UTF8"
};
var options = {
method : "POST",
contentType: "application/json",
payload : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(requestUrl, options);
var data = JSON.parse(response);
DriveApp.createFile('response3.json', response, MimeType.PLAIN_TEXT);
}
In this way, you only need to make one request and it will be faster than running 211 times your loop. I would also recommend you to check:
Apps Script Quotas: Running your code as you have it, it would give you more chances of hitting these quotas.
Best Practices: You can check more about the best practices so you can have a better idea about why I was telling you to avoid the getValue() method in a loop.
Related
I have been stumped on this for a while. I am fairly new to Google script app and wanted to see if there is a way to make this happen. So far, I've used a few methods within Google Sheet but seem to not get it working.
The code below does give me an output of all the data, however, the data that is nested in the data.custom_fields[x] has multiple objects that is separated by ",". I would like to be able to filter out the other key words and just use whatever is inside "display_value=". The display_value= is not always in the same area so have to run a search for them.
I am assuming some kind of If statement would be used here..
An example of the object is:
{type=x, resource_subtype=x, created_by={name=x, gid=x, resource_type=x}, display_value=Cool Value, description=x, enabled=x, resource_type=custom_field, gid=x, enum_options=[x.lang.Object;x, enum_value={x}, name=x}
I've tried to split function as well but not sure how to filter out the words I need.
function Users() {
var options = {
"headers" : {
"Authorization": "API Key here"
}
}
var response = UrlFetchApp.fetch("URL here", options);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheet = ss.getSheetByName("Tab Name here"); // specific sheet name getSheetByName(""); alternatively use ss.getActiveSheet()
var dataAll = JSON.parse(response.getContentText()); //
var dataSet = dataAll.data; // "data" is the key containing the relevant objects
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([
data.gid,
data.name,
data.permalink_url,
data.due_on,
data.custom_fields[1],
data.custom_fields[2],
data.custom_fields[4],
data.custom_fields[5],
data.custom_fields[6],
data.custom_fields[7],
data.custom_fields[8],
data.custom_fields[9],
]); //your JSON entities here
}
// [row to start on], [column to start on], [number of rows], [number of entities]
dataRange = sheet.getRange(2, 1, rows.length, 12);
dataRange.setValues(rows);
Thank you in advance!
Example Image of JSON imported data
Although they appear separated by ,'s, that is only how they're displayed in the log. Because you're using JSON.parse, you're receiving/converting to an Object, not a string.
Because data.custom_fields is an array of objects, you can access the property/key values as : data.custom_fields[x].display_value.
Learn More:
JSON.parse()
Accessing Object Properties
If you want to extract display_value, try
let myVal = myData.match(/(?<=display_value=)[^,]+/g)[0]
I guess that myData could be data.custom_fields[5], so replace it by
data.custom_fields[5].match(/(?<=display_value=)[^,]+/g)[0]
I'm currently trying to do an API call to update multiple tickets at once using ticket IDs. These ticket IDs are stored on google Sheets since I have the script running there. I would appreciate someone sharing how to use the REST method and get it working! Thank you!
Problem: I'm not sure how to update multiple tickets using the following
If I try with 1 ticket ID, example PUT https://company.zendesk.com/api/v2/tickets/12345 This is from https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-ticket. This will only update 1 ticket, fair.
Original Code: PUT /api/v2/tickets/{ticket_id} I know to just replace {ticket_id} with a ticket number. If I put something like https://company.zendesk.com/api/v2/tickets/{ticket_id} it will throw me an error.
When it comes to multiple:
(Source: https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-many-tickets). How do I write the code in a way I can read multiple ticket ids at once without having to repeat it 10 time if there are 10 tickets?
PUT https://company.zendesk.com/api/v2/tickets/update_many
Zendesk's example is saying it like this:
{
"tickets": [
{ "id": 1, "status": "solved" },
{ "id": 2, "status": "pending" }
]
}
When I saw your question, I thought that your goal might be able to be achieved by modifying this sample script. But, from your question, in your situation, I thought that when a sample modified script is shown, it might be useful for you and other users. So I posted a modified script instead of the duplicated question.
Prepare Spreadsheet:
This script retrieves the values from Spreadsheet. So, please set id and status to the columns "A" and "B" of the header row. And, please set the values of id and status.
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet. And please set the variables.
function sample() {
var url = 'https://{subdomain}.zendesk.com/api/v2/tickets/update_many.json'; // Please set your URL.
var user = '###'; // Please set your user name.
var pwd = '###'; // Please set your passworkd.
var sheetName = "Sheet1"; // Please set the sheet name.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
var [headers, ...rows] = sheet.getDataRange().getDisplayValues();
var tickets = rows.map(r => {
var temp = {};
headers.forEach((h, j) => {
if (r[j] != "") temp[h] = r[j];
});
return temp;
});
var options = {
'method': 'PUT',
'headers': { 'Authorization': "Basic " + Utilities.base64Encode(user + ':' + pwd) },
'payload': JSON.stringify({ tickets }),
'contentType': 'application/json',
'muteHttpExceptions': true
};
var response = UrlFetchApp.fetch(url, options);
console.log(response.getContentText());
}
When the values are retrieved from the Spreadsheet, JSON.stringify({ tickets }) is as follows.
{
"tickets": [
{"id": "1", "status": "status1"},
{"id": "2", "status": "status2"},
{"id": "3", "status": "status3"},
,
,
,
]
}
Note:
I think that if your values of user and pwd are invalid, an error occurs. At that time, please confirm your values again.
References:
Batch updates of Tickets
At PUT /api/v2/tickets/update_many, the document says Accepts an array of up to 100 ticket objects, or a comma-separated list of up to 100 ticket ids.. Please be careful about this.
Related thread.
Zendesk Update Users API From Google Sheets
fetch(url, params)
I have an array of arrays of strings saved in a database column as a varchar:
[["ben"],["john","mike"],["ben"]]
I want to parse the data back into an array of arrays, so I can show the data on the screen. While attempting to do this, I ran into an awkward and annoying problem:
Here's the JSON response that is generated on the server and sent back to the client:
var response = "[{\"Names\":\""+ rows[i].Names + "\"}]";
res.send(response);
Here's the client code I wrote to parse the data:
jQuery.ajax({
type: "GET",
url: ...,
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).done(function(data) {
jQuery.each(JSON.parse(data), function(i, parsedData) {
var names = JSON.parse(parsedData.Names);
var labels = "";
for (var n = 0; n < names.length; n++) {
var label = "<label>" + names[n] + "</label>";
labels = labels + label;
}
console.log(labels);
});
});
This is the error i'm getting:
Here's the JSON validation:
How can I solve this?
There is a simple rule:
Never use string tools to create or modify JSON. No string concatenation (+), no string replace and God forbid no regex.
The only way to produce JSON is to use a JSON serializer on a data structure. And the only way to manipulate JSON is to parse it, modify the data structure, and then serialize it again. JSON itself is to be treated as a constant, for all intents and purposes.
Your server code violates that rule. Change it like this:
var responseData = [{
Names: rows[i].Names
}];
var response = JSON.stringify(responseData);
In the above, responseData is a data structure. You are free to modify it. response is derived from that. You are not free to modify it, the only thing you can do with response is to write it to the client.
Note that rows[i].Names might be JSON itself, so you end up with a double-encoded value in your response.
Provided the server sends the Content-Type: application/json header, the client can use this:
jQuery.get("...").done(function(data) {
// data is already parsed here, you don't need to parse it
jQuery.each(data, function(i, item) {
// item.Names is not yet (!) parsed here, so we need to parse it
var names = JSON.parse(item.Names);
var labels = names.map(function (name) {
return $("<label>", {text: name});
}
console.log( labels );
});
});
If you don't want to call JSON.parse() on the client, you have to call it on the server:
var responseData = [{
Names: JSON.parse(rows[i].Names)
}];
var response = JSON.stringify(responseData);
I have a below set of code to get the table data in an array and pass the same to servlet through ajax call. But i am getting null. Please someone help me on what my mistake / how to get the required data since i am new to this servlet and web app. So far i tried with some examples given in SO. but i am clueless to get my expected data.
var myTableArray = [];
$("table#itemtable tr").each(function() {
var arrayOfThisRow = [];
var tableData = $(this).find('td');
if (tableData.length > 0) {
tableData.each(function() { arrayOfThisRow.push($(this).text()); });
myTableArray.push(arrayOfThisRow);
}
});
alert(myTableArray);
$.ajax({
url:"insertmasteritem",
type:"POST",
dataType:'json',
data: {json:myTableArray},
success:function(data){
// codes....
},
});
Servlet code
String[] myJsonData = request.getParameterValues("json[]");
System.out.println("myJsonData.length"+myJsonData.length);
for (int i = 0; i < myJsonData.length; i++) {
String[] innerArray=myJsonData[i].split(",");
System.out.println(myJsonData[i]);
}
Send your Json data like this
$.ajax({
url:"insertmasteritem",
type:"POST",
dataType:'json',
data:myTableArray,
success:function(data){
// codes....
},
});
and In Servlet Class
JSONObject jsonObj= new JSONObject(request.getParameter("myTableArray"));
Iterator it = jsonObj.keys();
while(it.hasNext())
{
String jsonKey = (String)it.next();
String jsonValue = jsonObj.getString(jsonKey);
System.out.println(jsonKey + " --> " + jsonValue );
}
Well, you need to send a properly formatted JSON object (as a string) to the servlet. Possibly the easiest way to do this is to create some javascript objects and fill an array with these objects. The array data should then be
converted to a JSON string (using JSON.stringify). I'm going to hardcode object values (but you will get them from your table)
Javascript code
function generateJson(){
var myObjArr = [];
//you will typically have just one object (e.g. myObj, which you will fill in your ajax table loop
//myObj.v1 = v1_val;
//myObj.v2 = v2_val;
...
//myObjArr[i] = myObj; //
myObj1 = { "v1": "Orange", "v2": "ABC", "v3":10,"v4":"OK" };
myObj2 = { "v1": "Apple", "v2": "XYZ", "v3":25,"v4":"OK" };
myObjArr[0] = myObj1;
myObjArr[1] = myObj2;
var jsonObjStr = JSON.stringify(myObjArr);
//you can now use jsonObjStr to send your data to the servlet
// document.getElementById("json").innerHTML = jsonObjStr;//this is just added for testing purposes
}
The generated JSON
[{"v1":"Orange","v2":"ABC","v3":10,"v4":"OK"},{"v1":"Apple","v2":"XYZ","v3":25,"v4":"OK"}]
As you can see, the json string starts with a [ (which denotes an array). You may have to change this to start with a { (and with a } ) depending on how your JSON parser works ({} denote an object).
For the servlet part, it depends on the actual JSON parser you're using. Try to use some of the suggestions provided by others. I can provide some code using Jackson though, but you will have to add the Jackson library to your classpath.
why you are getting parameter value as JSON[]
String[] myJsonData = request.getParameterValues("json[]");
I'm trying to do something that is beyond my junior coding capabilities. I have created a function that will parse API data into Google Spreadsheet, but no matter what I've tried (and searched online for answers), the results are only being posted to a single column.
The code I am using currently is:
function getAPIdata (URL,key){
var apiurl = "https://example.com/Site/"+URL+"/students?&ID="+key
var rank_data = parse(apiurl)
var result = []
var data_dictionary = rank_data.Student
for (var i in data_dictionary){
result.push(data_dictionary[i].Name)
result.push(data_dictionary[i].Grade)
}
return result
}
The data in question that is being parsed is
Student": [
{
"Name": Adam,
"Grade": 75
},
{
"Name": Alan,
"Grade": 90
}
What is happening is that when I call the function in excel I am getting a single column with:
Adam
75
Alan
90
What I would like to do is have the following (spaces here delineate another column)
Adam 75
Alan 90
Basically, I have a 1x4 output and I would like a 2x2 output. Is there anyway I could do this? I realize I can call the function twice and push different data sets each time, but in this case I can only call the API once for all data. I thought about potentially pulling the data, caching it but before I delve down learning a path that will not bear fruit, I was hoping some of the experts here could weigh in.
Thanks for reading!
I think you can use [] and push a row at a time, like
function getAPIdata (URL,key){
var apiurl = "https://example.com/Site/"+URL+"/students?&ID="+key
var rank_data = parse(apiurl)
var result = []
var data_dictionary = rank_data.Student
for (var i in data_dictionary){
result.push([data_dictionary[i].Name, data_dictionary[i].Grade])
}
return result
}