Cannot Sending Twilio SMS with TwiML Webhook - javascript

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

Related

whtsapp bot from twilio and nodejs - Wait for Reply

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.

Stripe Webhooks StripeSignatureVerificationError

I'm currently testing the Stripe Webhook Endpoints for the Checkout Process.
I'm confused because Stripe shows two different snippets how to set up the Webhook endpoint in their docs.
In the Checkout Doc they show this code snippet:
const stripe = require('stripe')('sk_test_...');
// Find your endpoint's secret in your Dashboard's webhook settings
const endpointSecret = 'whsec_...';
// Using Express
const app = require('express')();
// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');
// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
} catch (err) {
return response.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the checkout.session.completed event
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// Fulfill the purchase...
handleCheckoutSession(session);
}
// Return a response to acknowledge receipt of the event
response.json({received: true});
});
app.listen(8000, () => console.log('Running on port 8000'));
And in their Webhook Docs they are showing this snippet:
const app = require('express')();
// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');
// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
let event;
try {
event = JSON.parse(request.body);
} catch (err) {
response.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
// Then define and call a method to handle the successful payment intent.
// handlePaymentIntentSucceeded(paymentIntent);
break;
case 'payment_method.attached':
const paymentMethod = event.data.object;
// Then define and call a method to handle the successful attachment of a PaymentMethod.
// handlePaymentMethodAttached(paymentMethod);
break;
// ... handle other event types
default:
// Unexpected event type
return response.status(400).end();
}
// Return a response to acknowledge receipt of the event
response.json({received: true});
});
app.listen(8000, () => console.log('Running on port 8000'));
I tried both snippets but nothing seems to work for me.
The first one gives me the StripeSignatureVerificationError when I try to constructEvent(...)
and the second one is telling me that the Object event is undefined.
Does someone know why both of these endpoints are not working for me ?
Before using JSON Body parser configure to receive RAW body
app.use(bodyParser.raw({type: "*/*"})) <-- This line need to be added
app.use(bodyParser.json())
More discussion https://github.com/stripe/stripe-node/issues/331

Express CORS is not working with socket.io

I've used cors for my express server, but I can't figure out why it's not working. Can anyone please help me with this issue?
Access to XMLHttpRequest at
'https://tic-tac-toe-server.now.sh/socket.io/?EIO=3&transport=polling&t=N6Z2b4X'
from origin 'http://localhost:8080' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
Client:
import io from 'socket.io-client';
const socket = io('https://tic-tac-toe-server.now.sh')
Here is my index.js
const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const cors = require('cors');
const router = require('./router');
const { addUser, removeUser, getUsers } = require('./users');
const { getMatch, addPlayer, destroyMatch } = require('./players');
const PORT = process.env.PORT || 5000;
const app = express();
const server = http.createServer(app);
const io = socketio(server);
app.use(router);
app.use(cors());
io.on('connection', function (socket) {
const id = socket.id;
let user_room = '';
/**
* User Joins to the global room
*/
socket.on('join', function ({ name, room, playing = false }) {
addUser({ id, name, room, playing }); // add user to users array
user_room = room;
socket.join(user_room);
socket.join(id);
socket.emit('user_joined', getUsers());
socket.broadcast.emit('user_joined', getUsers()); // emit event with modified users array
});
/**
* Match Started
*/
socket.on('player_joined', user => {
const match = getMatch();
addPlayer(user.match, user);
if(match.hasOwnProperty(user.match) && match[user.match].length === 2){
socket.emit('player_joined', match[user.match]);
socket.broadcast.to(user.match).emit('player_joined', match[user.match]);
}
});
socket.on('move', (data) => {
socket.emit('move', data);
socket.broadcast.to(data.match).emit('move', data);
});
socket.on('emote', (data) => {
socket.emit('emote_from', data);
socket.broadcast.to(data.match).emit('emote_to', data);
});
/**
* On user challenge
*/
socket.on('challenge', (socketId) => {
io.to(socketId).emit('accept', id);
});
socket.on('rejected', (socketId) => {
io.to(socketId).emit('rejected', id);
});
socket.on('accepted', data => {
io.to(data.opponent.id).emit('accepted', data);
socket.emit('accepted', data);
});
socket.on('player_left_match', match => {
socket.broadcast.to(match).emit('player_left_match');
});
socket.on('destroy_match', match => {
destroyMatch(match);
});
/**
* User Disconnect function
*/
socket.on('disconnect', () => {
socket.leave(user_room);
socket.leave(id);
removeUser(id); // remove user form users array
socket.emit('user_left', getUsers());
socket.broadcast.emit('user_left', getUsers()); // emit event with modified users
})
});
server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
You can tell socket.io to only use the webSocket transport which is not subject to CORS by changing this:
const socket = io('https://tic-tac-toe-server.now.sh')
to this:
const socket = io('https://tic-tac-toe-server.now.sh', {transports: ['websocket']});
Some background. In its default configuration, socket.io starts every connection with multiple plain http requests. These plain http requests require server-side CORS support if the connection is cross-origin. But, socket.io can be configured to go straight to the webSocket transport (which is what is eventually ends up using anyway) and webSocket connections are not subject to CORS limitations.
The socket.io design to start with http polling was largely there because in the early days of webSocket support, not every browser supported it and not every server infrastructure supported it. But now-a-days, it is pretty widely supported.
So, telling socket.io to start with the webSocket transport from the beginning avoids many potential CORS issues.
We are now chasing a different issue and the error showing in the console at https://tic-tac-toe-vue.now.sh/ is coming from this code in webSocket.js.
try {
this.ws =
this.usingBrowserWebSocket && !this.isReactNative
? protocols
? new WebSocketImpl(uri, protocols)
: new WebSocketImpl(uri)
: new WebSocketImpl(uri, protocols, opts);
} catch (err) {
return this.emit('error', err);
}
It looks like something React related since there's a reference to isReactNative, but since your code is packaged and minimized, it's not very easy to do any debugging from here.

How to create a local server for dialogflow chatbot?

I am trying to built a local server for dialogflow bot using a node.js framework but ,not able to establish one .
I am using serveo.net as tunneling as ngrok doesn't work as it is blocked by my institute.
I am able to launch a server but unable to get a response from it back to the dialogflow agent.
'use strict';
const {WebhookClient} = require('dialogflow-fulfillment');
const express = require("express"); //express
const bodyParser = require("body-parser"); //body-parser
const app = express(); //app
app.use(bodyParser.json);
app.use(bodyParser.urlencoded({
extended: true
})
);
const WEBHOOK = 'webhook';
app.get('/', (req, res) => res.send('online'));
app.post('/webhook', express.json(), (request, respond) => {
const agent = new WebhookClient({
request,
response
});
function webhookprocessing(request, response) {
const agent = new WebhookClient(request, response);
const action = agent.intent;
if (action == WEBHOOK) {
agent.add("My name is karthik");
} else {
agent.add("karthik");
}
}
function welcome() {
agent.add('Welcome to my agent!')
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set("webhook", webhookprocessing);
agent.handleRequest(intentMap)
//const agentPath = agent.entitiesClient.projectAgentPath("master-bot-53dee");
//console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
//console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
//console.log("Server Hit");
});
app.listen(process.env.PORT || 5000);
edit1: I am getting a request from google dialogflow but my local server isn't sending a response.
edit2: The response payload shown received by dialogflow from my node is
{
"responseId":"efaf7898-74de-4727-bf2a-8eeb32ba570a-baaf0c1f",
"queryResult":{
"queryText":"1",
"parameters":{
"number":1
},
"allRequiredParamsPresent":true,
"fulfillmentMessages":[
{
"text":{
"text":[
""
]
}
}
],
"intent":{
"name":"projects/master-bot-53dee/agent/intents/15b96d92-4adb-4657-8b15-ebdf7df180b4",
"displayName":"webhook"
},
"intentDetectionConfidence":1,
"diagnosticInfo":{
"webhook_latency_ms":4991
},
"languageCode":"en"
},
"webhookStatus":{
"code":4,
"message":"Webhook call failed. Error: Request timeout."
}
}
and the request payload send by dialogflow is
{
"responseId":"efaf7898-74de-4727-bf2a-8eeb32ba570a-baaf0c1f",
"queryResult":{
"queryText":"1",
"parameters":{
"number":1
},
"allRequiredParamsPresent":true,
"fulfillmentMessages":[
{
"text":{
"text":[
""
]
}
}
],
"intent":{
"name":"projects/master-bot-53dee/agent/intents/15b96d92-4adb-4657-8b15-ebdf7df180b4",
"displayName":"webhook"
},
"intentDetectionConfidence":1,
"languageCode":"en"
},
"originalDetectIntentRequest":{
"payload":{
}
},
"session":"projects/master-bot-53dee/agent/sessions/d1205a66-9eda-d79c-7677-75eeb402e7e5"
}
The request sent by dialogflow reaches my public url created by my tunneling software but there isn't any response from the localhost .
This image is a screenshot of my console where I appear to be getting a post request but there isn't a response appearing on dialogflow.
I have used this url to refer webhook url https://excedo.serveo.net/.
app.post('/webhook', express.json(), (request, respond) => { // error name of the param doesn't match its usage
This line you are using respond as the parameter and passing and using response instead .Please change line to -
app.post('/webhook', express.json(), (request, response) => {
The webhook isn't being called at the /webhook path because the configuration in Dialogflow is telling it the webhook is at /. If you change this to https://excedo.serveo.net/webhook it will be routed correctly.

expressJS: How to push socketIO on get call?

This is how I set up a simple expressJS server with a socket.IO connection.
My application is reading some sensor data every 10 seconds, which gets pushed to every client. This is no problem for me.
But also one client can call /set-status with some parameter to change some status data. In that case the new status data should be send to every client. That's why a simple request/response attempt is not working.
What do I have to do to push the socketIO connection after /set-status has been called?
const express = require('express')
const http = require('http')
const socketIo = require('socket.io')
const app = express()
const server = http.createServer(app)
const io = socketIo(server)
io.on('connection', socket => {
getStatus(socket)
getData(socket)
setInterval(
() => getData(socket),
10000
)
})
app.get('/set-status', (req, res) => {
// Change some data and push new data to every client
// How to get access to socket?
res.send(200, 'new-data')
})
const getStatus = async socket => {
const res = { initial: 'data' }
socket.emit('exampleStatus', res)
}
const getData = async socket => {
// read some sensor data, which is refreshed every 10 sec.
// this is working as expected
const res = { some: 'sensor data' }
socket.emit('sensorData', res)
}
server.listen(port, () => {
if (process.env.NODE_ENV !== 'production') {
console.log(`Listening on port ${port}`)
}
})
If client sockets are listening for exampleStatus events, you can emit an exampleStatus event from inside of your get callback. It would look like this: io.emit('exampleStatus', data). On your client sockets, you can write a listener which looks like socket.on('exampleStatus, data => // do something with data).

Categories