cannot able to verify the twitter details in nodejs? - node.js

I used this link https://dev.twitter.com/apps I followed the procedure and I got the consumer key,consumer secret key,access token key,access token secret details.I put it in my code.I ran in localhost It shows **twitter.verifyCredentials is not a function.**I enclosed the code can anyone tell me what is the problem in the code.Thanks in advance...
var twitter=require("twitter");
var tweeter = new twitter(
{
consumer_key:'xyz',
consumer_secret:'abx',
access_token_key:'asd',
access_token_secret:'www'
});
app.get('/twitterCheck', function (req, res) {
twitter.verifyCredentials(function (error, data)
{
res.send("Hello, " + data.name + ". I am in your twitters.");
});
});
app.listen(8086,function()
{
console.log("port is listen on 8086");
});

This is from node-twitter-api package. Try using node-twitter-api, This will work:
const express = require('express')
const app = express()
const twitterAPI = require('node-twitter-api');
const twitter = new twitterAPI({
consumerKey: '*****',
consumerSecret: '******',
});
const accessToken = "***********";
const accessTokenSecret = "***********";
const params = {};
app.get('/twitterCheck', function (req, res) {
twitter.verifyCredentials(accessToken, accessTokenSecret, params, function (error, data, response) {
if (error) {
console.log(error);
} else {
console.log(data["screen_name"]);
}
});
});
app.listen(8086, function () {
console.log("port is listen on 8086");
});

Related

Connection is getting reset if I am doing a POST request

I am new to Node JS. Please help me to understand what am I doing wrong in the POST request. Sometimes my POST request is getting successfully resolved but sometimes it is giving me ECONNRESET.
I am sharing my app.js and file reader wrapper module.
GET is working perfectly fine.
Below is my App.js
const express = require('express');
const FileReader = require('./readFS');
const app = express();
const FS = new FileReader();
const port = 3000;
app.listen(3000, '127.0.0.1', () => {
console.log(`App running on port ${port}`);
});
app.use(express.json());
app.get('/api/v1/tours', (request, response) => {
const data = FS.read(`${__dirname}/dev-data/data/tours-simple.json`).then(
(data) => {
response.status(200).json({
status: 'success',
results: data.length,
data: {
tours: data,
},
});
}
);
});
app.post('/api/v1/tours', (request, response) => {
(async (req, res) => {
const tours = await FS.read(`${__dirname}/dev-data/data/tours-simple.json`);
const newID = tours[tours.length - 1].id + 1;
const newTour = Object.assign({ id: newID }, req.body);
tours.push(newTour);
console.log('File written Started');
await FS.write(
`${__dirname}/dev-data/data/tours-simple.json`,
JSON.stringify(tours)
);
console.log('File written Successfully');
res.status(200).send('Created Succesfully');
})(request, response);
});
File Reader Module:
module.exports = class {
constructor() {
this.tours = [];
}
read(path) {
return new Promise((resolve, reject) => {
if (this.tours.length > 0) {
resolve(this.tours);
}
fs.readFile(path, 'utf-8', (err, data) => {
if (err) reject(er);
this.tours = Object.assign(JSON.parse(data));
resolve(this.tours);
});
});
}
write(path, data) {
return new Promise((resolve, reject) => {
if (data.length <= 0) reject('Data is empty');
fs.writeFile(path, data, (err) => {
if (err) reject('Could not write');
resolve('Done');
});
});
}
};
Explanation of the error I was encountering
My issue with occasionally receiving ECONNRESET when POSTing to my listening endpoint was caused by the endpoint automatically restarting after each successful POST of a file to that same endpoint.

Node.js : How to use token with multer?

I want to run two same servers. And I want to upload a image from one to the other. These sources worked well but I felt that verifying a token is needed for security.
I will use the function createUploadToOther of settings.js to send image to the other server. I usually write a router like
router.post('/fromOther', verifyToken, function (req, res) {
But in this case, I don't know where to put that verifyToken. Could u let me know how to use a token with the multer header(?) in this case?
file.js
let express = require("express");
let router = express.Router();
let path = require('path');
let uploadDir = 'static'
let fs = require('fs');
const verifyToken = require('../libs/verifyToken')
const axios = require('axios')
const FormData = require('form-data')
let multer = require('multer');
let storageForSentFile = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, uploadDir);
},
filename: function (req, file, callback) {
callback(null, file.originalname);
}
})
let uploadForSentFile = multer({ storage: storageForSentFile })
router.post('/fromOther', uploadForSentFile.single('logo'), function (req, res) {
console.log("------file upload -------")
console.log(req.file)
res.json(req.file)
});
router.post('/toOther', uploadForSentFile.single('logo') , async function (req, res) {
let formData = new FormData()
formData.append('logo', fs.createReadStream(req.file.path), { knownLength: req.file.size })
const headers = {
...formData.getHeaders(),
"Content-Length": formData.getLengthSync()
};
try {
let result = await axios.post(
new URL('/file/fromOther', req.body.serverURL).href,
formData,
{headers }
)
res.status(200).json(result.data)
} catch (err) {
console.log('file/toOther err', err)
}
})
../libs/verifyToken.js
let jwt = require("jsonwebtoken");
const dotenv = require("dotenv");
function verifyToken(req, res, next) {
console.log("req.headers1 : ", req.headers);
let token = req.headers["authorization"];
if (!token)
return res.json({ status: 409, message: 'No authorization' })
jwt.verify(token, process.env.aSecretKey, function (err, decoded) {
if (err)
return res
.status(500)
.send({ auth: false, message: "Check your ID and password" });
console.log("decoded", decoded);
req.account = decoded.account;
req.idx = decoded.idx;
next();
});
}
module.exports = verifyToken;
settings.js
import axios from 'axios'
import { headers } from '../config/env'
export function createUploadToOther(data) {
return axios.post('/file/toOther', data, { headers })
}
Function verifyToken in router('/fromOther') checks just req.headers["authorization"], so I just added the function verifyToken to both router as argument(in fact don't need to add verifyToken to router('/toOther') but wanted to make it safer) and added the key "authorization" and the value as req.headers.authorization to router('/toOther'). Then it worked well, but I don't know this will be safe enough.
//(...)
router.post('/fromOther', verifyToken, uploadForSentFile.single('logo'), function (req, res) {
console.log("------file upload -------")
console.log(req.file)
res.json(req.file)
});
router.post('/toOther', verifyToken, uploadForSentFile.single('logo') , async function (req, res) {
let formData = new FormData()
formData.append('logo', fs.createReadStream(req.file.path), { knownLength: req.file.size })
const headers = {
...formData.getHeaders(),
"Content-Length": formData.getLengthSync(),
"authorization": req.headers.authorization
};
try {
let result = await axios.post(
new URL('/file/fromOther', req.body.serverURL).href,
formData,
{headers }
)
res.status(200).json(result.data)
} catch (err) {
console.log('file/toOther err', err)
}
})
//(...)

How to get multiple APIs request into a single page without using promise package

I'm trying to get 2 APIs into one page using Nodejs. I have searched for the same but it says to use promise package but it is deprecated now please help me
app.post("/", function (req, res) {
const username = req.body.username;
const url1 = "https://codeforces.com/api/user.info?handles=" + username;
https.get(url1, function (response) {
response.on("data", function (data) {
const code = JSON.parse(data);
res.render("result", { id: username, rating: code.result[0].rating, rank: code.result[0].rank, freinds: code.result[0].friendOfCount, contri: code.result[0].contribution });
});
})
const url2 = "https://codeforces.com/api/user.status?handle=" + username;
https.get(url2, function (response) {
response.on("data", function (data) {
const code = JSON.parse(data);
res.render("result", { cid: code.result[0].contestId });
})
})
})
Simple way - use callback in callback: When the first request finished, start the second request, when the second request finished, let call render with the response from 1st request and 2nd request.
app.post("/", function (req, res) {
const username = req.body.username;
const url1 = "https://codeforces.com/api/user.info?handles=" + username;
https.get(url1, function (response) {
response.on("data", function (data) {
const code1 = JSON.parse(data);
const url2 = "https://codeforces.com/api/user.status?handle=" + username;
https.get(url2, function (response) {
response.on("data", function (data) {
const code2 = JSON.parse(data);
res.render("result", {
id: username,
rating: code1.result[0].rating,
rank: code1.result[0].rank,
freinds: code1.result[0].friendOfCount,
contri: code1.result[0].contribution,
cid: code2.result[0].contestId
});
});
});
});
});
});

How can I make my Hapi route wait for data before returning a value?

I am using Hapi.js and have a route that I want to use to fetch data and then return a result.
I have tried to use async/await, but I must be doing something wrong because while the function I am calling eventually prints a result to the console, the route is returning without waiting for that function to return a value.
'use strict';
const Hapi = require('#hapi/hapi');
const HandyStorage = require('handy-storage');
var ethBalance ='';
// Connection to public blockchain via Infura.io
const Web3 = require("web3");
const web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/cf44bc52af3743bcad5f0b66813f8740"));
// Initialize Handy Storage
const storage = new HandyStorage({
beautify: true
});
//Get ETH address from Handy Storage
storage.connect('./preferences.json');
var walletAddress = storage.state.wallet;
// Get wallet balance
const getWalletBalance = async () => {
web3.eth.getBalance(`${walletAddress}`, async function(err, result) {
if (err) {
console.log('There was an error: ' + err);
return ({ error: 'The wallet balance call failed.' });
} else {
ethBalance = await web3.utils.fromWei(result, "ether");
console.log("This should be first: The wallet balance via API call is " + ethBalance + " ETH.");
return ethBalance; // I expect the walletbalance route to wait for this to be returned
}
});
};
// API Server
const init = async () => {
// Connection settings
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
// Get wallet balance
server.route({
method: 'GET',
path: '/walletbalance/',
handler: async (request, h) => {
let result = null;
try {
result = await getWalletBalance();
console.log('This should be second, after the getWalletBalance function has printed to the console.'); // this prints first, so await isn't working as expected
return ({ ethBalance: result });
} catch (err) {
console.log('Error in walletbalance route');
}
}
});
// 404 error handling
server.route({
method: '*',
path: '/{any*}',
handler: function (request, h) {
return ({
message: 'Error!'
});
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
Any idea where I have gone wrong here? This is the first time I have used async/await.
ETA: My console looks like this:
[nodemon] starting `node index.js`
Server running on http://localhost:3000
This should be second, after the getWalletBalance function has printed to the console.
This should be first: The wallet balance via API call is 4061.894069996147660079 ETH.
And this is the JSON I get back when I use the wallet balance route:
{}
Based on the answer I was given, I was able to get the results I wanted with this:
'use strict';
const Hapi = require('#hapi/hapi');
const HandyStorage = require('handy-storage');
var ethBalance ='';
// Connection to public blockchain via Infura.io
const Web3 = require("web3");
const web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/cf44bc52af3743bcad5f0b66813f8740"));
// Initialize Handy Storage
const storage = new HandyStorage({
beautify: true
});
//Get ETH address from Handy Storage
storage.connect('./preferences.json');
var walletAddress = storage.state.wallet;
// Get wallet balance
async function getWalletBalance(){
let ethBalance = await web3.eth.getBalance(`${walletAddress}`);
if (ethBalance.err) {
console.log('error in the called function');
} else {
return ethBalance;
}
}
// API Server
const init = async () => {
// Connection settings
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
// Get wallet balance
server.route({
method: 'GET',
path: '/walletbalance/',
handler: async (request, h) => {
try {
const result = await getWalletBalance();
const ethBalanceInWei = web3.utils.fromWei(result, "ether");
return ({ balance: ethBalanceInWei });
} catch (err) {
console.log('Error in walletbalance route');
}
}
});
// 404 error handling
server.route({
method: '*',
path: '/{any*}',
handler: function (request, h) {
return ({
message: 'Error!'
});
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();
Thank you for the help! That got me going in the right direction.
Basically your getWalletBalance function is using multiple concepts. callback style functions and inside that you are using await. I have restructured your code a little bit. Hopefully that should fix the issue which you are facing.
'use strict';
const Hapi = require('#hapi/hapi');
const HandyStorage = require('handy-storage');
var ethBalance ='';
// Connection to public blockchain via Infura.io
const Web3 = require("web3");
const web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/cf44bc52af3743bcad5f0b66813f8740"));
// Initialize Handy Storage
const storage = new HandyStorage({
beautify: true
});
//Get ETH address from Handy Storage
storage.connect('./preferences.json');
var walletAddress = storage.state.wallet;
function getWalletBalance() {
return Promise((resolve, reject) => {
web3.eth.getBalance(`${walletAddress}`, (err, result) => {
if (err) {
console.log('There was an error: ' + err);
reject({ error: 'The wallet balance call failed.' });
} else {
resolve(result);
}
});
});
}
// API Server
const init = async () => {
// Connection settings
const server = Hapi.server({
port: 3000,
host: 'localhost'
});
// Get wallet balance
server.route({
method: 'GET',
path: '/walletbalance/',
handler: async (request, h) => {
try {
const result = await getWalletBalance();
ethBalance = await web3.utils.fromWei(result, "ether");
return ethBalance;
} catch (err) {
console.log('Error in walletbalance route');
}
}
});
// 404 error handling
server.route({
method: '*',
path: '/{any*}',
handler: function (request, h) {
return ({
message: 'Error!'
});
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});
init();

Node.js rsmq - New message doesn't become visible until Node.js application is restarted

I'm trying to make this package work.
redis version: stable 4.0.6
I connect Redis like this, there's no issues there.
pubsub.js
var redis = require("redis");
var psRedis = redis.createClient();
psRedis.auth("mypasswordishere", function (callback) {
console.log("connected");
});
module.exports.psRedis = psRedis;
After starting Node.js application, I can see "connected" on the console and perform operations, I've checked this.
My test.js file is below.
test.js
var express = require('express');
var router = express.Router();
var path = require("path");
var bodyParser = require('body-parser');
var async1 = require("async");
var client = require("../databases/redis/redis.js").client;
var RedisSMQ = require("rsmq");
var psRedis = require("./realtime/operations/pubsub").psRedis;
var rsmq = new RedisSMQ({client: psRedis});
rsmq.createQueue({qname: "myqueue"}, function (err, resp) {
if (resp === 1) {
console.log("queue created");
}
});
rsmq.receiveMessage({qname: "myqueue"}, function (err, resp) {
if (resp) {
console.log(resp);
}
});
router.get('/pubsubTest', function (req, res, next) {
async1.waterfall([
function (callback) {
rsmq.sendMessage({qname: "myqueue", message: "Hello World 1"}, function (err, resp) {
if (resp) {
console.log("Message sent. ID:", resp);
}
});
callback(null, 'done!');
}
], function (err, result) {
res.sendStatus(200);
});
});
module.exports = router;
However, when I visit /pubsubTest, only message id appears on the console.
Message sent. ID: exb289xu0i7IaQPEy1wA4O7xQQ6n0CAp
If I restart my Node.js application, I get to see the result below, which is expected. Why doesn't it appear immediately?
{ id: 'exb289xu0i7IaQPEy1wA4O7xQQ6n0CAp',
message: 'Hello World 1',
rc: 1,
fr: 1515802884138,
sent: 1515802880098 }
Thank you.
receiveMessage will not "fire". You need to call it after you have sent a message.
what you are looking for is realtime option provided by rsmq.
var rsmq = new RedisSMQ({client: psRedis}, ns: "rsmq",realtime :true});
Now on every new message that is being added to a queue via sendMessage, a PUBLISH message will be sent to rsmq:rt:{qname} with the content {msg}. In your case sendMessage will emit an event namely rsmq:rt:myqueue
There can be two solutions for this , both will use the event rsmq:rt:myqueue
1.First one will use a redis client , which can subscribe to this published event with subscribe method provided by redis to implement PUB/SUB.
var redis = require('redis');
const subscribe = redis.createClient();
subscribe.subscribe('rsmq:rt:myqueue');
subscribe.on('message', function(msg) { //msg=>'rsmq:rt:myqueue'
rsmq.receiveMessage({qname: "myqueue"}, function (err, resp) {
if (resp) {
console.log(resp);
}
});
});
The whole code will look something like:
var express = require('express');
var router = express.Router();
var path = require("path");
var bodyParser = require('body-parser');
var async1 = require("async");
var client = require("../databases/redis/redis.js").client;
var psRedis = require("./realtime/operations/pubsub").psRedis;
var rsmq = new RedisSMQ({client: psRedis}, ns: "rsmq",realtime :true});
rsmq.createQueue({qname: "myqueue"}, function (err, resp) {
if (resp === 1) {
console.log("queue created");
}
});
const subscribe = redis.createClient( 6379,"127.0.0.1"); //creating new
worker and pass your credentials
subscribe.subscribe('rsmq:rt:myqueue');
subscribe.on('message', function(msg) { //msg=>'rsmq:rt:myqueue'
rsmq.receiveMessage({qname: "myqueue"}, function (err, resp) {
if (resp) {
console.log(resp);
}
});
});
router.get('/pubsubTest', function (req, res, next) {
async1.waterfall([
function (callback) {
rsmq.sendMessage({qname: "myqueue", message: "Hello World 1"},
function (err,
resp) {
if (resp) {
console.log("Message sent. ID:", resp);
}});
callback(null, 'done!');
}
], function (err, result) {
res.sendStatus(200);
});
});
module.exports = router;
2.Second solution is to use rsmq-worker which will provide you with a message event which you can listen to using .on method.
var RSMQWorker = require( "rsmq-worker" );
var worker = new RSMQWorker( "myqueue" ,{interval:.1}); // this worker
will poll the queue every .1 second.
worker.on( "message", function( message, next, msgid ){
if(message){
console.log(message);
}
next();
});
worker.start();
The whole code will look something like:
var express = require('express');
var router = express.Router();
var path = require("path");
var bodyParser = require('body-parser');
var async1 = require("async");
var client = require("../databases/redis/redis.js").client;
var psRedis = require("./realtime/operations/pubsub").psRedis;
var rsmq = new RedisSMQ({client: psRedis},{ ns: "rsmq",realtime :true});
rsmq.createQueue({qname: "myqueue"}, function (err, resp) {
if (resp === 1) {
console.log("queue created");
}
});
var RSMQWorker = require( "rsmq-worker" );
var worker = new RSMQWorker( "myqueue" ,{interval:.1});
worker.on( "message", function( message, next, msgid ){
if(message){
console.log(message);
}
next();
});
// optional error listeners
worker.on('error', function( err, msg ){
console.log( "ERROR", err, msg.id );
});
worker.on('exceeded', function( msg ){
console.log( "EXCEEDED", msg.id );
});
worker.on('timeout', function( msg ){
console.log( "TIMEOUT", msg.id, msg.rc );
});
worker.start();
router.get('/pubsubTest', function (req, res, next) {
async1.waterfall([
function (callback) {
rsmq.sendMessage({qname: "myqueue", message: "Hello World1"}
,function (err, resp) {
if (resp) {
console.log("Message sent. ID:", resp);
}});
callback(null, 'done!');
}
], function (err, result) {
res.sendStatus(200);
});
});
module.exports = router;
Note: In first solution you will need to delete the message that you received from the queue using deleteMessage or you can also use popMessage which will receive the last message and delete it for you. if you do not delete the message you will get all of the messages again until the timeout is over on that particular message.
For this reason i prefer to use the second solution , rsmq takes care of this stuff for you and also you can provide your own poll interval

Resources