Node js Service Doesnt Return anything - node.js

i have a simple code to wait for 10 min in "api/get" endpoint in Node js despite of keeping the both req.setTimeout(9000000); and server.setTimeout(5000000); still neither there is any error nor i am getting any result.It simply gets stuck.
const express = require('express');
const newman = require('newman');
var sleep = require('sleep');
const app = express();
const fs = require('fs');
var request = require("request");
var testexecution = require('./TestStatus');
var uploadtoblob = require('./BlobFiles');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.get('/api/version',(req,res)=>{
console.log("Started!")
res.status(200).json({
message: 'version 1.1.1'
});
});
app.get('/api/secondEndpoint',(req,res)=>{
console.log("Second Endpoint Started")
request({
uri: "http://protractortestcasesnew.eastus.azurecontainer.io/api/test",
method: "GET",
timeout: 1200000,
followRedirect: true,
maxRedirects: 10
}, function(error, response, body) {
console.log("Second Endpoint Exit")
return res.status(400).json(response.statusMessage);
});
});
app.get('/api/test',(req,res)=>{
req.setTimeout(9000000);
const cp = require('child_process');
var testName=req.rawHeaders[1];
//var enviroment=req.rawHeaders[2];
var enviroment="predev";
var file='/app/TestCases/reports\\testReport.html';
var connectionStringfile='/app/Service/NodejsWebApp/Values.json';
try
{
console.log("Method Entry");
setTimeout(() => { return res.status(200).json({
message: 'Pass'
}); }, 240000);
}
catch (error)
{
if((error.status == 1) && (error.message == "Command failed: npm test") && (fs.existsSync('/app/TestCases/reports\\testReport.html' && '/app/TestCases/reports\\testReport.html.json' )) )
{
console.log("Catch Exit");
console.log("res");
return res.status(404).json({
message: 'Failed npm Error'
});
}
else
{
console.log("Error!");
error.status;
error.message;
error.stderr;
error.stdout;
return res.status(500).json({
message: 'Failed'
});
}
}
});
var server=app.listen(80,()=>console.log("server is up"))
module.exports = app;
server.setTimeout(5000000);
i have a simple code to wait for 10 min in "api/get" endpoint in Node js despite of keeping the both req.setTimeout(9000000); and server.setTimeout(5000000); still neither there is any error nor i am getting any result.It simply gets stuck.

I figured out that after 4 mins or so the httpClient closes and does not give response out.So to overcome it you can probable poll on the endpoint after 2 mins and see if result is available or not and then get the result.

Related

WA business api nodejs

I have a problem with my nodejs code and the connection to the official whatsapp business api.
The bot connects the webhook correctly, the messages arrive to the server correctly but the code I have implemented to make it respond is not being effective, I checked the code from top to bottom but I can't find the fault.
I leave you the codes so you have more context:
whatsappController.js:
const fs = require("fs");
const myConsole = new console.Console(fs.createWriteStream("./logs.txt"));
const whatsappService = require("../services/whatsappService")
const VerifyToken = (req, res) => {
try {
var accessToken = "456E7GR****************************";
var token = req.query["hub.verify_token"];
var challenge = req.query["hub.challenge"];
if(challenge != null && token != null && token == accessToken){
res.send(challenge);
}
else{
res.status(400).send();
}
} catch(e) {
res.status(400).send();
}
}
const ReceivedMessage = (req, res) => {
try {
var entry = (req.body["entry"])[0];
var changes = (entry["changes"])[0];
var value = changes["value"];
var messageObject = value["messages"];
if(typeof messageObject != "undefined"){
var messages = messageObject[0];
var text = GetTextUser(messages);
var number = messages["from"];
myConsole.log("Message: " + text + " from: " + number);
whatsappService.SendMessageWhatsApp("The user say: " + text, number);
myConsole.log(messages);
myConsole.log(messageObject);
}
res.send("EVENT_RECEIVED");
}catch(e) {
myConsole.log(e);
res.send("EVENT_RECEIVED");
}
}
function GetTextUser(messages){
var text = "";
var typeMessage = messages["type"];
if(typeMessage == "text"){
text = (messages["text"])["body"];
}
else if(typeMessage == "interactive"){
var interactiveObject = messages["interactive"];
var typeInteractive = interactiveObject["type"];
if(typeInteractive == "button_reply"){
text = (interactiveObject["button_reply"])["title"];
}
else if(typeInteractive == "list_reply"){
text = (interactiveObject["list_reply"])["title"];
}else{
myConsole.log("sin mensaje");
}
}else{
myConsole.log("sin mensaje");
}
return text;
}
module.exports = {
VerifyToken,
ReceivedMessage
}
The second file is whatsappService which I make the connection with the api using the token and I also send the format of the message I want to send when I receive a hello for example...
const https = require("https");
function SendMessageWhatsApp(textResponse, number){
const data = JSON.stringify({
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": number,
"type": "text",
"text": {
"preview_url": false,
"body": textResponse
}
});
const options = {
host:"graph.facebook.com",
path:"/v15.0/1119744*************/messages",
method:"POST",
body:data,
headers: {
"Content-Type":"application/json",
Authorization:"Bearer EAAWNbICfuWEBAK5ObPbD******************************************************"
}
};
const req = https.request(options, res => {
res.on("data", d=> {
process.stdout.write(d);
});
});
req.on("error", error => {
console.error(error);
});
req.write(data);
req.end();
}
module.exports = {
SendMessageWhatsApp
};
Then I declare the routes for the get (to check token) and post (to receive and reply to messages) methods:
const expres = require("express");
const router = expres.Router();
const whatsappController = require("../controllers/whatsappControllers");
router
.get("/", whatsappController.VerifyToken)
.post("/", whatsappController.ReceivedMessage)
module.exports = router;
Last but not least the index file for the code to run correctly:
const express = require("express");
const apiRoute = require("./routes/routes");
const app = express();
const PORT = process.env.PORT || 3000
app.use(express.json());
app.use("/whatsapp", apiRoute);
app.listen(PORT, () => (console.log("El puerto es: " + PORT)));
I should clarify that I did the tests with Postman and they were all successful, it responds and receives messages correctly, finally I did the tests by uploading the bot to the Azure service and it works without problem until it has to answer/replicate the user's message.
The bot is not responding to the user when he talks to it but everything arrives correctly to the server and it processes it with a 200 response. I attach the evidence that there is no problem in the reception.
Finally I must say that in the meta platform I have everything configured as specified by the same platform, I have already configured the api to answer the messages through the webhooks and everything is correct, I just can't get the bot to answer correctly.
The bot is hosted in the Azure service.
Solved: some numbers have a problema with the api of WAB in my country (Argentina) the phone numbers start in +54 9 11. The problem is the 9 in the phone number, and this have a conflict in the servers of meta, Solution quit number 9 to numbers of this country and the message will send to user.

node js not behaving the same way on local and Google App Egine

I'm developing an app to upload .las file to cesium ion.
I have modified this code https://github.com/CesiumGS/cesium-ion-rest-api-examples/blob/main/tutorials/rest-api/index.js
To pass a file from the browser.
It's working flawlessly when I run npm start on my local env.
When I try the same thing on the app Engine, I do not get the message about where the process is at. It's does upload the file though. It's just I can't monitor what is going on.
To explain what is going on below, I send a file from the client, then it's catch by app.post("/upload"
Then, it create asset on Ion, and then upload to S3, then it tell ion it's finished, then it monitor the tiling on Ion.
Then I call every second app.post("/progress" That is sending back the stat of things to the client.
I think there is probably a logic I'm missing, something basic I make totally wrong. I'm using one single service for both the backend and the frontend. Can this be a part of the problem ?
const express = require('express');
const app = express();
const port = process.env.PORT || 3001;
const fileUpload = require("express-fileupload");
const cors = require('cors');
var path = require('path');
const AWS = require('aws-sdk');
const fs = require('fs');
const rawdatafr = require('./lang/fr.json');
const rawdataen = require('./lang/en.json');
const axios = require('axios').default;
const accessToken = process.env.REACT_APP_ION_TOKEN;
const environment = process.env.NODE_ENV || 'production';
var urlLang = (environment === 'development') ? 'client/src/lang/' : 'lang/';
console.log('urlLang ? '+urlLang);
app.use(cors());
app.use(fileUpload({
useTempFiles: true,
safeFileNames: false,
preserveExtension: true,
tempFileDir: 'temp/'
}));
'use strict';
var messageFromLoc = rawdataen;
var input = null;
var filename = null;
var srcType = 'POINT_CLOUD';
var message = null;
var needMonitoring = false;
var assetMetadata = null;
var finished = null;
function resetGlobalvar(){
message = null;
needMonitoring = false;
assetMetadata = null;
finished = null;
input = null;
filename = null;
srcType = 'POINT_CLOUD';
}
async function creat_asset(){
finished = false;
message = 'create asset';
axios.post('https://api.cesium.com/v1/assets', {
name: filename,
description: '',
type: '3DTILES',
options: {
position:[ 2.29, 48.85, 0.1],
sourceType: srcType,
}
},{
headers: { Authorization: `Bearer ${accessToken}` }
})
.then(function (response) {
message = 'created successfully :> send to s3';
sendtos3(response.data);
})
.catch(function (error) {
console.log(error);
message = error;
});
}
async function sendtos3(response){
console.log('Asset created.');
message = 'send to s3';
try{
const uploadLocation = response.uploadLocation;
const s3 = new AWS.S3({
apiVersion: '2006-03-01',
region: 'us-east-1',
signatureVersion: 'v4',
endpoint: uploadLocation.endpoint,
credentials: new AWS.Credentials(
uploadLocation.accessKey,
uploadLocation.secretAccessKey,
uploadLocation.sessionToken)
});
let params = {
Body: fs.createReadStream(input),
Bucket: uploadLocation.bucket,
Key: uploadLocation.prefix+filename
};
let s3Response = await s3.upload(params).on('httpUploadProgress', function (progress) {
message = `${messageFromLoc.upload}: ${((progress.loaded / progress.total) * 100).toFixed(2)}%`;
console.log(`Upload: ${((progress.loaded / progress.total) * 100).toFixed(2)}%`);
}).promise();
// request successed
console.log(`File uploaded to S3 at ${s3Response.Bucket} bucket. File location: ${s3Response.Location}`);
message = `File uploaded to S3 at ${s3Response.Bucket} bucket. File location: ${s3Response.Location}`;
step3(response);
// return s3Response.Location;
}
// request failed
catch (ex) {
console.error(ex);
message = ex;
}
}
async function step3(response){
const onComplete = response.onComplete;
assetMetadata = response.assetMetadata;
message = 'step3';
axios.post(onComplete.url, onComplete.fields,{
headers: { Authorization: `Bearer ${accessToken}` }
})
.then(function (response) {
message = 'step3 done';
monitorTiling(assetMetadata);
})
.catch(function (error) {
console.log(error);
message = error;
});
}
async function monitorTiling(assetMetadata){
// console.log(response);
const assetId = assetMetadata.id;
message = 'monitorTiling';
axios.get(`https://api.cesium.com/v1/assets/${assetId}`,{headers: { Authorization: `Bearer ${accessToken}` }})
.then(function (response) {
// handle success
console.log('monitorTiling - success');
var status = response.data.status;
message = 'Tiling - success';
if (status === 'COMPLETE') {
console.log('Asset tiled successfully');
console.log(`View in ion: https://cesium.com/ion/assets/${assetMetadata.id}`);
message = 'Asset tiled successfully';
needMonitoring = false;
finished = true;
} else if (status === 'DATA_ERROR') {
console.log('ion detected a problem with the uploaded data.');
message = 'ion detected a problem with the uploaded data.';
needMonitoring = false;
finished = true;
} else if (status === 'ERROR') {
console.log('An unknown tiling error occurred, please contact support#cesium.com.');
message = 'An unknown tiling error occurred, please contact support#cesium.com.';
needMonitoring = false;
finished = true;
} else {
needMonitoring = true;
if (status === 'NOT_STARTED') {
console.log('Tiling pipeline initializing.');
message = 'Tiling pipeline initializing.';
} else { // IN_PROGRESS
console.log(`Asset is ${assetMetadata.percentComplete}% complete.`);
message = `Asset is ${assetMetadata.percentComplete}% complete.`;
}
}
})
.catch(function (error) {
// handle error
console.log(error);
message =error;
})
}
/*------- LISTEN FOR CALL TO UPLOAD AND START THE UPLOAD PROCESS ----------*/
app.post("/upload", (req, res) => {
if (!req.files) {
res.send("File was not found");
message = 'File was not found';
return;
}
input = req.files.file.tempFilePath;
filename = req.files.file.name;
emptyTempFolder('temp', input.replace('temp/', ''));
var ext = path.extname(filename);
if(ext=='.zip'){
srcType = 'CITYGML';
}
/*------- START UPLOAD PROCESS ----------*/
creat_asset();
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
/*------- LISTEN FOR PROGRESS TO UPLOAD ASSET ----------*/
app.get("/progress", (req, res) => {
// lang = req.get('Accept-Language').substring(0, 2).toLowerCase();
// if(lang=='fr'){
// messageFromLoc = rawdatafr;
// }
console.log('message ='+message);
if(needMonitoring){
monitorTiling(assetMetadata);
}
res.json({ message: message, done: finished, myAssetMetadata: assetMetadata });
if(finished){
resetGlobalvar();
}
});
/*--------------STATIC ----------------*/
app.use(express.static( path.join(__dirname, 'build' )));
And my app.yaml is like this :
runtime: nodejs14
env: standard
includes:
- env_variables.yaml
instance_class: B1
service: my-app
basic_scaling:
max_instances: 25
idle_timeout: 60m
I think this is from your instance(s). You're using basic scaling with up to 25 instances.
It looks like a combination of the following is happening
a) When you send a request to /progress, a new instance of your App is created which means all of the global variables are starting from their default values (the initial value of message is null).
b) Other times, a request to /progress is handled by an existing instance which was already processing an upload request and that request has completed and so the message says completed
You don't have this problem on your local environment because only 1 instance runs.
To test this theory, modify your app.yaml and set max_instances: 1. This is supposed to force the App to only use 1 instance which means subsequent requests should use an existing instance (which has the updated state of your global variables)

Unexpected token require('https’)?

I am new to node js. I am a bit struggling to fix this compilation issue.
How do I fix this? I believe I am missing some package. How can I include it?
I get error on the line require('https') i.e unexpected token. I have tried running npm install https -g but it hasn't fixed anything. I am running this code on Ubuntu and OSX.
var https = require('https’);
const parseUrl = require('parseurl');
var options = {
key: fs.readFileSync(‘/Users/admin/Dropbox/node_prj/SiteNodeJS/server.key’),
cert: fs.readFileSync(‘/Users/admin/Dropbox/node_prj/SiteNodeJS/server.crt’)
};
const fileEngine = require('./fileErrHandler');
const UrlLoader = require('./urlController');
https.createServer(options, function (req, res)
{
try
{
// this is a library function
var pathName = decodeURIComponent(req.url);
var pathCheck = fileEngine(pathName); //return true or error message
if(pathCheck){
}
else{
}
var fileResEngine= new fileEngine(pathName);
// create a literal validateFile to validate the path
fileResEngine.pathCheck();
if (fileResEngine.error === true )
{
res.statusCode = fileResEngine.statusCode;
res.end(fileResEngine.ErrorMsg);
return;
}
else
{
var UrlResLoader = new UrlLoader();
UrlResLoader.requestUrl(fileResEngine, function(urctrl){
res.writeHead(urctrl.httpcode, urctrl.fileType);
res.write(urctrl.data);
res.end();
});
}
}
catch(err)
{
res.statusCode = err.status || 500;
res.end(err.message);
}
}).listen(443);
It seems you have a typo here: var https = require('https’ <---); You have a tick instead of a single quote.

angularjs error on server callback

I'm making a call to the server using resource and when I go to the base URL of
/viewEvent
It works fine. I receive all the database entries. However, when I go to
/viewEvent/1234
where 1234 is the eventID
I get a undefined is not a function and this is a crash from within angular. Stack trace is
TypeError: undefined is not a function
at copy (http://localhost:8000/js/lib/angular/angular.js:593:21)
at http://localhost:8000/js/lib/angular/angular-resource.js:410:19
at wrappedCallback (http://localhost:8000/js/lib/angular/angular.js:6846:59)
at http://localhost:8000/js/lib/angular/angular.js:6883:26
at Object.Scope.$eval (http://localhost:8000/js/lib/angular/angular.js:8057:28)
at Object.Scope.$digest (http://localhost:8000/js/lib/angular/angular.js:7922:25)
at Object.Scope.$apply (http://localhost:8000/js/lib/angular/angular.js:8143:24)
at done (http://localhost:8000/js/lib/angular/angular.js:9170:20)
at completeRequest (http://localhost:8000/js/lib/angular/angular.js:9333:7)
at XMLHttpRequest.xhr.onreadystatechange (http://localhost:8000/js/lib/angular/angular.js:9303:11) angular.js:575
When I examine the server, the request was made correctly. I can see that it got 1234 and it pulls the correct entry from the mongo database.
This is the controller logic
.controller("viewEventsController", ["$scope", 'EventService', '$location', function($scope, EventService, $location){
var path = $location.path().split('/');
var pathSize = path.length;
$scope.events = [];
if(pathSize === 2){
console.log("No event ID");
$scope.events = EventService.query();
}
else{
console.log("Event ID specified");
EventService.get({"eventID": path[pathSize - 1]}, function(data){
//$scope.events.push(data);
console.log(data);
}, function(error){
console.log(error);
});
}
}]);
and the service logic
service.factory('EventService', function($resource){
return $resource('api/viewEvent/:eventID');
});
It never makes it back to the controller so I'm "confident" it's not that. (watch it be that)
Not sure if the best way, but I got it working by doing
In service:
service.factory('EventService', function($resource){
return $resource('api/viewEvent/:eventID',
{eventID:"#eventID"},
{
'getSingleEvent': {
url: "api/viewEvent/:eventID",
method: "GET",
isArray: true
}
}
);
controller
var path = $location.path().split('/');
var pathSize = path.length;
EventService.getSingleEvent({"eventID":path[pathSize - 1]}, function(result){
$scope.updateEvent();
});
Server
routes = require('./routes')
var router = express.Router();
router.get('/api/viewEvent/:eventID', routes.viewEvent);
and in the routes directory I have a js file with
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'eventApp');
var eventSchema = require('../models/createEvent.js').eventSchema;
var event = db.model('events', eventSchema);
exports.viewEvent = function(req, res){
console.log(req.params.eventID);
if(req.params.eventID) {
event.find({"_id": req.params.eventID}, function (error, events) {
console.log(events);
res.send(events);
});
}
else{
event.find({}, function (error, events) {
console.log(events);
res.send(events);
})
}
};

NodeJs requests callbacks in Dart

I'm trying to convert the following Node.js snippet to Dart. In my conversion the 'data returned...' message is printed as soon as there is a response unlike in the Node.js version which waits until the page completes the requested 2 second delay.
Node.js
var http = require('http')
function fetchPage() {
console.log('fetching page');
http.get({ host: 'trafficjamapp.herokuapp.com', path: '/?delay=2000' }, function(res) {
console.log('data returned from requesting page');
}).on('error', function(e) {
console.log("There was an error" + e);
});
}
Dart
import 'dart:io';
import 'dart:uri';
fetchPage() {
print('fetching page');
var client = new HttpClient();
var uri = new Uri.fromComponents(scheme:'http', domain: 'trafficjamapp.herokuapp.com', path: '?delay=2000');
var connection = client.getUrl(uri);
connection.onRequest = (HttpClientRequest req) {
req.outputStream.close();
};
connection.onResponse = (HttpClientResponse res){
print('data returned from requesting page');
};
connection.onError = (e) => print('There was an error' ' $e');
}
How do I achieve the same delayed print in Dart as in Node? Thanks in advance.
Your Dart code was almost right, but there was a bug. You should have used query named parameter instead of path. I don't really know which Url is call with your code but the response has a 400 status code. For more readability, you can also use the Uri.fromString constructor.
Moreover you can omit your onRequest setting because the same code is done when onRequest is not defined.
Here's the code :
import 'dart:io';
import 'dart:uri';
main() {
print('fetching page');
//var uri = new Uri.fromString('http://trafficjamapp.herokuapp.com/?delay=2000');
var uri = new Uri.fromComponents(scheme:'http',
domain: 'trafficjamapp.herokuapp.com', query: 'delay=2000');
var client = new HttpClient();
var connection = client.getUrl(uri);
connection.onResponse = (HttpClientResponse res){
print('data returned from requesting page with status ${res.statusCode}');
};
connection.onError = (e) => print('There was an error' ' $e');
}
You can find this in the documentation of the onResponse callback:
The callback is called when all headers of the response are received and data is ready to be received.
So it works like this:
connection.onResponse = (res) {
print('Headers received, can read the body now');
var in = res.inputStream;
in.onData = () {
// this can be called multiple times
print('Received data');
var data = in.read();
// do something with data, probably?
};
in.onClosed = () {
// this is probably the event you are interested in
print('No more data available');
};
in.onError = (e) {
print('Error reading data: $e');
};
};

Resources