Node.js and twilio integration - node.js

I am trying to integrate twilio with Node.js+express.
I don't have a site yet. what value should I give for HOSTNAME, along with SID and AUTH_TOKEN, these values I got from twilio site.
I have written some code, whatever suggestion given below I have placed in to views folder in twiclient.js , I have added a route in app.js to redirect the request if /twi is called , but I am not getting any result. some errors are appearing in the console, would you please help me figure out what I'm doing wrong? I have placed the correct SID, token and hostname, as specified below.
app.js has the following entry, does anything else need to be done for the twilio calling part to work?
Also, where should I define the GUI for calling a phone in the views folder?
var TwilioClient = require('twilio').Client,
      Twiml = require('twilio').Twiml,
      sys = require('sys');
var client = new TwilioClient('MY_ACCOUNT_SID', 'MY_AUTH_TOKEN', 'MY_HOSTNAME');
var phone = client.getPhoneNumber('+2323232323');
phone.setup(function() { phone.makeCall('+15555555555', null, function(call) {});
phone.setup(function() {
    phone.makeCall('+15555555555', null, function(call) {
        call.on('answered', function(callParams, response) {
            response.append(new Twiml.Say('Hey buddy. Let\'s meet for drinks later tonight.'));
            response.send();
        });
    });
});

The hostname is 'api.twilio.com'. Your SID and AUTH_TOKEN come from your twilio account. When you log in, go to the dashboard. You'll find your SID and AUTH_TOKEN listed there.
Here's the code I use to make a request to twilio to place a call. It should help you get started.
var https = require('https');
var qs = require('querystring');
var api = 'your api key';
var auth = 'your auth token';
var postdata = qs.stringify({
'From' : '+5554321212',
'To' : '+5552226262',
'Url' : 'http://yourwebsite.com/call'
});
var options = {
host: 'api.twilio.com',
path: '/2010-04-01/Accounts/<your api key>/Calls.xml',
port: 443,
method: 'POST',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
'Content-Length' : postdata.length
},
auth: api + ':' + auth
};
var request = https.request(options, function(res){
res.setEncoding('utf8');
res.on('data', function(chunk){
console.log('Response: ' + chunk);
})
})
request.write(postdata);
request.end();

Related

IIS authentication for http request with Nodejs

I have one problem with HTTP GET/POST request.
When I use the DHC/Postman, send the parameters to the URL + endpoint, works perfectly. 200 is returned.
But with code, like my example, show one 401 error.
I have searched about that and the problem is with the auth, not sure, see... Maybe is the same.
With this explanation, need to set the Authorization, I think. But the problem is when I access the site, the auth is automatic, see:
My code:
var jsonObject = JSON.stringify({ "UserName": login});
// prepare the header
var postheaders = {
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};
// the post options
var optionspost = {
host: "xxxxxxxxxx.com",
// path: '/Home/endpoint', //send the data for the endpoit with Postma works fine
method: 'POST',
headers : postheaders
};
console.info('Options prepared:');
console.info(optionspost);
console.info('Do the POST call');
// do the POST call
var reqPost = http.request(optionspost, function(res) {
console.log("statusCode: ", res.statusCode);
// uncomment it for header details
// console.log("headers: ", res.headers);
res.on('data', function(d) {
console.info('POST result:\n');
process.stdout.write(d);
console.info('\n\nPOST completed');
});
});
// write the json data
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
console.error(e);
});
Obs.: This website it's from my Company (.NET) and is Integrated with IIS (Active Directory login users for authenticate), when I access, automatically is logged... I really don't know how to solve this.
Obs II.: I Try to use one anonymous new tab and use DHC online, and my post doesn't work. This application just works inside network company and with Client side (Using postman with my computer).
Obs III.: The request is from Server and the login from my server have all permissions to access this site, and when I request, is like I'm anonymous, but if I did the same with REST Client/Postman, works perfectly. I need that it works with http request from my Server.
You can use a module like ntlm-webapi which will allow you to use NTLM auth. That way the request will go through. Just make sure the user you use is authorized for that server.
var Request = require('ntlm-webapi');
var request = new Request({
url: "http://some.restful.api.org/you/want/to/call",
username: 'username',
password: 'password',
domain: 'company_domain'
});
request.get(function(err, result){
if (err) console.log (err);
console.log (result);
});
It seems that you forgot to add the Authorization header in your code
// prepare the header
var postheaders = {
'Authorization' : 'Negotiate '+ yourAccessKey,
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};

Node.js post video from s3 to Facebook via Graph API

I have a video file on s3 that I want to post to a user Facebook account:
https.get(signedUrlOfObjectInS3, function(httpRes){
var form = new formData(); // that's form-data module https://github.com/felixge/node-form-data
form.append('source', httpRes);
var options = {
method: 'post',
host: 'graph-video.facebook.com',
path: '/me/videos?access_token=' + user_access_token,
headers: form.getHeaders(),
}
var buffer = '';
var apiCall = https.request(options, function (res){
res.on('data',function(chunk){
buffer += chunk;
});
res.on('end',function(){
var data = JSON.parse(buffer);
console.log('data from fb is: ' + util.inspect(data));
});
});
form.pipe(apiCall);
});
The response I get from Facebook is:
(#352) Sorry, the video file you selected is in a format that we don\'t support.
The video file on s3 is a mov file with a content type of video/quicktime.
OK, so apparently Facebook ignores the content type in the headers and guesses it from the file name. Since the s3 signed url doesn't end with filename.mov for example, it doesn't get it...
All I had to do was concating a '&f=filename.mov' to the end of the signedUrl, and now Facebook get that...
The following code actually worked fine for me for me:
https.get(signedUrlOfObjectInS3, function(httpRes) {
var form = new FormData(); // that's form-data module https://github.com/felixge/node-form-data
form.append('source', httpRes);
var options = {
method: 'post',
host: 'graph-video.facebook.com',
path: '/me/videos?access_token=' + user_access_token,
headers: form.getHeaders(),
}
var apiCall = https.request(options);
form.pipe(apiCall);
apiCall.on('response', function(res) {
console.log(res.statusCode);
});
});
try making the small difference in apiCall postback ,
other explanation might be that i've used a public amazon URL...

Clean Instagram oauth using node.js and express and minimal middlewares

I am trying to get a clean Instagram oauth without relying on middlewares such as passport, or instagram-node to learn the process and have maximum control. I have been trying to follow instagram Server-side (Explicit) Flow, which is a 2 step operation:
request an access code
request an access token
right now my server is set up using:
express = require('express'),
app = express();
and to initiate the first step I am using :
app.get('/', function(req, res){
var url = 'https://api.instagram.com/oauth/authorize/?client_id='+CLIENT-ID+'&redirect_uri='+YOUR-REDIRECT-URI+'&response_type=code'
res.redirect(url);
});
The above step sends me properly to instagram for authentication and the redirect callback of instagram gets picked up bellow at which point the console.log does display the correct instagram code. But the res.set part is wrong and does not work.
app.get('/auth/instagram/callback', function(req, res){
console.log('/// here to keep track of how many times this is called');
console.log('Instagram code: ', req.query.code);
var url = 'https://api.instagram.com/oauth/access_token';
res.set({
'client_id' : 'CLIENT-ID',
'client_secret' : 'CLIENT-SECRET',
'grant_type' : 'authorization_code',
'redirect_uri' : 'YOUR-REDIRECT-URI',
'code' : req.query.code
}).redirect(url);
});
Unfortunately it hangs at this point and clearly does not provide back the right data back.
Instagram suggest to do the following, but I am unsure how this would translate in express:
curl \-F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri=YOUR-REDIRECT-URI' \
-F 'code=CODE' \https://api.instagram.com/oauth/access_token
Any insight on this would be most welcome!
Thank you for your help.
And here is the actual response for the second part of OAuth with Instagram! Might not
var data = {'client_id' : process.env.FANCRAWLCLIENTID,
'client_secret' : process.env.FANCRAWLCLIENTSECRET,
'grant_type' : 'authorization_code',
'redirect_uri' : process.env.INSURIREDIRECT,
'code' : req.query.code
};
// Configure the request
var options = {
uri: 'https://api.instagram.com/oauth/access_token',
method: 'POST',
form: data
}
request(options, function (error, response, body) {
// to convert the string body to a usable object
var pbody = JSON.parse(body);
// pbody should look like this:
// {"access_token":"8943851.83434d.697342341324jkfdjsf41afd784932a2e8",
// "user":
// {"username":"my_user_name",
// "bio":"blah blah...",
// "website":"http:\/\/www.something.com",
// "profile_picture":"http:\/\/images.ak.instagram.com\/profiles\/profile_851_73sq_115.jpg",
// "full_name":"Full Name",
// "id":"8943851"}
// }
});
Enjoy!!!
I would suggest studying passport code (and instagram in particular).
In any case, after getting the code back (which works for you), you need to send a request from your backend code to Instagram. So your code would look more like (top of my head):
app.get('/auth/instagram/callback', function(req, res){
console.log('/// here to keep track of how many times this is called');
console.log('Instagram code: ', req.query.code);
var data = {
'url': url
'client_id' : 'CLIENT-ID',
'client_secret' : 'CLIENT-SECRET',
'grant_type' : 'authorization_code',
'redirect_uri' : 'YOUR-REDIRECT-URI',
'code' : req.query.code
};
var url = 'https://api.instagram.com/oauth/access_token';
request.post({
method: 'POST',
url: url,
body: JSON.stringify(data),
},
function (e, r, body) {
//body will contain the access_token
});
});
Then after you get the token you can set session, etc.
Ok got it to work to do post request for specific API calls but not yet the OAUTH part.. and WITH instagram secure header.
This exemple is to follow a user when you have an access token for a user.
var crypto = require('crypto'),
request = require('request');
var hmac = crypto.createHmac('SHA256', 'INSTAGRAM_CLIENT_ID');
hmac.setEncoding('hex');
hmac.write('IP_ADDRESS_127.0.0.1_OR_12.34.56.78');
hmac.end();
var hash = hmac.read();
// Set the headers
var headers = {
'X-Insta-Forwarded-For': 'IP_ADDRESS_127.0.0.1_OR_12.34.56.78|'+hash
}
// Configure the request
var options = {
uri: 'https://api.instagram.com/v1/users/1234/relationship_ OR WHATEVER API CALL',
qs: {'access_token': 'INSTAGRAM ACCESS TOKEN'},
method: 'POST',
headers: headers,
form:{action:'follow'}
}
request(options, function (error, response, body) {
// body response is what you are interested in
// NOTE that the body info is a string response so use var your_variable = JSON.parse(body) to use it as an object.
// Some exemples bellow
// USER NOT EXISTANT
// {"meta":{"error_type":"APINotFoundError","code":400,"error_message":"this user does not exist"}}
//
// successful response from unfollow
// {"meta":{"code":200},"data":{"outgoing_status":"none","target_user_is_private":false}}
//
// NOT FOLLOWING OR FOLLOWED BY
// {"meta":{"code":200},"data":{"outgoing_status":"none","target_user_is_private":false,"incoming_status":"none"}}
//
// you are following user 1234 but not followed back by them
// {"meta":{"code":200},"data":{"outgoing_status":"follows","target_user_is_private":false,"incoming_status":"none"}}
//
// Following and followed by
// {"meta":{"code":200},"data":{"outgoing_status":"follows","target_user_is_private":true,"incoming_status":"followed_by"}}
//
// PRIVATE users
// {"meta":{"code":200},"data":{"outgoing_status":"requested","target_user_is_private":true}}
});
I hope this helps.

Req.data not showing up once sent to server with POST method (using connect middleware)

I'm unable to get the var data I sent in via a POST method. This should be easy (right?), but I'm clearly missing something (either conceptually or a setting).
At this stage, I simply want to check to see if the server side code will output the data to the console. The array is being stringify-ed correctly, eg. ['one','two','three'] becomes 0=one&1=two&2=three
but I can't pull it out on the server side.
What am I missing?
Client side
var qs = require('querystring')
, http = require('http');
var some_array = ['one','two','three'];
var data = qs.stringify(some_array);
var options = { host: 'localhost',
path: '/search',
port: '3000',
method: 'POST',
headers: { 'content-length': Buffer.byteLength(data),
'Content-Type': 'application/json' }
}
function go_post(data) {
req = http.request(options, function(res) {
// do something with response
});
req.write(data);
req.end();
};
go_post(data);
Server side
var connect = require('connect');
var qs = require('querystring');
var server = connect.createServer();
server.use(function(req,res,next) {
if ( '/search' == req.url && req.method == 'POST' ) {
// quick check to see if data came through
console.log('BODY IS ' + req.data);
} else {
next();
};
});
These objects arent available because they are still in the "raw" request. You have to use a middleware like connect().use(connect.bodyParser()) in order to get them from the request via req.data.

Twitter Streaming API - Node.js returning unauthorised error (OAuth)

I'm attempting to connect to Twitters Streaming API over OAuth using http.get although I'm having a slight problem.
The script keeps returning unauthorised
The code I'm using follows, can anybody tell me if I'm missing something stupid or my headers are incorrect.
var https = require('https');
var options = {
host: 'stream.twitter.com',
path: '/1.1/statuses/filter.json?track=bieber',
method: 'GET',
headers: {
authorization: '
OAuth
oauth_consumer_key = "",
oauth_nonce = "",
oauth_signature = "",
oauth_signature_method = "HMAC-SHA1",
oauth_timestamp = "",
oauth_token = "",
oauth_version = "1.0"
'
}
};
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log(chunk);
});
});
req.on('error', function(e) {
console.log('Oops... ' + e.message);
});
req.write('data\n');
req.write('data\n');
req.end();
The problem I had here was that the OAuth request was NOT being signed, which ment the authorisation was failing.
OAuth is a complicated process and it's best to use a library or NPM module that has already been developed.
The particular NPM I used in this instance was node-oauth
try this:
var options = {
host: 'stream.twitter.com',
path: '/1.1/statuses/filter.json?track=bieber',
method: 'GET',
auth : "YOUR_ID:YOUR_PASS"
};
var https = require('https');
https.get(options,function(res){
res.on("data",function(trunk){
//YOUR CODE
}).on("end",function(){
//YOUR CODE
}).on("error",function(e){
//YOUR CODE
});
}

Resources