InDesign scripting of the Socket object yields cryptic error message - javascript

I'm working on a broadcast e-mail template that would pull the latest three articles off our blog from an RSS feed and insert the relevant sections into the document.
I looked at the documentation, and based on the bit about the File object, some of my own debugging, and an InDesign forum post I've learned that it's not possible to use the File object to source an online XML file.
The alternative (without resorting to an external script, one of which didn't work for me anyways), it seems, is to use the Socket object. So I went back to the documentation and copied/pasted this code verbatim from there:
reply = "";
conn = new Socket;
// access Adobe’s home page
if (conn.open ("www.adobe.com:80")) {
// send a HTTP GET request
conn.write ("GET /index.html HTTP/1.0\n\n");
// and read the server’s reply
reply = conn.read(999999);
conn.close();
}
When I ran it, I received this descriptive error message:
A search for "89858 javascript error" yielded nothing useful.
So I'm stuck. Either Adobe's code sample has an error, or, more likely, there's something wrong on my end. If I had to guess, I'd guess that it's some kind of proxy problem, but I don't know for sure and don't know how to find out.
Can anyone help? The principles of the Socket object make sense to me, but if I can't get even the sample to work, I don't really have anywhere to go with this.

The error above occurs when you return certain objects (XML, Socket) from a function call, but the return values does not get assigned anywhere.
function test() {
var xml = new XML('<test />');
return xml;
}
test();
The above will cause an error. To get around it you have to assign the return value somewhere.
var result = test();
Try to put all collect all function calls result. I am not sure which one causes the error.
var reply = "";
var conn = new Socket;
// access Adobe’s home page
if (conn.open ("www.adobe.com:80")) {
// send a HTTP GET request
var result = conn.write ("GET /index.html HTTP/1.0\n\n");
// and read the server’s reply
reply = conn.read(999999);
var close = conn.close();
}

Related

The remote endpoint could not be called, or the response it returned was invalid. (alexa, aws)

I'm currently getting into developing alexa-skills. This is in fact the 1st time I'm trying this and I kinda works out good so far. However, I stumbled upon a problem which seems to be wide-spreaded but I couldn't find an answer how to solve it.
First things first:
I started this skill by following a tutorial. It might be that this tutorial is outdated and therefore this error appears.
I created a skill from the scratch and it works to the part where the LaunchRequest is invoked:
As you can see, I get my response as expected. (works on the test-environment as well as on alexa itself). Now, when try to call an IntentRequest, I just get the error-message:
The remote endpoint could not be called, or the response it returned was invalid.
As I can tell from the picture / request, the correct intent-request is called (in my case getSubscriberCount ) - And this is the point where I have no idea anymore on how to resolve this problem.
To keep things short, this here is the JS-part for the Intent:
case "IntentRequest":
// Intent Request
console.log(INTENT REQUEST)
switch(event.request.intent.name) {
case "GetSubscriberCount":
var endpoint = "my url"
var body = ""
https.get(endpoint, (response) => {
response.on('data', (chunk) => { body += chunk })
response.on('end', () => {
var data = JSON.parse(body)
var subscriberCount = data.items[0].statistics.subscriberCount
context.succeed(
generateResponse(
buildSpeechletResponse(`Du hast momentan ${subscriberCount} Abonnenten`, true),
{}
)
)
And this is causing my problems. To test what exactly is wrong, I tried the following:
Called the endpoint in my browser --> Correct output
Adjusted the "response" to the minimum to see if that works --> didn't work
Checked several sources related to this error --> didn't help either
I saw some approaches to get rid of this, since this seems to be a common issue, but I got lost. Someone mentioned an environment variable, which I couldn't put my hands on. Another one suggested to run the JSON request manually, which I tried, but leading to the same error.
Hopefully you can help me out here.
Assuming you AWS lambda, it might be because you didn't create your response right or your AWS lambda function had a error.

javascript - make facebook page post

I am not using the Javascript SDK because that is client-side whereas I'm making a server-side call.
I want to make a page post so that I can make an ad creative with it. I can do the call perfectly fine in the Graph API Explorer tool, but I cannot make the same call (with the same long-lived access tokens that continue to work in the Graph Explorer) from Javascript. Here is my code:
tok = <valid and never expiring user token>;
var pg_tok = <valid and never expiring page token>;
var act_id = <account_id>;
var pg_id = <page_id>;
var call_to_action = 'INSTALL_MOBILE_APP';
var fb_app_url = 'https://itunes.apple.com/us/app/id284882215';
var msg = 'Test creative, ya see';
var pic_url = 'https://s3.amazonaws.com/<path_to_my_image>';
var ROOT = 'https://graph.facebook.com/';
var pagepost_endpoint = ROOT+pg_id+'/feed';
console.log(pagepost_endpoint);
var pagepost_params = {
access_token: pg_tok,
call_to_action: {
type: call_to_action,
value: {link: fb_app_url}
},
message: msg,
picture: pic_url,
published: false
};
console.log(pagepost_params);
var pagepost_res = HTTP.post(pagepost_endpoint, {params: pagepost_params});
console.log(pagepost_res);
I have played around a bunch with params vs. data for where pagepost_params goes in the HTTP.post that is giving the error (that is Meteor's HTTP btw).
-Putting everything in params gives the error: {"error":{"type":"Exception","message":"No Call To Action Type was parseable. Please refer to the call to action api documentation","code":1373054,"is_transient":false}}.
-Putting everything in data gives the error: {"error":{"message":"(#200) This API call requires a valid app_id.","type":"OAuthException","code":200}}.
-Putting access_token in params and everything else in data gives the error: {"error":{"message":"Invalid parameter","type":"FacebookApiException","code":100,"error_subcode":1349125}}.
One more clue for everyone, if I change the HTTP.post to HTTP.get, and just put access_token in params and include no other parameters (in params or in data), the call succeeds and I see past posts I have made on this page through the Graph Explorer (only the ones with published: true, though), so the access token and endpoint do work, just something is faulty about POST-ing instead of GET-ing and the specific parameters I'm using.
Have you tried posting to /photos instead of /feed? The error subcode is the same as mentioned here Posting to facebook wall using graph api
Hope this helps
Turned out to be an issue with Meteor's HTTP. It does not handle nested JSON very well, and we're going to submit a pull request for that. But for those seeing this, the important thing to take away is that the call_to_action may not be a valid JSON object, and even if it is, it may not be being stringified/parsed as expected. My fix was using request.post instead of HTTP.post. (then instead of params or data, you use form. look up node's request https://github.com/mikeal/request)

Youtube Data API v. 3 - Display channel author name of private / deleted video

This is one of them Youtube internal decisions that is highly counter-productive. Correct me if I'm wrong, but they currently don't want to expose the channel name of private / deleted videos. They even call it a 'bug' if it happens ( http://code.google.com/p/gdata-issues/issues/detail?id=5893 ). So what happens if I solely request video IDs that were public beforehand but then later became private or deleted? I will get, via usage of Youube Data API v3, a "response is undefined" error message in console. WHat happens when that message happens? My code breaks!
This is the code I currently use:
function DisplayThemVideos(yeah) {
var yeah = $("#ThoseMissingIDs").text();
var vidrequestOptions = {
id: yeah,
part: 'snippet',
fields: 'items(id),items(snippet(channelId)),items(snippet(channelTitle)),
items(snippet(title)),items(snippet(thumbnails(default)))'
};
var vidrequest = gapi.client.youtube.videos.list(vidrequestOptions);
vidrequest.execute(function(response) {
var videoIdItems = response.result.items;
if (videoIdItems) { // If results
displayResults(videoIdItems);
} else { // if NO results
alert('Sawwy, YouLose, thx to Youtube!'); // This alert never fires!
}
});
}
Now the undefined "response" is actually an empty request sent back to my app from Youtube server. Youtube answers back with an empty "item" tag which obviously doesn't help much for the displayResults(videoIdItems) function which gets fired without any item to display! They should at least let the channel name and channel ID filter through so a User could click on a link in order to access the remaining public videos of that channel (wouldn't that be productive Jeff P?).
SO my dilemma is to get the else section working like so:
displayResults(videoIdItems);
} else { // if NO results or if results return EMPTY or response "undefined"
alert('Sorry pal but these IDs ___________ are currently missing.
Click the Channel link to access the public videos of that channel.');
}
The else part works as it should for similar API calls as demonstrated in Youtube Data API v.3 sample code, but I guess it currently isn't able to handle empty requests.
So what am I to do? WIll I have to use an ajax call with success fail error handling? Like I said beforehand, the API returns an empty request so the response is legit but the response content comes empty for private/deleted videos, hence, "undefined" with code breaking along the wway.
Any hints leading to a working solution would help! Thx for guidance.
I can only partly answer my question. Easiest is to use Catch of Try - Catch method which detects everything except syntax errors, helpful in detecting an empty response (undefined) and activating your function that can access the Youtube player for displaying current availability status of the missing ID:
...
var vidrequest = gapi.client.youtube.videos.list(vidrequestOptions);
vidrequest.execute(function(response) {
try {
var videoIdItems = response.result.items;
if (videoIdItems) { // If results
displayResults(videoIdItems);
return false;
}
} catch (e) {
// put code here that handles errors such as empty or undefined response
// which otherwise breaks your code
} finally {
// optionally, put code here that will always trigger
}
});
Hope this helps others.

Why is node.js variable persisting

I'm making a temporary fake API and am trying to set up a simple request response script in node using express.js to achieve this. It's very strraightforward, A request comes in, is validated and, if valid, is merged with a .json template file and the result returned, thus giving the impression the user was successfully created.
app.post('/agent/user', function(req, res){
var responseTemplate = new jsonRequired('post_user');
var errorTemplate = new jsonRequired('post_user_error');
var payload = req.body;
var responseData;
var hasErrors = false;
console.log('Creating new user');
//Recursive Merge from http://stackoverflow.com/a/383245/284695
responseData = new mergeRecursive(responseTemplate,payload);
if(!payload.username){
hasErrors = true;
errorTemplate.errors.username.push('A username is required.');
}
if (hasErrors){
res.send(errorTemplate,422);
}else{
res.send(responseData,200);
}
});
The problem I'm having is that data is persisting between calls. So if I define a username and name[first] in 1 request and just a username in the 2nd one, both requests come back with the name[first] property.
I have a feeling it's something to do with js closures. Unfortunately, every tutorial I find seems to be about making closures, not avoiding them.
It should work like this:
The client POST's username=user1&name[first]=joe&name[last]=bloggs
The Server loads a json file containing a prepopulated user object: e.g.
{"username":"demo","name":{"first":"John","last":"Doe"}...}
mergeRecursive() merges the payload from the POST request over the template object and returns the new object as the POST response text.
The problem is that with every new request, the server is using the result of step 3 in step 2 instead of reloading the .json file.
That mergeRecursive function has the same caveat as jQuery.extend: it modifies the first object sent into it. In fact, you don't even need to use its return value.
You didn't show the code of jsonRequired function (it's not even clear why you've used new when invoking it), but it looks like this function doesn't create a new object each time it's called, instead fetching this object from some outer repository. Obviously, mergeRecursive modifications for it won't be lost after that function ends.
The solution is using your data object for merging. Like this:
var responseData = {};
...
mergeRecursive(responseData, responseTemplate);
mergeRecursive(responseData, payload);
Merging two objects will make this for you.
If your responseTemplate has parameter, which actual request did not have, then you will end up having it there.
Check definition of word merge ;)
While this doesn't resolve the issue I had, I have found a workaround using the cloneextend package available via npm:
$ npm install cloneextend
This allows me to use the following js:
var ce = require('cloneextend');
...
ce.extend(responseData, responseTemplate);
ce.extend(responseData, payload);

'POST 400 bad request' error when updating parse.com table

I am getting a 'POST 400 bad request' error when trying to update a table on parse.com using JS SDK.
var Gallery = Parse.Object.extend("Gallery");
var gallery = new Gallery();
var activeArtworks = 0;
gallery.save(null, {
success: function(gallery) {
gallery.set("activeArtworks", activeArtworks);
gallery.save();
}
});
Please help!
I can't see how this is any different to the sample code provided by parse here
The sample code you reference creates all of its parameters before setting up the save() method. This is the step you're missing; you need to create the activeArtworks parameter on your gallery instance. Your update is failing because you're trying to update a property that was never created.
I would expect this code to work, though I didn't test it because parse.com requires you to set up an account to run any code, which is silly, and I didn't feel like creating one:
var Gallery = Parse.Object.extend("Gallery");
var gallery = new Gallery();
var activeArtworks = 0;
gallery.activeArtworks = []; // or some more appropriate default if you have one.
gallery.save(null, {
success: function(gallery) {
gallery.set("activeArtworks", activeArtworks);
gallery.save();
}
});
It might also be worth checking if there's any info in the headers of the 400 error (the debug console in your browser will show these in its Network tab). I would expect Parse to give you some sort of information to help you debug issues, and that's the only place it would fit for an HTTP error.
If you had use user.logIn(callback) function with Parse JS, maybe your session invalid. Please check your callback function error code, if error.code==209 (invalid session token), use Parse.User.logOut() and re-login again.
Like this:
if (error.code == 209) {
Parse.User.logOut();
user.logIn(loginCallback);
return;
}
I had this same issue and it was resolved after realising that the data type that I was posting was different to that specified in the columns that I had created.
In my case, I was trying to save an object when I had specified an array when creating the column in the class.

Categories