Nodejs website execution in the background - node.js

So I am developing a call logging website based on Nodejs, I have come to a point from where I need to send SMS to the engineer when the call is logged. I have got access to the SMS gateway which is essentially a URL like the following :
http://192.x.x.x username=x password=y&to=mobileno&text=xyz
My requirement is to execute this link so that the SMS is sent and the page remains as it was without having to be redirected.
Many thanks

This is a pretty simple task due to node.js io asynchrony.
Suppose you have an express route:
app.get('/some-url', (req, res) => {
request('http://192.x.x.x?username=x&password=y&to=mobileno&text=xyz')
.then(response => { // process response })
res.end();
});

What i understood from your description is you have to hit the url after certain task.So u can use a rest client to hit the url in the callback of certain task(here after call is logged).
I prefer node-rest-client(https://www.npmjs.com/package/node-rest-client).There are other options also.

Related

GET request recieved in php but not node.js w/ Express

I'm trying to integrate KiwiWall, a rewarded ads/offerwall provider, with my website. The end goal is to credit virtual coins to the user when an offer is completed.
The code that I currently have is as follows. I'm simply trying to make sure a request is being received from KiwiWall, which it is not. It's worth noting that the following DOES log the intended information to the console when a request is sent from my browser or a request testing website like ReqBin:
app.use('/offers/kiwiwall/api', cors(), async (req, res) => {
console.log(req.method)
})
However, no output can be seen when using the postback testing functionality of KiwiWall.
In order to make sure the issue isn't on KiwiWall's end, I hosted the example php code from the KiwiWall docs on the same webserver, and was able to successfully receive and process the request using it. Why is this not working with node.js/Express?

Is it possible to not stop an API call which is doing some operation in server side if i redirect to another page in the mean time in React?

I used the post method to send some data through an API calling to Nodejs and waiting for the response after getting the response it will trigger another API. At this moment user wants to visit another page but the API calls will not be aborted. API call will do its task.
Is it possible to do so?
Call the API in redux using redux-thunk. Since redux is outside of all component. Changing page won't stop the API calling
You can just create a state variable and save the response of the post request in that variable, so it will be saved
When I implement the APIs in express, they continue to be executed even if the user navigates away, as illustrated by this example:
express()
.get("/api1", function(req, res) {
setTimeout(function() {
console.log("API call finished");
res.end();
}, 10000);
})
.get("/api2", function(req, res) {
res.end();
})
.listen(...);
The user first types http://server/api1 into their browser, which returns nothing after 10 seconds. But rather than wait, they navigate away to http://server/api2, which returns nothing immediately. But the /api1 call continues, as demonstrated by the console message after 10 seconds.
How does this differ from your case?

External web service redirects the user and posts data to my callback URL. How do I render the posted data to the user in an Express/Next.js app?

Any help would be hugely appreciated! Been stuck on this for a few days.
I have an Express/Next.js app where:
I send the user to an external website
user makes a payment
external website redirects and posts data back to my callback URL.
So now I have the user on a mysite.com/payment-complete route but also want to display the data that was sent back.
I have an app.post endpoint to successfully grab the data:
app.post("/payment-complete", async (req, res) => {
const transactionID = req.body.trans_id;
});
How would I pass the data to the user who is already on that route? Or pass the data before the page is rendered?
The flow of data is third party > my server > user and I'm not sure how to make this work.
I'd be grateful for any help/direction with this.
If anyone comes across this - the problem was that in Express (and other languages) you can't redirect or render a view for an AJAX POST request but you can if the POST request is coming from a submitted html form. The web service was in fact POST-ing the data and redirecting my users with a form and so I could render a view.
Following code worked using Handlebars templating engine to send the render.
router.post("/payment-ok", async (req, res) => {
const transactionID = req.body.trans_id;
return res.render("rendertest", { id: transactionID });
});
Should also possibly work with app.render to send a Next.js view instead, but I wanted to render from a separate routes file.

render page while making http request express

Hi i'm an express noob.... I have an api look page, that's all working but what i'd like to have is once a user hits the route i'll display a loading page, fire off the api http request then once it's successful redirect/render the results page. As i understand it you can't use res.render twice on the same route? Maybe our chum next(); can help here?
This is what i have so far:
router.get('/lookup/post/:url', function(req, res){
// Render the loading page...?
res.render('loading');
Lookup.post(req.params.url, function(err, result){
if(err){
}else{
// ...Then once the api lookup comes back ok redirect or render the results page?
res.render('results', {
posts : result.store.postData.posts[0],
votes : result.store.voteData
});
}
});
});
The solution to your problem is to do part in the UI and part on the server. You can do it with an Ajax call or by using Socket.IO, which will create a socket connection to the server.
I would argue that the later is the most convenient solution, because you can talk to the back-end and the front-end by emitting and listening to messages. The cool part of Socket.IO is that if the browser doesn't support sockets, it will default to an Ajax call.
The official website of Socket.IO is: http://socket.io. You can also check my bPhone project where I use Socket.IO in the simplest way possible. Plus my code have a lot of comments that should make everything super clear.
I hope this will put you on the right path :)

Express request is called twice

To learn node.js I'm creating a small app that get some rss feeds stored in mongoDB, process them and create a single feed (ordered by date) from these ones.
It parses a list of ~50 rss feeds, with ~1000 blog items, so it's quite long to parse the whole, so I put the following req.connection.setTimeout(60*1000); to get a long enough time out to fetch and parse all the feeds.
Everything runs quite fine, but the request is called twice. (I checked with wireshark, I don't think it's about favicon here).
I really don't get it.
You can test yourself here : http://mighty-springs-9162.herokuapp.com/feed/mde/20 (it should create a rss feed with the last 20 articles about "mde").
The code is here: https://github.com/xseignard/rss-unify
And if we focus on the interesting bits :
I have a route defined like this : app.get('/feed/:name/:size?', topics.getFeed);
And the topics.getFeed is like this :
function getFeed(req, res) {
// 1 minute timeout to get enough time for the request to be processed
req.connection.setTimeout(60*1000);
var name = req.params.name;
var callback = function(err, topic) {
// if the topic has been found
if (topic) {
// aggregate the corresponding feeds
rssAggregator.aggregate(topic, function(err, rssFeed) {
if (err) {
res.status(500).send({error: 'Error while creating feed'});
}
else {
res.send(rssFeed);
}
},
req);
}
else {
res.status(404).send({error: 'Topic not found'});
}};
// look for the topic in the db
findTopicByName(name, callback);
}
So nothing fancy, but still, this getFeed function is called twice.
What's wrong there? Any idea?
This annoyed me for a long time. It's most likely the Firebug extension which is sending a duplicate of each GET request in the background. Try turning off Firebug to make sure that's not the issue.
I faced the same issue while using Google Cloud Functions Framework (which uses express to handle requests) on my local machine. Each fetch request (in browser console and within web page) made resulted in two requests to the server. The issue was related to CORS (because I was using different ports), Chrome made a OPTIONS method call before the actual call. Since OPTIONS method was not necessary in my code, I used an if-statement to return an empty response.
if(req.method == "OPTIONS"){
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.status(204).send('');
}
Spent nearly 3hrs banging my head. Thanks to user105279's answer for hinting this.
If you have favicon on your site, remove it and try again. If your problem resolved, refactor your favicon url
I'm doing more or less the same thing now, and noticed the same thing.
I'm testing my server by entering the api address in chrome like this:
http://127.0.0.1:1337/links/1
my Node.js server is then responding with a json object depending on the id.
I set up a console log in the get method and noticed that when I change the id in the address bar of chrome it sends a request (before hitting enter to actually send the request) and the server accepts another request after I actually hit enter. This happens with and without having the chrome dev console open.
IE 11 doesn't seem to work in the same way but I don't have Firefox installed right now.
Hope that helps someone even if this was a kind of old thread :)
/J
I am to fix with listen.setTimeout and axios.defaults.timeout = 36000000
Node js
var timeout = require('connect-timeout'); //express v4
//in cors putting options response code for 200 and pre flight to false
app.use(cors({ preflightContinue: false, optionsSuccessStatus: 200 }));
//to put this middleaware in final of middleawares
app.use(timeout(36000000)); //10min
app.use((req, res, next) => {
if (!req.timedout) next();
});
var listen = app.listen(3333, () => console.log('running'));
listen.setTimeout(36000000); //10min
React
import axios from 'axios';
axios.defaults.timeout = 36000000;//10min
After of 2 days trying
you might have to increase the timeout even more. I haven't seen the express source but it just sounds on timeout, it retries.
Ensure you give res.send(); The axios call expects a value from the server and hence sends back a call request after 120 seconds.
I had the same issue doing this with Express 4. I believe it has to do with how it resolves request params. The solution is to ensure your params are resolved by for example checking them in an if block:
app.get('/:conversation', (req, res) => {
let url = req.params.conversation;
//Only handle request when params have resolved
if (url) {
res.redirect(301, 'http://'+ url + '.com')
}
})
In my case, my Axios POST requests were received twice by Express, the first one without body, the second one with the correct payload. The same request sent from Postman only received once correctly. It turned out that Express was run on a different port so my requests were cross origin. This caused Chrome to sent a preflight OPTION method request to the same url (the POST url) and my app.all routing in Express processed that one too.
app.all('/api/:cmd', require('./api.js'));
Separating POST from OPTIONS solved the issue:
app.post('/api/:cmd', require('./api.js'));
app.options('/', (req, res) => res.send());
I met the same problem. Then I tried to add return, it didn't work. But it works when I add return res.redirect('/path');
I had the same problem. Then I opened the Chrome dev tools and found out that the favicon.ico was requested from my Express.js application. I needed to fix the way how I registered the middleware.
Screenshot of Chrome dev tools
I also had double requests. In my case it was the forwarding from http to https protocol. You can check if that's the case by looking comparing
req.headers['x-forwarded-proto']
It will either be 'http' or 'https'.
I could fix my issue simply by adjusting the order in which my middlewares trigger.

Resources