whtsapp bot from twilio and nodejs - Wait for Reply - javascript

Trying to create a WhatsApp bot through twilio
Can send one sided messages
Unable to send a response message on a completed question
Sending sample code that doesn't work
From what it seems the reference to POST is not the correct reference
Thank you
app.post('/message', (req, res) => {
const message = req.body.Body;
if (message === 'hello') {
client.messages
.create({
body: 'Hello, how can I help you?',
from: 'YOUR_TWILIO_NUMBER',
to: 'USER_PHONE_NUMBER'
})
.then((message) => console.log(message.sid));
}
});

You don't need to use client.messages.create() if you "just" want to reply to an incoming message. This is possible but isn't recommended as the webhook call might return a error status code even though the reply was successful.
Instead, you can reply with a TwiML response:
const express = require('express');
const { MessagingResponse } = require('twilio').twiml;
const app = express();
app.post('/sms', (req, res) => {
const twiml = new MessagingResponse();
twiml.message('The Robots are coming! Head for the hills!');
res.type('text/xml').send(twiml.toString());
});
app.listen(3000, () => {
console.log('Express server listening on port 3000');
});
PS: Here's the related doc file for this use-case.

Related

Is it possible to implement socket.io connection in express route?

I implement a payment service which depend on one of my express route as a callback route, so whenever a user want to make a payment, they will be redirected to this payment service link which entirely different my backend/frontend domain. After a successful payment, user will then be redirected to my express GET route (callback route), in this route is where I give users their asset and then redirect them to the frontend.
EXPECTATION
My expectation is, whenever a user make a purchase, I want a real time update on the frontend for others to see some details about the purchase without refreshing their browser.
WHAT I'VE TRIED
I had think socket.io would solve this, like adding a socket connection in the route to then push the data to the frontend. But after making lot of research, no solution seems to work for me.
HERE IS A SIMPLE CODE OF WHAT I'VE TRIED
=============================== server.js ========================
const express = require("express")
const app = express()
const http = require("http")
const cors = require("cors")
const session = require("express-session")
const runSocket = require("./runSocket")
const { Server } = require("socket.io")
app.use(cors())
app.use(express.json())
const server = http.createServer(app)
server.listen(3004, () => {
console.log("SERVER IS RUNNING")
})
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
})
const postRoute = require("./routes/postData")(io)
app.use("/post-data", postRoute)
==================================== postData Route ======================================
module.exports = function (io) {
router.post("/", async (req, res) => {
const data = req?.body?.data.message
const room = req?.body?.data?.room
io.on("connection", (socket) => {
console.log("Socket Running...")
socket.to(room).emit("the_message", data)
})
console.log("Under socket...")
return res.status(200).json({ data: req.body.data })
})
return router
}
This log: in postData route is not printing console.log("Socket Running...")
EXPECTATION
My expectation is, whenever a user make a purchase, I would like to make a real time update on the frontend for others to see some details about the purchase.
UPDATE: The Payment Gateway config looks somthing like this:
const { body } = await got.post("https://payment-provider-link", {
headers: { Authorization: "Bearer token for payment" },
json: {
email: "email#gmail.com",
amount: amount * 100,
initiate_type: "inline",
callback_url: `${BackendBaseUrl}/payment-callback`, // <<<============
},
})
Okay so you don't need the io.on("connection") in ur route. Remove that piece of code and simply change it to io.to(room).emit("the_message", data). Also make sure to have the other sockets joined the room ur trying to emit to otherwise they won't receive the data.

getting error 405 'Method not Allowed' When trying to send request to my node server

Its my first time using Express and MongoDB, i have created my Node server and connected it to my mongoDB database, but when i try to send an request from my html page to the server i get Error 405 method not allowed, following is my node.js server code
mongoose.connect('mongodb://localhost/userdatabase' ,{
useNewUrlParser: true,
useUnifiedTopology: true
})
const app = express()
app.use('/', express.static(path.join(__dirname, 'static')))
app.use(bodyParser.json())
const port = 5500
app.listen(port, () => {
console.log(`server is up at ${port}`)
})
app.post('/api/register', async(req, res) => {
const {username, password} = req.body
res.json({status: 'ok'})
try{
const response = await User.create({
username,
password
})
console.log('User created succesfully' , response)
}catch(error){
console.log(error)
}
})
and here is the function im trying to call to do the post request
const form = document.querySelector('#register')
form.addEventListener('submit', registerUser)
async function registerUser(event){
event.preventDefault()
const username = document.getElementById('username').value
const password = document.getElementById('password').value
const result = await fetch('/api/register', {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}, body: JSON.stringify({
username,
password
})
}).then(res => res.json())
}
basically i am creating an login system and try to register users, but for some reason i keep getting the error 405 when trying to call the Server, Note that for some reason it worked 3 times when i was trying earlier, I havent changed almost anything in the code but it just wont work, what it can be ? thanks in advance
You should tell in which port mongoDB would run.
const mongoose = require('mongoose');
main().catch(err => console.log(err));
async function main() {
await mongoose.connect('mongodb://localhost:27017/test');
}
I think you have to declare the server and port while calling the axios. The axios call should be - await fetch('localhost:5500/api/register'). It's searching for '/api/register' but didn't find anything. Hope this will solve your issue.
Issue solved : the html file wasn't in the folder 'static' 😅 probably i have moved it and didn't noticed, sorry for the question guys, if anyone have the same problem make sure to check it

get method not displaying the data on browser and put showing error on postman

I'm creating an API with JS. While using the get method I'm not receiving the JSON data from the ./personal_data.js file. It's only displaying closed braces as response.
I'm attaching the code and output below. Any suggestions might be helpful.
const express = require('express');
const personal_data = require('./personal_data');
const app = express();
app.listen(3000, () => {
console.log('Listening on port 3000');
});
app.get('/', (req, res) => {
res.json({ Message: 'API is Working' }); // show messsage on serv
});
app.get('/personal_data', (req, res) => {
res.json(personal_data); // send employee json file
});
app.post('/personal_data',(req,res)=>{
res.send('post request')
})
json file with data
OUTPUT
Post man
Make sure you're exporting your data correctly. Use module.exports = ... instead of module.export = ... in your personal_data.js. Don't forget to restart your server once it's updated.
Check this sandbox where I show you the difference: CodeSandbox

Cannot Sending Twilio SMS with TwiML Webhook

The code below should send the message "TwilioQuest rules", via twilio webhook using ngrok so that it can be accessed via the internet https://765ec92dsf.ngrok.io/sms to send messages. But when the code is executed it always displays response 404. And I don't know where the error lies, because the console.log doesn't display anything.
My Code
const http = require('http');
const express = require('express');
const { urlencoded } = require('body-parser');
const ngrok = require('ngrok');
const twilio = require('twilio');
// Set up our express web application
const PORT = 8767;
const app = express();
app.use(urlencoded({ extended: false }));
// Create a route to handle incoming SMS messages
// This is where the magic happens!
app.post('/sms', (request, response) => {
console.log(
`Incoming message from ${request.body.From}: ${request.body.Body}`
);
response.type('text/xml');
response.send(`
<Response>
<Message>TwilioQuest rules</Message>
</Response>
`);
});
// Create and run an HTTP server which can handle incoming requests
const server = http.createServer(app);
server.listen(PORT, () =>
console.log(`Express server listening on localhost:${PORT}`)
);
// -----------------------------------------------------------------------------
// This code sets up a tool called ngrok to let Twilio talk to the app running
// on your computer. It then uses the Twilio REST API to direct all incoming
// SMS messages to your local app. You should not have to edit any of this
// code below.
// -----------------------------------------------------------------------------
(async function() {
try {
await ngrok.disconnect();
await ngrok.kill();
let url = await ngrok.connect(PORT);
console.log('ngrok forwarding configured - your app is live at ', url);
let client = twilio(
process.env.TQ_TWILIO_ACCOUNT_SID,
process.env.TQ_TWILIO_AUTH_TOKEN
);
let ngrokUrl = `${url}/sms`;
let number = await client
.incomingPhoneNumbers(process.env.TQ_TWILIO_NUMBER_SID)
.update({
smsUrl: ngrokUrl,
smsMethod: 'POST',
});
console.log(
`${number.phoneNumber} configured to send incoming SMS to ${ngrokUrl}`
);
console.log(
`Send a message to ${
number.phoneNumber
} and check the reply you get back!`
);
} catch (e) {
console.log('There was an error configuring incoming SMS:');
console.log(e);
}
})();
Response
Cannot GET /sms
Thanks

NextJS, Express, Error during WebSocket handshake: Unexpected response code: 200

The basic problem can be summarized as follows: When creating a Websocket server in Node using ws with the server option populated by an express server(as in this example), while using that same express server to handle the routing for NextJS (as in this example), the upgrade header seems to not be properly parsed.
Instead of the request being routed to the Websocket server, express sends back an HTTP 200 OK response.
I've searched high and low for an answer to this, it may be that I simply do not understand the problem. A possibly related question was brought up in an issue on NextJS's github. They recommend setting WebsocketPort and WebsocketProxyPort options in the local next.config.js, however I have tried this to no avail.
A minimal example of the relevant server code can be found below. You may find the full example here.
const express = require('express')
const next = require('next')
const SocketServer = require('ws').Server;
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
const wss = new SocketServer({ server });
wss.on('connection', function connection(ws, request) {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
wss.on('error', function (error) {
console.log(error);
});
setInterval(() => {
wss.clients.forEach((client) => {
client.send(new Date().toTimeString());
});
}, 1000);
}).catch(ex => {
console.error(ex.stack);
process.exit(1);
});
The expected result, of course, is a connection to the websocket server. Instead I receive the following error:
WebSocket connection to 'ws://localhost:3000/' failed: Error during WebSocket handshake: Unexpected response code: 200
Can anyone elucidate anything for me here?
Ok, after more digging I have solved the problem. Quite simply, the ws.Server object to which I was trying to feed the server = express() object is not strictly speaking an http server object. However, server.listen() returns such an http server object. On such an object we can listen for an 'upgrade' call, which we can pass to our ws.Server object's handleUpgrade() event listener, through which we can connect. I will be updating the examples that I linked in my question, but the relevant code is below:
app.prepare().then(() => {
const server = express()
server.all('*', (req, res) => {
return handle(req, res)
})
const wss = new SocketServer({ server });
wss.on('connection', function connection(ws, request) {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
wss.on('error', function (error) {
console.log(error);
});
let srv = server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
srv.on('upgrade', function(req, socket, head) {
wss.handleUpgrade(req, socket, head, function connected(ws) {
wss.emit('connection', ws, req);
})
});

Categories