Unexpected result when my API server handels aws SNS subscriotion confirmation message - node.js

I've created a topic in AWS SNS. Then I've created a subscription, in which an HTTP protocol is the endpoint .
I've written a simple script in express js to response to messages received from AWS-SNS.
The code expect to receive a json request. Then I'm trying to inspect the header of the request to decide on the appropriate response. If the header is SubscriptionConfirmation then the code will handle the request. And if the header is notification, it'll just print some message.
This is my code:
'use strict';
const express =require('express')
//const axios =require('axios')
//const got=require('got')
const request=require('request')
const app = express()
const bodyParser =require('body-parser')
const port = 4000
app.use(express.json())
// app.use(bodyParser.urlencoded({ extended: true }));
// app.use(bodyParser.json());
app.post('/', async function (req, res) {
try {
let valueStr = req.bod
let payload = JSON.parse(valueStr)
console.log(JSON.stringify(payload))
if (req.header('x-amz-sns-message-type') === 'SubscriptionConfirmation') {
const url = payload.SubscribeURL;
await request (url, handleSubscriptionResponse)
} else if (req.header('x-amz-sns-message-type') === 'Notification') {
console.log(payload)
//process data here
} else {
throw new Error(`Invalid message type ${payload.Type}`);
}
} catch (err) {
console.error(err)
res.status(500).send('Oops')
}
res.send('Ok')
})
var handleSubscriptionResponse = function (error, response) {
if (!error && response.statusCode == 200) {
console.log('Yess! We have accepted the confirmation from AWS');
}
else {
throw new Error(`Unable to subscribe to given URL`);
//console.error(error)
}
}
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
I've used ngrok to test my code. However, I've been getting some unexpected result when runing the script. The result shows some sort of errors which I'm not able to figure out:
Example app listening at http://localhost:4000
SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse (<anonymous>)
at /home/ahmad/snstest/Sns.js:21:28
at Layer.handle [as handle_request] (/home/ahmad/snstest/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ahmad/snstest/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/ahmad/snstest/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/ahmad/snstest/node_modules/express/lib/router/layer.js:95:5)
at /home/ahmad/snstest/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/ahmad/snstest/node_modules/express/lib/router/index.js:335:12)
at next (/home/ahmad/snstest/node_modules/express/lib/router/index.js:275:10)
at jsonParser (/home/ahmad/snstest/node_modules/body-parser/lib/types/json.js:119:7)
(node:36762) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (/home/ahmad/snstest/node_modules/express/lib/response.js:771:10)
at ServerResponse.send (/home/ahmad/snstest/node_modules/express/lib/response.js:170:12)
at /home/ahmad/snstest/Sns.js:36:9
at Layer.handle [as handle_request] (/home/ahmad/snstest/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ahmad/snstest/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/ahmad/snstest/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/ahmad/snstest/node_modules/express/lib/router/layer.js:95:5)
at /home/ahmad/snstest/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/ahmad/snstest/node_modules/express/lib/router/index.js:335:12)
(node:36762) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:36762) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I'm a bit confused about the error !!3
I would appreciate any help on how to resolve this error.

Related

Object.fromEntries is not a function (Node.js error with Express)

I am developing a Node.js app, and it's working great on the local server. However on my Cpanel server (running Node 14.20.1) I am getting this strange error:
"Object.fromEntries is not a function"
The stack trace is
at app.post (/home/joshgncd/riverbank.app/auth/index.js:435:5) \\ this is just the line that prints the error
at Layer.handle [as handle_request] (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/layer.js:95:5)
at next (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/route.js:144:13)
at Route.dispatch (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/route.js:114:3)
at Layer.handle [as handle_request] (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/layer.js:95:5)
at /home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/index.js:284:15
at Function.process_params (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/index.js:346:12)
at next (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/express/lib/router/index.js:280:10)
at cors (/home/joshgncd/nodevenv/riverbank.app/auth/14/lib/node_modules/cors/lib/index.js:188:7)
The function calling it never calls Object.fromEntries:
app.post('/auth/notion/action', async (req, res) => {
try {
const data = req.body
const tokens = users[req.query.email].notion_tokens
const notion = new Notion({
auth: tokens.access_token
})
let response = await notion.search(data)
res.send(response)
} catch (err) {
console.trace(err.message)
res.status(400).send(err.message)
}
})
Can someone help figure out why this is happening?
I also am sure it's not a Notion API error as I replaced let response = await notion.search(data) with an Axios HTTP request and still got this Object.fromEntries error.
I have fixed the issue by using this libary: polyfill-object.fromentries

Req.body of a twilio webhook request is undefined node js

I tried following this twilio article:
https://www.twilio.com/blog/parsing-an-incoming-twilio-sms-webhook-with-node-js
The following is my server in its entirety
// Imports
const http = require('http')
const express = require('express')
const app = express()
const port = 80
const MessagingResponse = require('twilio').twiml.MessagingResponse;
// Static Files
app.use(express.static('public'))
// Set views
app.set('views', './views')
app.post('/sms', (req, res) => {
const twiml = new MessagingResponse();
// Access the message body and the number it was sent from.
console.log(req.IncomingMessage.body)
res.writeHead(200, {'Content-Type': 'text/xml'});
res.end(twiml.toString());
});
// Listen on port
app.listen(port, () => {
console.log(`Running on port ${port}`)
})
I have the webhook of my twilio phone posting to "http://{domain}.com/sms"
Every time I send a text to my twilio phone, I get the following error:
TypeError: Cannot read property 'body' of undefined
at app.post (/home/ubuntu/{domain}/server.js:24:37)
at Layer.handle [as handle_request] (/home/ubuntu/{domain}/node_modules/express/lib/router/layer.js:95:5)
at next (/home/ubuntu/{domain}/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/ubuntu/{domain}/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/ubuntu/{domain}/node_modules/express/lib/router/layer.js:95:5)
at /home/ubuntu/{domain/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/ubuntu/{domain}/node_modules/express/lib/router/index.js:335:12)
at next (/home/ubuntu/{domain}/node_modules/express/lib/router/index.js:275:10)
at serveStatic (/home/ubuntu/{domain}/node_modules/serve-static/index.js:75:16)
at Layer.handle [as handle_request] (/home/ubuntu/{domain}/node_modules/express/lib/router/layer.js:95:5)
I don't think the req object has any property called IncomingMessage. Instead you could try:
console.log(`Incoming message from ${req.body.From}: ${req.body.Body}`);
So based on the twilio specs, the endpoint would look like:
app.post('/sms', (req, res) => {
const twiml = new MessagingResponse();
// Access the message body and the number it was sent from.
console.log(`Incoming message from ${req.body.From}: ${req.body.Body}`);
res.writeHead(200, {'Content-Type': 'text/xml'});
res.end(twiml.toString());
});
Since the message body is in the req.body.Body parameter, so console logging this property will show you the message text.
First answer is correct,
console.log(`Incoming message from ${req.body.From}: ${req.body.Body}`);
but I had to make sure to set the express urlencoding or else req.body came back as undefined.
app.use(
express.urlencoded({
extended: true,
})
);
I'm not sure if this is correct but when I'm using express I use req.body.IncomingMessage
console.log(req.body.IncomingMessage)

Cant use parseInt() in LocalHost NodeJS - Body Parser

im actully new in node js so i got this error while using parseInt or Number() in my server
code :
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/bmicalculator", function(req, res) {
res.sendfile(__dirname + "/index.html");
});
app.post("/bmicalculator", function(req, res) {
var nm1 = parseInt(req.body.num1); // <-- here the error
var nm2 = parseInt(req.body.num2); // <-- here the error
var result = nm1 + nm2 * nm2;
res.send(result);
});
app.listen(3000, function() {
console.log("server started");
});
here the error from Browser & Terminal :
RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 29636
at ServerResponse.writeHead (_http_server.js:248:11)
at ServerResponse._implicitHeader (_http_server.js:239:8)
at ServerResponse.end (_http_outgoing.js:763:10)
at ServerResponse.send (C:\Users\Amir\Desktop\Calculator\node_modules\express\lib\response.js:221:10)
at C:\Users\Amir\Desktop\Calculator\calculator.js:16:9
at Layer.handle [as handle_request] (C:\Users\Amir\Desktop\Calculator\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Amir\Desktop\Calculator\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Amir\Desktop\Calculator\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Amir\Desktop\Calculator\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Amir\Desktop\Calculator\node_modules\express\lib\router\index.js:281:22
This error seems to be caused by the method res.send. In old version of Express (v3),
the first argument used to be http status code but in your case, it's a big number (invalid http status code), hence the error is thrown.
in order to fix this, you can do either
upgrade to a newer version of express.
do this res.send(200, result) instead.
See the Express v3 docs here for reference: https://expressjs.com/en/3x/api.html#res.send
res.send([body|status], [body])
Send a response.
res.send(Buffer.from('whoop'))
res.send({ some: 'json' })
res.send('<p>some html</p>')
res.send(404, 'Sorry, we cannot find that!')
res.send(500, { error: 'something blew up' })
res.send(200)
You can see your case is same as the last example but your first argument is a big number 29636, which is invalid status code.
Add:
app.use(bodyParser.json());
And change the reponse to:
res.send(200, result);

What to log to debug Error [ERR_HTTP_HEADERS_SENT]?

In an Express controller function, I am running into to this error Error [ERR_HTTP_HEADERS_SENT]. This occurs when I call res.json() if headers have already been set on the res object. However, I don't see place in my function (or middleware) where headers could be set prior to my calling res.json().
To debug the cause of this error, I thought I could add some logging. Prior to calling res.json, I could check if headers had been set and, if so, log some information about who set them.
async function get(req, res) {
...
if (res._header) {
logger.debug(...);
}
res.json(...);
Unfortunately, I don't see anything useful in the res object to log, any message that would indicate why/how the headers were set (or who set them). Any suggestions for what I could log to debug this issue? Or other debugging suggestions?
You can patch res.header res.send res.set to log the stack trace for you. For example this is my main application.
const express = require('express');
const app = express();
const someGoody = require('./stupid-blackbox');
/** patch the res **/
app.use((req, res, next) => {
const _header = res.header.bind(res); // .header and .set is an alias pair
const _send = res.send.bind(res);
res.header = res.set = (field, val) => {
console.trace('.header/.set called', field, val);
console.log('-----');
return _header(field, val);
}
res.send = (body) => {
console.trace('.send called', body);
console.log('-----');
return _send(body);
}
next();
})
// some innocent looking middleware
app.use(someGoody);
// my main routes
app.get('*', (req, res) => {
res.json({url: req.url});
})
app.listen(3000);
And for stupid-blackbox.js:
const express = require('express');
const router = express.Router();
router.use((req, res, next) => {
res.header('X-Crash-You', '1').send(':)');
next();
})
module.exports = router;
When ran, you will get this in the log:
Trace: .header/.set called X-Crash-You 1
at ServerResponse.res.header.res.set (C:\Users\eric_\Desktop\initial\play\index.js:11:13)
at router.use (C:\Users\eric_\Desktop\initial\play\stupid-blackbox.js:6:9)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:317:13)
at C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
-----
Trace: .send called :)
at ServerResponse.res.send (C:\Users\eric_\Desktop\initial\play\index.js:17:13)
at router.use (C:\Users\eric_\Desktop\initial\play\stupid-blackbox.js:6:36)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:317:13)
at C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:275:10)
at Function.handle (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\eric_\Desktop\initial\play\node_modules\express\lib\router\layer.js:95:5)
On the second line of each stack trace you can see the stupid-blackbox.js.
On a side note, res.json will not result in error if only res.header or res.set is called, the error is headers has been sent so that means somewhere in the code, res.send is called causing headers to be sent before your actual code.

Can't reply on message through vk node bot

I created the bot with Botact packdge, it running, but I constantly have this error:
**
(node:5744) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined
at executionItems.forEach (D:\Node\VK-sleep-bot\node_modules\botact\lib\utils\callbackHandler.js:7:35)
at Array.forEach (<anonymous>)
at module.exports (D:\Node\VK-sleep-bot\node_modules\botact\lib\utils\callbackHandler.js:4:18)
at api.then.catch.err (D:\Node\VK-sleep-bot\node_modules\botact\lib\utils\executeHandler.js:15:23)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:118:7)
(node:5744) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
**
Here my code:
const express = require('express');
const bp = require('body-parser');
const { Botact } = require('botact');
const app = express();
const bot = new Botact({
token: 'c70595eee2bcec797e2e18cb10eab81d46e3ffc68caea34e4d005f231af1c733c751c1ff9cd4908722591',
confirmation: '65a50ccd'})
bot.on(function(ctx){
console.log(ctx.body);
ctx.reply('Hello');
});
app.use(bp.json());
app.post('/', bot.listen);
app.listen(80);
Is anyone know, how I can fix it?

Resources