Context
I am using telegraf.js for more than 3 bots which run very well in plenty of groups.
Currently one of the bots needs to request for Display Picture of the user who does not have a display picture.
It works very well as expected but unfortunately the bot throws an error and the server goes down
Current Code
// Request for display picture
const requestDP = async (ctx, next) => {
const { from, chat } = ctx.message;
const { can_delete_messages:canDelete } = await deletePermision(ctx);
let totalDPs = 1;
totalDPs = await ctx.telegram.getUserProfilePhotos(ctx.message.from.id)
.then((result) => result.total_count)
.catch((err) => {
console.log(err);
});
if (totalDPs != 0) return next();
if ((chat.id === -1001341734527 || chat.id === -1001083711103 ) && canDelete) {
await ctx.deleteMessage().then((response) => response, ({ response }) => response.ok);
await ctx.replyWithMarkdown(`[${from.first_name||''} ${from.last_name||''}](tg://user?id=${from.id}), പ്രൊഫൈൽ ഫോട്ടോ ഇല്ലാത്തവർക്ക് ഗ്രൂപിൽ മെസേജ് അയക്കാൻ സാധ്യമല്ല`)
.then(({ message_id }) => setTimeout(() => ctx.deleteMessage(message_id), 5 * 60 * 1000))
.catch((err) => console.log("Error in prevencontacts: " + err));
}
}
module.exports = requestDP;
Failure Information (for bugs)
let totalDPs = 1;
totalDPs = await ctx.telegram.getUserProfilePhotos(ctx.message.from.id)
.then((result) => result.total_count)
.catch((err) => {
console.log(err);
});
The functions seem to be working well. But unfortunately sometimes they get an error the and server goes down.
Error message 👇
Error: 400: Bad Request: request for new profile photos has already been sent
It is really hard to refresh the server occasionally :-(
Is there any solution to manage this error ?
Related
I've got some checkuser middleware that stores the user entry when a JWT is verified. However, when I include it in my routes and try to console.log(res.locals.user.username) I get the username logged twice. When I'm trying to store this username in some JSON, its creating a seperate JSON with {username: ___} that is causing issues in Mongoose. Help would be appreciated, thanks.
const checkUser = async (req, res, next) => {
const token = req.cookies.jwt
if (token) {
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, async (err, decodedToken) => {
if (err) {
res.locals.user = null
console.log(err.message)
next()
}
else {
const user = await User.findById(decodedToken.id)
res.locals.user = user
next()
}
})
}
else {
res.locals.user = null
next()
}
}
app.post('*', checkUser) //all routes
app.post('/newuser', requireAuth, async (req, res) => {
let user = res.locals.user
console.log(res.locals.user.username)
let user_req_body = req.body
let starter_workout = {}
starter_workout.username = user.username
user_req_body.username = user.username
if (user_req_body.FitnessMode == 'cardio') {
starter_workout.workout = cardio
starter_workout.workout_name = 'Default Cardio'
}
else if (user_req_body.FitnessMode == 'hypertrophy') {
starter_workout.workout = hypertrophy
starter_workout.workout_name = 'Default Hypertrophy'
}
else if (user_req_body.FitnessMode == 'powerlifting') {
starter_workout.workout = powerlifting
starter_workout.workout_name = 'Default Powerlifting'
}
else if (user_req_body.FitnessMode == 'calisthenics') {
starter_workout.workout = calisthenics
starter_workout.workout_name = 'Default Calisthenics'
}
const user_info = new userInfo(user_req_body)
const workout_info = new routines(starter_workout)
/*
await user_info.save()
.then(resp => console.log(resp))
.catch(err => console.log(err))
await workout_info.save()
.then(resp => console.log(resp))
.catch(err => console.log(err))
This code will send duplicated data to MongoDB. Also worth noting that this happens only with app.use(express.json()). I guess thats where I would need help with some work-around. Thank you.
If console.log(res.locals.user.username) inside of this:
app.post('/newuser', ...)
is outputting twice, then that's because your server is getting two posts requests to /newuser. A common reason for that is if this comes from a <form> in your web page that you are also sending an ajax call from javascript in the page. If you don't properly use e.preventDefault() to prevent the default post that the browser does automatically, then you will get duplicate post requests. To look into that more, we'd have to see how the /newuser request comes from the web page.
I am trying to fetch 20 random users data from 'https://randomuser.me/api' and in some cases, I get the 503 Service Unavailable error.
I tried to resolve the problem with this kind of code.
async function fetchDriver() {
const driver = await fetch(driverUrl)
.then((response) => {
if (response.status === 200) {
return response.json();
}
if (response.status === 503) {
return fetchDriver();
}
})
.then((data) => console.log(data))
.catch((error) => {
console.log(error);
fetchDriver();
});
return driver;
}
do {
const geoPosition = fetchGeoPosition();
const phoneNumber = fetchPhoneNumber();
const licenseNumber = fetchLicense(3);
const speed = fetchSpeed(60, 200);
const driver = fetchDriver();
const first = driver.name.first;
const last = driver.name.last;
fetchedCars.push({
licenseNumber,
first,
last,
phoneNumber,
geoPosition,
speed,
favorite: false,
more: false,
});
} while (fetchedCars.length < 20);
But console.log(data) in some cases still shows the value of undefined and I just don't know what to do with this.
random user API has a rate limiter. use this to fetch multiple users in one request (for example 20 users):
https://randomuser.me/api/?results=20
check the documentation here
This GitHub thread mentions the rate-limiting and the solution I've included
I joined the site a few days ago.
I'm new here.
I have a problem that I can not solve. I built a function in Nodejs, every time I run the function I want to get information from the server.
On the client side I have this function, which I run, and then save the data, here no problem.
export const getRealtimeConversations = (user) => (dispatch) => {
axios.post('/realtimeConversations', user)
.then((res) => {
dispatch({
type: userConstants.GET_REALTIME_MESSAGES,
payload: res.data
});
})
.catch((err) => console.log(err))
}
I have a series of axios, when I use this line, I run a server-side function.
app.post('/realtimeConversations', FBAuth, getRealtimeConversations);
This is the function on the server side, I have a collection, which I want to access according to details I send from the client. After I have done the calculations I want, I want to return the end result.
exports.getRealtimeConversations = (req, res) => {
db.collection('conversations')
.where('user_uid_1', 'in', [req.body.uid_1, req.body.uid_2])
.orderBy('createdAt', 'asc')
.onSnapshot((querySnapshot) => {
const conversations = [];
querySnapshot.forEach(doc => {
if (
(doc.data().user_uid_1 == req.body.uid_1 && doc.data().user_uid_2 == req.body.uid_2)
||
(doc.data().user_uid_1 == req.body.uid_2 && doc.data().user_uid_2 == req.body.uid_1)
) {
conversations.push(doc.data())
}
});
console.log(conversations);
return res.json(conversations);
})
}
I do not know why but I get that I have a 404 error, I am completely new to it, I think I have a logical error in the server side function, but I'm not sure what I'm doing wrong.
I'm learning React (with hooks) and I encountered a weird issue. Im currently working on Notes Application (from FullStackOpen learn react). My database only accepts notes which content length is greater than 4 characters. In case of invalid note my server catches a ValidationError and returns an error message with status code 401 instead of new note. My goal is to catch this error in frontend and display an error message.
Backend code:
try{
const savedNote = await note.save()
user.notes = user.notes.concat(savedNote._id)
await user.save()
response.json(savedNote.toJSON())
} catch(e) {
//console.log(e.name)
const msg = {error: 'too short!!!'}
//console.log(msg)
return response.status(401).json(msg)
}
Problem appears when I try to receive data at the front side of application. My development console displays Error: Request failed with status code 401 no matter what I do. I can't find a way to enter catch block at front.
Frontend code for communication with server:
const create = async newObject => {
const config = { headers: { Authorization: token } }
const response = await axios.post(baseUrl, newObject, config)
console.log(response.data)
return response.data
}
(...)
const addNote = (event) => {
event.preventDefault()
try{
const noteObject = {
content: newNote,
date: new Date().toISOString(),
important: Math.random() > 0.5
}
noteService
.create(noteObject)
.then(returnedNote => {
setNotes(notes.concat(returnedNote))
setNewNote('')
setErrorMsg('')
setUserNotes(userNotes.concat(returnedNote))
})
} catch (e) {///<----how to get there
setErrorMsg('note too short! minimum 5 characters')
setNewNote('')
setTimeout(() => {
setErrorMsg(null)
}, 5000)
}
}
Some advices would be appreciated.
Solution:
Chaining promises - .catch()
const addNote = (event) => {
event.preventDefault()
const noteObject = {
content: newNote,
date: new Date().toISOString(),
important: Math.random() > 0.5
}
noteService
.create(noteObject)
.then(returnedNote => {
setNotes(notes.concat(returnedNote))
setNewNote('')
setErrorMsg('')
setUserNotes(userNotes.concat(returnedNote))
})
.catch(e => {
setErrorMsg('note too short! minimum 5 characters')
setNewNote('')
setTimeout(() => {
setErrorMsg(null)
}, 5000)
})
}
Put the try, catch block around your api call:
try {
const response = await axios.post(baseUrl, newObject, config)
} catch (e) {
// handle error
}
On another note, I don't recommend using 401 as the invalid status code as that has a reserved meaning of Unauthorized. Use 400 (Bad request) instead. The definitions of status codes: https://httpstatuses.com/
I've got a trouble when trying to implement backend firebase Authorization.
After I had read carefully the docs (https://firebase.google.com/docs/auth/web/phone-auth), I figured out that Authorization need to be proceded by two steps:
send phone
send code
I divided Google's example on two promises, but can't understand how to store current user and whether or not I've done everything in an appropriate way.
app.post("/appSignInByPhone", (req, res) => {
let {phoneNumber, applicationVerifier} = req.body;
firebase.auth().signInWithPhoneNumber(phoneNumber, applicationVerifier)
.then(() => res.end("Waiting for code"))
.catch(
error => res.json(error)
);
});
app.post("/appSignInPhoneVerify", (req, res) => {
let {verificationCode} = req.body;
firebase.auth.ConfirmationResult.confirm(verificationCode)
.then( user => res.json(user))
.catch(
error => res.json(error)
);
});
Maybe there are some ways of merging these to request to one...
Try the following:
In step #1 either store or send back the confirmationResult you get from the fulfillment handler:
firebase.auth().signInWithPhoneNumber(phoneNumber, applicationVerifier)
.then((confirmationResult) => {
// either store confirmationResult
// or send it to the client and ask for it in step #2)
}).catch(
error => res.json(error)
);
then in step #2:
// get the confirmationResult from the client or from some storage
// in the server
// for example let { verificationCode, confirmationResult } = req.body;
confirmationResult.confirm(verificationCode)
.then( user => res.json(user))
.catch(
error => res.json(error)
);