I am wondering why the tokens through API should be passed as POST x-www-form-urlencoded ONLY, and not as JSON. This brings many issues. One issue, among others, is when you encode the URL the "value" lenght must be short and nearly just plain text, not URL and/or HTML, otherwise you will pass the 2048 character limit that some services like Google has for URLFetch, leaving this end point nearly usless.
I did try compressing the URL through gzip, shortening the URL thoroug few services, but the Marketo end point refuses to accept those, so the question is why , why not to accept a JSON payload?
Solved! Go to Solution.
I found the solution, I think it was a long night...
DON't do that
// Create the API endpoint URL with placeholders
var apiUrl = "https://xxx-xxx-xx.mktorest.com/rest/asset/v1/folder/" + program + "/tokens.json?folderType=Program&name=" + name + "&type=" + type + "&value=" + value;
// Compress the API URL
//var compressedApiUrl = compressUrl(apiUrl);
// Check if compressed API URL length exceeds 2082 characters
if (apiUrl.length > 2082) {
Logger.log("Compressed API URL length exceeds 2048 characters. Skipping this row.");
var ui = SpreadsheetApp.getUi();
ui.alert( "URL Length Exceeded " + apiUrl.length, "URL length for Row " + i + " exceeds 2082 characters. Skipping this row.", ui.ButtonSet.OK);
continue; // Skip this row
}
// Make the API request with the Marketo access token
var response = UrlFetchApp.fetch(apiUrl, {
method: "post",
contentType: "application/x-www-form-urlencoded",
headers: {
"Authorization": "Bearer " + accessToken
DO that
// Prepare the payload as a URL-encoded string
var payload = "folderType=Program&name=" + name + "&type=" + type + "&value=" + value;
// Make the API request with the Marketo access token
var response = UrlFetchApp.fetch("https://xxx-xxx-xxx.mktorest.com/rest/asset/v1/folder/" + program + "/tokens.json", {
method: "post",
contentType: "application/x-www-form-urlencoded",
headers: {
"Authorization": "Bearer " + accessToken
},
payload: payload
});
“Nearly useless” is a wild overstatement. If you choose to use a client library that doesn’t actually support HTTP but enforces fake payload (entity-body) limits, that’s not Marketo’s fault.
Why would you use an app that pretends you can’t send large payloads to an HTTP server? The Fetch API doesn’t have a limit like that — the thing you’re referring to is a deliberately restricted wrapper around Fetch. One simply can’t expect to use standard APIs with a non-standard library. The same would be true for uploading images above 2Kb (or even smaller in Base64). It’s not the right tool.
I haven't chosen the client, the thing is that copy writers would't use Postman or Mulesoft, but instead a Google document. The idea was not to make marketing people to go to an API client to create/update tokens but from the document itself push/create changes. Here are the limitattions .
https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app
Of course you chose the client: AppScript is one of millions of HTTP clients. It may be the only client supported by a platform you chose to work with, but it's still your choice.
Also bear in mind that while the endpoint formally expects application/x-www-form-urlencoded, it is implemented to support not only multipart/form-data with UTF-8 parts but also UTF-8 IRIs, not just URIs.
There’s no reason for these encodings to be a barrier vs. JSON.
(Really unlikely that JSON would be more space-efficient than an IRI in any practical scenario. That is, the difference in byte length would be at most a handful of bytes in either direction.)
I found the solution, I think it was a long night...
DON't do that
// Create the API endpoint URL with placeholders
var apiUrl = "https://xxx-xxx-xx.mktorest.com/rest/asset/v1/folder/" + program + "/tokens.json?folderType=Program&name=" + name + "&type=" + type + "&value=" + value;
// Compress the API URL
//var compressedApiUrl = compressUrl(apiUrl);
// Check if compressed API URL length exceeds 2082 characters
if (apiUrl.length > 2082) {
Logger.log("Compressed API URL length exceeds 2048 characters. Skipping this row.");
var ui = SpreadsheetApp.getUi();
ui.alert( "URL Length Exceeded " + apiUrl.length, "URL length for Row " + i + " exceeds 2082 characters. Skipping this row.", ui.ButtonSet.OK);
continue; // Skip this row
}
// Make the API request with the Marketo access token
var response = UrlFetchApp.fetch(apiUrl, {
method: "post",
contentType: "application/x-www-form-urlencoded",
headers: {
"Authorization": "Bearer " + accessToken
DO that
// Prepare the payload as a URL-encoded string
var payload = "folderType=Program&name=" + name + "&type=" + type + "&value=" + value;
// Make the API request with the Marketo access token
var response = UrlFetchApp.fetch("https://xxx-xxx-xxx.mktorest.com/rest/asset/v1/folder/" + program + "/tokens.json", {
method: "post",
contentType: "application/x-www-form-urlencoded",
headers: {
"Authorization": "Bearer " + accessToken
},
payload: payload
});
You aren't URI-encoding nor IRI-encoding, just concatenating!
This code is incorrect for sending to an x-www-form-urlencoded endpoint, unless you're not showing the part where you actually encode reserved characters.
not showing
/ Iterate through each row (skip header row)
for (var i = 1; i <= numIterations; i++) {
// Get the values for the current row
var program = encodeURIComponent(data[i][programIndex]);
var name = encodeURIComponent(data[i][nameIndex].substring(0, 50)); // Trim "name" to 50 characters
var type = encodeURIComponent(data[i][typeIndex]);
var value = encodeURIComponent(data[i][valueIndex]);
OK, that’s good. We don’t want people to get the idea that URI encoding is just a matter of concatenating values with & and =.
It sounds like you don’t actually have a problem with Apps Script’s simplistic HTTP client, but you could run across a similar client that limited the request or response payload size for resource management reasons. For example, Zapier limits HTTP responses to 6 MB. But it’s a choice to use Zapier for such things.
The idea here is create an interface , in this case Google document, suitable for someone that doesn't know anything about Martketo, APIs or anything, so it just fills up the copy, has a menu that says update content and boom.. It also puts some velocity together (in a text token 😉... I know I know ) so at the end the asset gets personalized.