How to make sequence of commands for questionnaire in Telegram bot? - javascript

For a questionary, I have over 80 questions in the following code I tied to do that but was not working. I will be appreciated for any help:
I am using telegraf SDK for bot:
Question e.g :
1)Q1: Seldom I am feeling good. (1 point)
Q2: I am feeling good always. (2 points)
app.action('Start', (ctx) => {
//console.log(getdata('http://localhost:3000/api/questions'));
getdata(myCallback);
});
var myCallback = function (data) {
let i = Object.keys(data).length;
let x = 0;
for (x = 0;x!=i; x++ ){
app.action(ctx => {
ctx.editMessageText('Choose your own proper sentence:', Extra.HTML().markup(m => m.inlineKeyboard([
m.callbackButton(data[x].Q1, 'plus1'),
m.callbackButton(data[x].Q2, 'plus2')
])))
});
}
};
app.action('pluse1',(ctx)=>{
console.log(1);
//do somethings
});
app.action('pluse2', (ctx) => {
console.log(2);
//do other things
});
var getdata = function (callback) {
http.get('http://localhost:3000/api/questions', (res) => {
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
callback(parsedData);
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
}
function callback(data){
console.log('cb',data)
this.qa = data;
}

Related

My weather app is throwing type error of temp.. It was console logging the data when I checked but as I enter city Lat and Log it shows type error [duplicate]

I'm trying to get my function to return the http get request, however, whatever I do it seems to get lost in the ?scope?. I'm quit new to Node.js so any help would be appreciated
function getData(){
var http = require('http');
var str = '';
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
//return str;
}
var req = http.request(options, callback).end();
// These just return undefined and empty
console.log(req.data);
console.log(str);
}
Of course your logs return undefined : you log before the request is done. The problem isn't scope but asynchronicity.
http.request is asynchronous, that's why it takes a callback as parameter. Do what you have to do in the callback (the one you pass to response.end):
callback = function(response) {
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(req.data);
console.log(str);
// your code here if you want to use the results !
});
}
var req = http.request(options, callback).end();
Simple Working Example of Http request using node.
const http = require('https')
httprequest().then((data) => {
const response = {
statusCode: 200,
body: JSON.stringify(data),
};
return response;
});
function httprequest() {
return new Promise((resolve, reject) => {
const options = {
host: 'jsonplaceholder.typicode.com',
path: '/todos',
port: 443,
method: 'GET'
};
const req = http.request(options, (res) => {
if (res.statusCode < 200 || res.statusCode >= 300) {
return reject(new Error('statusCode=' + res.statusCode));
}
var body = [];
res.on('data', function(chunk) {
body.push(chunk);
});
res.on('end', function() {
try {
body = JSON.parse(Buffer.concat(body).toString());
} catch(e) {
reject(e);
}
resolve(body);
});
});
req.on('error', (e) => {
reject(e.message);
});
// send the request
req.end();
});
}
Shorter example using http.get:
require('http').get('http://httpbin.org/ip', (res) => {
res.setEncoding('utf8');
res.on('data', function (body) {
console.log(body);
});
});
from learnyounode:
var http = require('http')
http.get(options, function (response) {
response.setEncoding('utf8')
response.on('data', console.log)
response.on('error', console.error)
})
'options' is the host/path variable
from learnyounode:
var http = require('http')
var bl = require('bl')
http.get(process.argv[2], function (response) {
response.pipe(bl(function (err, data) {
if (err)
return console.error(err)
data = data.toString()
console.log(data)
}))
})
I think it's too late to answer this question but I faced the same problem recently my use case was to call the paginated JSON API and get all the data from each pagination and append it to a single array.
const https = require('https');
const apiUrl = "https://example.com/api/movies/search/?Title=";
let finaldata = [];
let someCallBack = function(data){
finaldata.push(...data);
console.log(finaldata);
};
const getData = function (substr, pageNo=1, someCallBack) {
let actualUrl = apiUrl + `${substr}&page=${pageNo}`;
let mydata = []
https.get(actualUrl, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', async () => {
if (JSON.parse(data).total_pages!==null){
pageNo+=1;
somCallBack(JSON.parse(data).data);
await getData(substr, pageNo, someCallBack);
}
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}
getData("spiderman", pageNo=1, someCallBack);
Like #ackuser mentioned we can use other module but In my use case I had to use the node https. Hoping this will help others.
This is my solution, although for sure you can use a lot of modules that give you the object as a promise or similar. Anyway, you were missing another callback
function getData(callbackData){
var http = require('http');
var str = '';
var options = {
host: 'www.random.org',
path: '/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new'
};
callback = function(response) {
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
callbackData(str);
});
//return str;
}
var req = http.request(options, callback).end();
// These just return undefined and empty
console.log(req.data);
console.log(str);
}
somewhere else
getData(function(data){
// YOUR CODE HERE!!!
})

how to handle proxy error in core-https in node js

so am using core-https to do a Get request to a webstie , iam doing this get reqeust using a proxy by using this code :
const { HttpsProxyAgent } = require("https-proxy-agent");
const proxy = new HttpsProxyAgent(`http://user:pass#host:port`);
https.get("https://www.google.com/",
{ agent: proxy },
(res) => {
var body = "";
res.on("data", function (chunk) {
body += chunk;
// console.log(body)
});
res.on("end", function () {
}
);
})
so sometimes the proxy would be invalid or expired , or even use a local-host for debugging using fiddler or Charles
const { HttpsProxyAgent } = require("https-proxy-agent");
const proxy = new HttpsProxyAgent(`http://127.0.0.1:8888`); // For Debugging
https.get("https://www.google.com/",
{ agent: proxy },
(res) => {
var body = "";
res.on("data", function (chunk) {
body += chunk;
// console.log(body)
});
res.on("end", function () {
}
);
})
and would also result an error if i forgot to open a proxy-debugger .
i tried doing it in this way :
res.on("error" , function(e){
console.log("an error have been occurred ")
})
but nothing seems to work
So i found the answer , it would be done like this
https.get(
"https://www.google.com/",
{ agent: proxy },
(res) => {
var body = "";
res.on("data", function (chunk) {
body += chunk;
});
res.on("end", function () {
// console.log(body)
})
.on('error', function (e) {
console.error("error");
}).end();

JavaScript https get request

a get request to the address https://api.steampowered.com/ISteamApps/GetAppList/v2/?format=json is sent too long with this code:
https.get("https://api.steampowered.com/ISteamApps/GetAppList/v2/?format=json", (res) =>
{
res.setEncoding("utf8");
let bodyCount = "";
res.on("data", (dataCount) => {
bodyCount += dataCount;
});
res.on("end", () => {
bodyCount = JSON.parse(bodyCount);
console.log(bodyCount);
});
});
The process takes up to several seconds, so how to make it happen faster?
In case anyone is wondering how I solved the problem:
setInterval(() =>{
https.get("https://api.steampowered.com/ISteamApps/GetAppList/v2/?format=json", (res) => {
res.setEncoding("utf8");
let body ="";
res.on("data", (dataCount) => {
body += dataCount;
});
res.on("end", () =>{
fs.writeFile('./steamdatabase.txt', body, (err) => {
if (err) {
console.error(err)
return
}
});
});
});
}, 86400000);
...
fs.readFile('./steamdatabase.txt', (err, data) => {
if (err) {
console.error(err)
return
}
let body = JSON.parse(data);
for(let i = 0;i<body.applist.apps.length;i++){
if(body.applist.apps[i].name == generateParameter(args)) appidGame = body.applist.apps[i].appid;
}
if(appidGame) appInfo(appidGame,mess);
});

Node js pause while loop wait until functions inside get executed completely?

I am coding a post request which downloads all URL HTML,zips them and email it back. This all should happen in the backend. I am storing all the data in an array and extract the first element to start these operations.
I have while loop inside which I am calling some functions. Each function gets executed at a certain time.
I used async, await and promises to make sure they run one after the
other.
Coming to my problem.
My while loop starts getting executed again before all the
functions inside it are executed.
app.post('/?', async (req, res) => {
var urls = req.query.urls
var email = req.query.email;
var new_stack = [urls, email]
stack.push(new_stack)
res.send("Mail sent")
if (isFunctionRunning === false) { //initially it is false
console.log(isFunctionRunning, stack.length)
send_mails();
}
});
const getGoogleIndexHTML = (url) => {
return new Promise((resolve, reject) => {
request(url, (err, res, body) => err ? reject(err) : resolve(body))
})
}
const some_function_to_download = async (url) => {
try {
const a = url.split(".")
let googleIndexHTML = await getGoogleIndexHTML(url)
await fs.writeFile(directory + '/' + a[1] + '.html', googleIndexHTML, (err) => {
if (err) throw err
})
console.log('File created.')
} catch (err) {
console.log(err)
}
}
const html_to_zip_file = async () => {
await zipper.zip(directory, function (error, zipped) {
if (!error) {
zipped.compress();
zipped.save('./package.zip', function (error) {
if (!error) {
console.log("Saved successfully !");
}
});
} else {
console.log(error)
}
})
}
const send_mails = async () => {
while (stack.length > 0) {
isFunctionRunning = true
var a = stack.shift()
var urls = a[0]
var collection_urls = urls.split(",");
var to_email = a[1]
rimraf(directory, function () {
console.log("done");
});
fs.mkdirSync(directory);
for (url of collection_urls) {
await some_function_to_download(url); // 5 sec per download
}
await html_to_zip_file() // takes 5 sec to zip
.then(result => {
transporter.sendMail(set_mail_options(to_email)) //2 sec to send mail
.then(result => {
console.log("Mail sent")
})
.catch(err => {
console.log(err)
})
})
.catch(err => {
console.log(err)
})
console.log("reached") // this is reached before zip is done and mail sent. I want to prevent this
}
isFunctionRunning = false
}
You need to return transporter.sendMail in sendMail, fs.writeFile in someFunctionToDownload and zipper.zip in htmlToZipFile otherwise the await won't work as expected (I'm assuming that they actually do return promises, I'm only familiar with fs.writeFile)
Also: CamelCase is used in JS, not snake_case 🙃
And are you sure rimraf is synchronous?
const sendMails = async () => {
while (stack.length > 0) {
isFunctionRunning = true;
const [urls, toEmail] = stack.shift();
var collectionUrls = urls.split(",");
rimraf(directory, function() {
console.log("done");
});
await fs.mkdir(directory);
await Promise.All(collectionUrls.map(someFunctionToDownload)); // 5 sec per download
await htmlToZipFile() // takes 5 sec to zip
.then(result => transporter.sendMail(set_mail_options(toEmail))) //2 sec to send mail
.then(result => {
console.log("Mail sent");
})
.catch(err => {
console.log(err);
});
console.log("reached"); // this is reached before zip is done and mail sent. I want to prevent this
}
isFunctionRunning = false;
};
const someFunctionToDownload = async url => {
const a = url.split(".");
const googleIndexHTML = await getGoogleIndexHTML(url);
return fs.writeFile(`${directory}/${a[1]}.html`, googleIndexHTML, err => {
if (err) throw err;
});
};
const htmlToZipFile = async () => {
return zipper.zip(directory, function(error, zipped) {
if (!error) {
zipped.compress();
zipped.save("./package.zip", function(error) {
if (!error) {
console.log("Saved successfully!");
}
});
} else {
console.log(error);
}
});
};
Try using the following
while (stack.length > 0) {
isFunctionRunning = true
var a = stack.shift()
var urls = a[0]
var collection_urls = urls.split(",");
var to_email = a[1]
rimraf(directory, function () {
console.log("done");
});
fs.mkdirSync(directory);
for (url of collection_urls) {
await some_function_to_download(url); // 5 sec per download
}
try {
const result = await html_to_zip_file() // takes 5 sec to zip
const sendMailResult = await transporter.sendMail(set_mail_options(to_email))
} catch(e)
{
console.log(e)
}
console.log("reached")
}
Since html_to_zip_file() and sendMail function are independent
we can use
const result = await Promise.all([html_to_zip_file(),transporter.sendMail(set_mail_options(to_email))]);

Async with http Node.js

I have 2 asynchronous functions on gives me some urls and other one gives me the content I need from the url and one that writes the content I need to an file, but it write to file first and then it gives me the content I need to write, how can I get him to write to file after I get the content I need. Thanks
var http = require('http');
var fs = require('fs');
var list = {};
var k = 0;
function getContent(url){
var options = {
host: 'www.exammple.org',
path: url
}
var request = http.request(options, function (res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
list[k] = data;
k++;
});
});
request.on('error', function (e) {
console.log(e.message);
});
request.end();
}
var options = {
host: 'www.example2.org',
path: '/mypath'
}
var request = http.request(options, function (res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
///Here I get some urls from data
data = data.split(";");
for(key in data){
data = data.split('href=\"')[1].split('"')[0];
getContent(data[key]);
}
writeToFile();
}
});
});
request.on('error', function (e) {
console.log(e.message);
});
function writeToFile(){
fs.writeFile("file.txt", JSON.stringify(list), function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved");
}
});
}
request.end();

Categories