I have been using Twitters search API (via the node-twitter module) and I am running into an issue with the attitude operator. I am looking to get both positive and negative tweets about a certain subject. Currently though they return identical results. Here is my code that calls the API.
// Add since ID for future requests
twitterSearchClient.search(
{'q' :'xmas+%3A%28',
'lang' : 'en',
'count' : 100,
'result_type': 'recent'},
function(error, result) {
if (error) {
console.log('Error: ' + (error.code ? error.code + ' ' + error.message : error.message));
}
if (result) {
var requestDetails = result.search_metadata;
var results = result.statuses;
var resultsLength = results.length;
var r;
var data;
var d;
console.log(resultsLength);
for (var i=0; i<resultsLength; i++) {
console.log(r.text);
}
}
}
);
As you can see I am using the fully urlencoded value like the example in the documentation. I have also tried using xmas+%3A) for positive and xmas+%3A( for negative but this returns a 401 unauthorised error for some reason.
Has anyone ran into this issue or has a solution.
If you have any future questions I will be happy to answer them
Thanks in advance.
Per twitter's docs
Please, make sure to URL encode these queries before making the request
When going to that url and typing in your search xmas :) I got this query
https://twitter.com/search?q=xmas%20%3A)
as you can see xmas :) = xmas%20%3A) and xmas :( ends up being
https://twitter.com/search?q=xmas%20%3A(
xmas :( = xmas%20%3A(
If you still do not get different results (you can compare the results to what get when doing the search on the link above) then it is not the query, but maybe how you are making the call. Will need additional information if that is the case.
In this case, have you tried not encoding your query? The client may well be encoding it on your behalf.
...
'q': 'xmas :(',
...
NOTE: You do not mention, or link to which twitter client (via npm?) that you are using.
I can't speak for your specific issues, when I search via the form on the site I do get different results, and the queries are URI encoded... When you are passing input to a remote query string, I would recommend using encodeURIComponent('xmas :)') for your input values, this will yield the most predictable results.
Related
Here am trying to find a better way to write the getItem in dynamoDB , how to return the record not found and can we store both record and 'not found' string on same response variable
public async getItem(){
let response;
try {
dynamoClient = new AWS.DynamoDB({
region: 'us-east-1'
})
data = await dynamoClient
.getItem(params)
.promise()
if(data.length == 0){
respoonse = 'no record found'
}else{
respnse = data
}
} catch (error) {
Logger.error('get error', error.stack)
}
return response;
}
JavaScript is very relaxed in regard to types. Your code is fine for node.js to run, but IMO using inconsistent return values is a bad practice. Eslint for example has a rule to check this.
To address your code, one option would be to create a database response structure that contains required information. Simple examply would be such as
{
data: <db-response> | null,
error: "not found" | <some error> | null
// ... other field as needed
}
With this you also can address the issue when the code throws an exception. Just include enough information to error field.
On the client side of getItem() you can check for presence of data|error as you need.
This is a very simple approach to fulfill your requirement. On the downside, it adds logic on the client side as a burden to check the presence of data/error.
Another option to consider is using Maybe structure. Basically the response might have data or not. In any case, it is the client's responsibility to handle the possible data not found case and act accordingly.
Note: The Maybe in itself is off topic for this thread and I'm not going to explain it further. Searching the web will give you a lot better resources with more detailed information than I could ever provide.
I'm still new enough with Node that HTTP requests trip me up. I have checked all the answers to similar questions but none seem to address my issue.
I have been dealt a hand in the Wild of having to go after JSON files in an API. I then parse those JSON files to separate them out into rows that populate a SQL database. The API has one JSON file with an ID of 'keys.json' that looks like this:
{
"keys":["5sM5YLnnNMN_1540338527220.json","5sM5YLnnNMN_1540389571029.json","6tN6ZMooONO_1540389269289.json"]
}
Each array element in the keys property holds the value of one of the JSON data files in the API.
I am having problems getting either type of file returned to me, but I figure if I can learn what is wrong with the way I am trying to get 'keys.json', I can leverage that knowledge to get the individual JSON data files represented in the keys array.
I am using the npm modules 'request' and 'request-promise-native' as follows:
const request = require('request');
const rp = require('request-promise-native');
My URL is constructed with the following elements, as follows (I have used the ... to keep my client anonymous, but other than that it is a direct copy:
let baseURL = 'http://localhost:3000/Users/doug5solas/sandbox/.../server/.quizzes/'; // this is the development value only
let keysID = 'keys.json';
Clearly the localhost aspect will have to go away when we deploy but I am just testing now.
Here is my HTTP call:
let options = {
method: 'GET',
uri: baseURL + keysID,
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function (res) {
jsonKeysList = res.keys;
console.log('Fetched', jsonKeysList);
})
.catch(function (err) {
// API call failed
let errMessage = err.options.uri + ' ' + err.statusCode + ' Not Found';
console.log(errMessage);
return errMessage;
});
Here is my console output:
http://localhost:3000/Users/doug5solas/sandbox/.../server/.quizzes/keys.json 404 Not Found
It is clear to me that the .catch() clause is being taken and not the .then() clause. But I do not know why that is because the data is there at that spot. I know it is because I placed it there manually.
Thanks to #Kevin B for the tip regarding serving of static files. I revamped the logic using express.static and served the file using that capability and everything worked as expected.
To begin with, I am new to couchdb and new to databases in general.I have a couchdb instance setup in a docker container. I have another docker container in the same box that has some nodeJS code that is talking to this couchdb instance.
Now, I am doing basic stuff like adding an entry and getting an entry from the db. To get an entry, this is what I do:
curl -X GET http://IP:5984/mydb/158
I get an output as follows:
{"_id":"156", "_rev":"1-47c19c00bee6417f36c7db2bc8607468", "name":{"given":["Itisha"], "family":["Iyengar"]}, "dob":"1981-06-01", "phone":{"value":"tel:312-116-1123"}, "address":{"line["147leverettmailcenter"], "city":"Naperville", "state":"IL", "postalCode":"02770"}, "SID":""}
I pass the data to another function that processes it further. However, I only want the actual data and don't want fields like _id and _rev.How do I do that? -
I read somewhere that I can log into the couchdb instance by doing http://localhost:5984/ from the machine where it is installed. Here I can edit the get script to make it return just the data and ignore the _id and _rev fields. However, I am running it from a docker container on Ubuntu. I do not have access to a UI through which I can make such changes. Is there an alternate way to do this?
If not, is there a way to parse the output and filter out the _id and _rev fields? As of now, I am doing this in a crude way by doing String.splice() and filtering out the data (after the _id and _rev fields) till the end. But I don't think this is a good way to do this and definitely not a good idea for actual production code.
Please suggest.
Thanks in advance.
There are multiple ways to achieve this, depending on your needs:
method 1
Use _find by making a POST request to /db/_find and select the fields you want
curl -X POST -d '{"fields": ["name", "family", "dob", "phone", "address", "SID"]}' http://IP:5984/mydb/_find
The parameter -d is used to send the data to the POST request.
You may need to escape the quotes if you're running Windows.
method 2
Use a view function
method 3
Process the results with a simple node program
const http = require("http");
http.get({
host: 'IP',
port: 5984
path: '/mydb/158'
}, function(response) {
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
var parsed = JSON.parse(body);
var result = {};
for (var key in parsed) {
if (key != "_id" && key != "_rev") {
result[key] = parsed[key];
}
}
console.log(result);
});
}
);
The above code issues a GET request to your couchdb server, parses the JSON output and puts the results in a new object after ignoring the _id and _rev keys.
method 4
Process the output as a string. As you correctly pointed out, this is not a good solution. It's ugly, but it doesn't mean it can't be done. You could even pipe the output through sed/awk/perl and process the string there.
I'm still relatively new to NetSuite, and have taken over a project that a contractor did for us, so this may be a simple question. We have a Suitelet that is calling another Suitelet with nlapiRequestURL. The Suitelet that is being called, is supposed to return a single ID. Instead, we get a 'Invalid Page Parameter' response.
I looked at the configuration for the Suitelet that is called, and there is a parameter setup, but the 'Preference' field on that parameter is blank, which according to the documentation suggests that when that is the case, the parameter value should be defined in the Deployment, on the Parameter tab. Which it is, and appears to be the correct value.
So I assume the issue is with one of the parameters in the URL that is being used in nlapiRequestURL, and not the parameter defined on the script record in Netsuite. Here is an example of one of those URLs. I just changed the compid for obvious reasons:
https://forms.sandbox.netsuite.com/app/site/hosting/scriptlet.nl?script=147&deploy=1&compid=12345&h=e06792b0e7727d53f816&internalIds=17509
I verified that '147' is the correct script id. I also tried removing each of the parameters one by one from the URL, but that doesn't work. Depending on which one I remove, I either get 'An unexpected error occurred', or 'Missing a required parameter'. The only parameter that is being used inside the Suitelet that is called is 'internalids'. I can see that it's being obtained with 'request.getParameter("internalIds")'. (See code below)
As a sidenote, I'm not sure what the 'h' parameter is for in the URL, and can't find where that, or compid, or deploy is configured. I'm wondering if that 'h' value is incorrect, but am not sure what it's for. Why are 'compid', 'deploy' and 'h' being included in the URL? I can assume the compid is for identifying our company, but I'm not seeing how someone can determine how to build a URL for a request, since I don't know what mandatory parameters there are like that. I'm guessing I don't know where to look in Netsuite to find that configuration. Are there settings for base URLs somewhere?
Anyway, this is the script below that is being called. The other script is quite a bit longer, and has some company related info, so I'm not going to include it, but I don't think that matters anyway. The only thing that needs to be known is that we're using the URL above with nlapiRequestURL to call the script below, and calling 'getBody' on the result.
function suitelet(request, response){
nlapiLogExecution('DEBUG', 'suitelet', 'In the Preview_Link.suitelet function');
nlapiLogExecution('DEBUG', 'suitelet', 'The request is ' + JSON.stringify(request));
nlapiLogExecution('DEBUG', 'suitelet', 'The response is ' + JSON.stringify(response));
var context = nlapiGetContext();
var folderInternalId = context.getSetting('SCRIPT', 'custscript_buffer_folder_for_temp_pdf');
var strInternalIds = request.getParameter('internalIds');
if(!strInternalIds)
return;
var internalIds = strInternalIds.split(',');
if(!internalIds || internalIds.length == 0)
return;
var xml = "<?xml version=\"1.0\"?>\n<!DOCTYPE pdf PUBLIC \"-//big.faceless.org//report\" \"report-1.1.dtd\">\n";
xml += "<pdfset>";
for (var index = 0; index < internalIds.length; index++)
{
var internalId = internalIds[index];
xml += "<pdf src='"+ nlapiEscapeXML(nlapiLoadFile(internalId).getURL()) +"'/>";
}
xml += "</pdfset>";
var file = nlapiXMLToPDF(xml);
file.setName(internalIds[0] + '_' + internalIds.length + '_' + Math.random() +'.pdf');
file.setFolder(folderInternalId);
file.setIsOnline(true);
var internalIDUpdatedData = nlapiSubmitFile(file);
response.writeLine(internalIDUpdatedData);
}
So 'custscript_buffer_folder_for_temp_pdf' is the parameter defined on the Script record in Netsuite, and there is a value for it on that script's Deployment tab, on the Parameter tab, of '36', which is the value we want. That's our 'TEMP' folder in the File Cabinet. 'internalIds' is defined in the script that calls the one above, and it's either a single integer, or a comma separated list of them. (although it seems to always be a single value)
I should mention that this works in our production instance, and we just refreshed our Sandbox instance two days ago based on production. It didn't work in Sandbox prior to the refresh either. The only difference I can see, is that in production, the domain name is different in the URL, which of course it must be. All the code and settings appear to be identical besides that between the two environments.
Like I said, I'm new to Netsuite, so I haven't used nlapiRequestURL before. So this may be something incredibly stupid I'm overlooking. I've stepped through the code in the script that does the calling, but I can't seem to debug the Suitelet that is being called with nlapiRequestURL. I placed a nlapiLogExecution call as the first line in the script that is being called though, and it never even seems to hit that. I just get one of the errors I mentioned above before it actually steps into that script.
If anyone has any advice, I'd appreciate it. I've more or less exhausted my knowledge and resources. Thanks in advance, and let me know if you need further info.
Some things you may want to try:
var baseSuiteletURL = nlapiResolveURL('SUITELET', SUITELET_SCRIPT_ID, SUITELET_DEPLOYMENT_ID, true); //Getting URL from script id and deployment id
var reqUrl = baseSuiteletURL + "&internalids=17509"; //Adding your GET parameter here (all in lowercase)
var requestBody = {}; //Alternatively you could send your parameters within the POST body
requestBody.internalids = 17509;
var reqBody = JSON.stringify(requestBody);
var reqHeaders = {};
reqHeaders["User-Agent"] = "Mozilla/5.0"; //Sending user agent header to allow Suitelet to Suitelet calls
var myResponse = nlapiRequestURL(reqUrl, reqBody, reqHeaders);
Test sending your GET Query parameters (internalids) all in lowercase, I have experienced issues before in which the parameters case gets converted and it creates unnecessary troubles.
This is my first post here so please don't get mad if my formatting is a bit off ;-)
I'm trying to develop a backend solution using Azure mobile apps and node.js for server side scripts. It is a steep curve as I am new to javaScript and node.js coming from the embedded world. What I have made is a custom API that can add users to a MSSQL table, which is working fine using the tables object. However, I also need to be able to delete users from the same table. My code for adding a user is:
var userTable = req.azureMobile.tables('MyfUserInfo');
item.id = uuid.v4();
userTable.insert(item).then( function (){
console.log("inserted data");
res.status(200).send(item);
});
It works. The Azure node.js documentation is really not in good shape and I keep searching for good example on how to do simple things. Pretty annoying and time consuming.
The SDK documentation on delete operations says it works the same way as read, but that is not true. Or I am dumb as a wet door. My code for deleting looks like this - it results in exception
query = queries.create('MyfUserInfo')
.where({ id: results[i].id });
userTable.delete(query).then( function(delet){
console.log("deleted id ", delet);
});
I have also tried this and no success either
userTable.where({ id: item.id }).read()
.then( function(results) {
if (results.length > 0)
{
for (var i = 0; i < results.length; i++)
{
userTable.delete(results[i].id);
});
}
}
Can somebody please point me in the right direction on the correct syntax for this and explain why it has to be so difficult doing basic stuff here ;-) It seems like there are many ways of doing the exact same thing, which really confuses me.
Thanks alot
Martin
You could issue SQL in your api
var api = {
get: (request, response, next) => {
var query = {
sql: 'UPDATE TodoItem SET complete=#completed',
parameters: [
{ name: 'completed', value: request.params.completed }
]
};
request.azureMobile.data.execute(query)
.then(function (results) {
response.json(results);
});
}};
module.exports = api;
That is from their sample on GitHub
Here is the full list of samples to take a look at
Why are you doing a custom API for a table? Just define the table within the tables directory and add any custom authorization / authentication.