Forward messages to another number using Twilio - javascript

I would like to forward all incoming messages to some other number with the number to which I got the reply on Twilio,
For example:
I have a Twilio number say "+14444444444" to which I got the reply from number say: '+15555555555' and I would like to forward all messages to number '+19999999999'.
So I would like to forward all messages on number '+19999999999' which should be received from '+15555555555', not from '+14444444444',
Will anyone please let us know if there is an API in Twilio that can do a trick using nodeJs.
Note: The SMS forwarding number can be dynamic and in that case, we cannot use Twiml, if we can use Twiml so please let us know how to set dynamic forwarding number.
Also got the following link that says how to forward SMS but is not relevant to approach we are trying to accomplish using nodeJS:
https://support.twilio.com/hc/en-us/articles/223134287-Forwarding-SMS-messages-to-another-phone-number
Thanks, any help will be appreciated.

Updated Answer
Thanks, #Alex and #Piyush for clarifying the question:
Really sorry about that! Thanks for clarifying. If I understand you correctly now, you want to forward a message to another number, but preservice the original number from the message. Unfortunately, there's not a way to do this. You can forward the message and include the original sender in the message body, but there's no way to replace the actual sender as the original.
Let me know if I understood that correctly this time and if there's anything else I can help with.
Old Answer (Message forwarding with own number)
You can use TwiML dynamically when using our helper libraries, so that should be something you can setup using Node. When your webhook sends your message to your Node application, you can check the body of the message, and make a conditional SMS request or conditionally point to different TwiML based on the content of the body. Here's an example of how to setup a conditional reply for your incoming messages based on the message body in Node:
https://www.twilio.com/docs/sms/tutorials/how-to-receive-and-reply-node-js
While this example is for replying to messages, it shows you the principles of how conditional TwiML can work.
You would just have add a "to" number you want to forward the message to in the message request.
Below is the example of conditional forward.
const http = require('http');
const express = require('express');
const MessagingResponse = require('twilio').twiml.MessagingResponse;
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/', (req, res) => {
const twiml = new MessagingResponse();
twiml.to = "+1234567890 // Your number here.
if (req.body.Body == 'hello') {
twiml.message('Hi!');
} else if (req.body.Body == 'bye') {
twiml.message('Goodbye');
} else {
twiml.message(
'No Body param match, Twilio sends this in the request to your server.'
);
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(twiml.toString());
});
http.createServer(app).listen(1337, () => {
console.log('Express server listening on port 1337');
});
Let me know if that helps and if you have anymore questions on how to set this up.

Related

Javascript function available but not “readable”

I have a proprietary math formula written in a javascript function that I need to make available for a website to use it without them actually having access to the code itself.
Is it possible?
The idea is to make the formula available online without people being able to read the code. I have no idea how to do it.
I read about private packages on npm, but it seems to restrict prople who can use and read the code. I need them to use it but not read it.
If the code is run on the client's machine in any way, it will be possible for any sufficient dedicated and persistent user to find it, eventually; all code that runs on a page can be found through the browser devtools.
The only way for true privacy for such a thing would be to not send the code that implements the formula to the client in the first place. Set up a server, if you don't already have one, and create a very simple API for it - one that takes the inputs for the formula as, say, a POST request, runs the formula that calculates the result on the server, and responds to the client with the result.
Use node.js to create an express server that listens for incoming requests and then send back the result to the client in the response
const express = require('express');
const app = express();
function proprietaryFormula(x, y) {
// the formula goes here
return x + y;
}
app.get('/formula', (req, res) => {
let x = req.query.x;
let y = req.query.y;
let result = proprietaryFormula(x, y);
res.send(result);
});
app.listen(3000, () => {
console.log('started listening on port 3000');
});
The website can call this API to access the formula's functionality, and the code for the formula is kept on the server and never exposed to the client-side.

How to block an incoming socket connection if the client already has one

So i noticed that you can run 'io()' in console on client side.
I'm worried that if someone were to loop it, it would crash the node.js server.
Does anybody know how to prevent multiple connection for the same user.
It is a fairly complicated process to do that properly.
But on that same note, people won't be able to crash your server with socket.io as easy as you think they would be able to.
Node.js can handle a ton of connections at once, same with socket.io. Obviously these are both dependent on what your server actually is; but even as Raspberry Pi can handle a significant amount of connections.
But, if you truly must implement this, I'd recommend checking out this issue and just making a counter-based dictionary of IP's and to disconnect sockets if their IP goes above a specific number.
Get the client's IP address in socket.io
Very crude, but it would do what you need.
you need some helper function on server side
get user ip with this package:
npm install request-ip
create array of users:
let users = [ ];
validate and add user to array on new join request
const requestIp = require('request-ip');
const addUser = () => {
const ipMiddleware = function(req, res) {
const clientIp = requestIp.getClientIp(req);
};
const existingUser = users.find(user.clientIp === clientIp)
if (existingUser) {
return false
}
const newUser = { clientIp };
users.push(newUser)
return true
}

Callbacks are not supported when broadcasting python-socketio

I have this code, whenever the user goes to this certain endpoint, it is supposed to emit a message to a python client, which then gets some data and then returns it back as a callback so I can show the users the data.
This is the server-side code (NodeJS):
app.get('/hueapi/lights', verifyToken, (req,res) => {
const bridgeIDFromApp = req.header('bridgeID');
const socketID = socketRefDic[bridgeIDFromApp]['socketID'];
io.to(socketID).emit('getAllLights', 'getAllLights', function(data){
res.send(data); // The callback function that shows the data given by the python client
});
});
It just sends a simple 'getAllLights' message to the python client in question and then runs the function which provides the data.
This is the client-side code (python):
def getAllLights(data):
lightData = requests.get('http://localhost:4000/lights/')
return lightData
Am I doing the call back wrong or? I just want to send the data straight back to the user after retrieving it.
EDIT:
I am now using io.to(...).emit(...) instead of io.send(...).emit(...) yet I am still getting the error saying I'm broadcasting, yet I'm not, am I?
I don't think that the ack method will work for you unless it is implemented on the python side as well. The reason that you are still getting the broadcasting error is because io.to does not return a socket it returns a room which does broadcast.
Probably easier to just have a separate endpoint on the client side. Which your python code doesn't even attempt from what I see. The python code should still be able to write to the socket.
So to implement your own ack function you would simply write your ack message to the socket. If you need it to be statefully namespaced then you would have to include an address for the python code to reference with your getAllLights message.
Node:
app.get('/hueapi/lights', verifyToken, (req,res) => {
const bridgeIDFromApp = req.header('bridgeID');
const socketID = socketRefDic[bridgeIDFromApp]['socketID'];
const uniqAck = "some unique endpoint path";
const socket = getSocketByID(socketID);
socket.on(uniqAck, (data) => res.send);
socket.emit('getAllLights', 'getAllLights:'+uniqAck);
});
Python:
def getAllLights(data):
lightData = requests.get('http://localhost:4000/lights/');
return (lightData, split(data, ":")[1]); // split if its not already done by this point.
// capture 'value' from getAllLights when it is called...
socket.emit(value[1], value[0]);

Facebook messenger API incomplete content in request body

The explanation is a bit long so please bear with me.
I am building a Facebook messenger bot which uses my sails.js/node.js server in the backend and a MongoDB database.
In my sails app, I have applied policies to the method of the controller which handles the operations to be performed after recieving a text from the user. In this policy, I am following the documentation(https://developers.facebook.com/docs/messenger-platform/webhook-reference - "Security" section) and comparing the x-hub-signature that comes in the request's header with the sha1 digest of the request payload(body).
So now whenever I am sending a message to the bot, it says in the policy that the signature from the request and the signature calculated by me is different and thus, doesnt go further. I double checked the app secret which I should use while calculating the digest and it seems to be correct. Another difference which I found was that, Facebook request also sends a "content-length" field in its header, which is different than character length of the body they sent in the same request. And this is what I think is the reason for different signatures but I am unable to resolve it and get to the root of the problem as to why is this happening.
Also another thing to note is that the same code that throws this mismatch error, runs perfectly at certain times(actually, most of the times).
So can somebody please help me this? I ll be forever grateful :)
Here is the code from the policy
var crypto = require('crypto');
if(req.headers['x-hub-signature']){
//console.log('req headers -----', JSON.stringify(req.headers));
//console.log('req body -----', JSON.stringify(req.body));
var hmac, calculatedSignature, payload = req.body;
hmac = crypto.createHmac('sha1', app_secret);
hmac.update(JSON.stringify(payload));
calculatedSignature = 'sha1='+hmac.digest('hex');
//console.log("signature calculatedSignature",calculatedSignature);
if(calculatedSignature === req.headers['x-hub-signature']){
return next();
}else{
res.forbidden('You shall not pass!');
}
}
This is a sample request header -
{"host":"e93d4245id.ngrok.io","accept":"*/*","accept-encoding":"deflate, gzip","content-type":"application/json","x-hub-signature":"sha1=d0cd8177add9b1ff367d411942603b0d08183964","content-length":"274","x-forwarded-proto":"https","x-forwarded-for":"127.0.0.1"}
And this is the body from the same request -
{"object":"page","entry":[{"id":"1778585282425767","time":1479476014038,"messaging":[{"sender":{"id":"userId"},"recipient":{"id":"recipientId"},"timestamp":1479468097895,"message":{"mid":"mid.1479468097895:efdc7d2c68","seq":2355,"text":"Hahahaha"}}]}]}
I think the problem was some specific characters such as # and % were needed to be converted to their unicode escape sequence as specified in their documentation and replaced in the original stringified JSON. I converted them and then calculated the hmac signature of the new string and it got matched.
Also the reason why it was working and why it was not in certain cases was I think because of the special characters being present in that string which was being stringified. If it did not have the characters # or % then it worked without any problem.
This is how I solved it -
inside if
var hmac, calculatedSignature, payload = JSON.stringify(req.body);
var resStr = payload.replace(/\#|\%/g,function(a, i){
hex = payload.charCodeAt(i).toString(16);
var s = "\\u" + ("000"+hex).slice(-4);
return s;
});
hmac = crypto.createHmac('sha1', app_secret);
hmac.update(resStr);
calculatedSignature = 'sha1='+hmac.digest('hex');
if(calculatedSignature === req.headers['x-hub-signature']){
return next();
}else{
res.forbidden('You shall not pass!');
}
Your bodyParserJSON should return rawBody (just stringifying will fail in many cases):
bodyParser.json({
verify(req, res, buf) {
req.rawBody = buf;
},
})
Here is a middleware that I've written. It uses crypto module to generate sha1
fbWebhookAuth: (req, res, next) => {
const hmac = crypto.createHmac('sha1', process.env.FB_APP_SECRET);
hmac.update(req.rawBody, 'utf-8');
if (req.headers['x-hub-signature'] === `sha1=${hmac.digest('hex')}`) next();
else res.status(400).send('Invalid signature');
}
and finally in your route you can use it as:
app.post('/webhook/facebook', middlewares.fbWebhookAuth, facebook.webhook);

Node JS sending data via URL

Recently i started programming with Node JS and found it an amazing replacement for php . In php i used to send get requests with Data in the url .
Something like : http://sample.com/public.php?x=helloworld
How to perform something like this in Node JS or is there a better way to send data to node unlike using the url in the above case .
Also , I have noticed that in some cases like stackoverflow , queries are different and dont include the file name
like /public?= instead of /public.php?=
How is this achieved , i always thought this was something related to REST . Also , if you have the answer you might as well guide me if it could be done with Node and a few sources to learn could be of help too .
the most regular way to use REST api
req.query
// GET /search?q=foo+bar
req.query.q
// => "foo bar"
// GET /phone?order=desc&phone[color]=black&shoe[type]=apple
req.query.order
// => "desc"
req.query.phone.color
// => "black"
req.params
// GET /user/william
req.params.name
// => "william"
req.body(for form data)
// POST /login
req.body.username
// => "william"
req.body.password
// => "xxxxxx"
You'll probably be much better off using a pre-existing module as your web server. You can set one up manually, but you have to know about a lot of potential edge cases and really understand web servers. Most people in node use express. In node, as in any server-side language, you can pass data around in a few ways. The query string is one. You can also put some parameters directly in the url (like "/users/12" where 12 is a user id). Depending on the type of request, you can put data in the body of the request. You can also pass cookies. These are not node-specific. Explaining how express works in a post like this would be crazy, so I'll just give you a short example of a what a route handler matching your example route might look like:
var express = require('express');
var app = express();
app.get('/public', function(req, res, next) {
// Get the value from the query string. Express makes the query
// available as an object on the request parameter.
var x = req.query.x;
// Execute your main logic
doSomethingWithX(x);
// Send a response
res.status(200).json({ foo: 'bar' });
});

Categories