Closed jusfeel closed 1 year ago
Hello @jusfeel !
No, you don't need to login every request. Do you have some kind of "startup" phase? Otherwise you could create a function which returns a memoized promise of the bot.login. This way you can ensure that the login is only done -on demand- but never more than once.
Does this help?
Best, Simon
I don't know how memorized promise work. The problem is when the startup login expires then the bot will not be logged-in when the request comes. It needs to login again. How do I do that? For app without routes, from the server side prospective, the server starts so the bot can be logged-in, but what happens when the bot is not logged in, say, wiki server restarts, or the login session expired.
So if I can check to tell if the user is not logged-in, then I can log user in when the request comes. But I didn't find a way to do that?
Could you explain memorized promise? Sounds the right way to go. Will it handle the situation I described when user is not logged-in any more.
Re-logging in when the login expires is not something mwbot does handle itself, sadly. Memoized Promises won't handle that for you, too. I fear this is more difficult to achive. You basically need to create a new bot instance with a new login first and then always use this for further request. If one request goes wrong you need to evaluate if it is because of an expired login and then renew the bot instance (login again) without changing the reference to it.
It would be nicer, if the mwbot library could do that by itself as you probably don't want to handle this type of error in many places. But I've got not much time for developing this project, so this feature will not be likely in the near future, sorry.
You don't need to go with memoized promises, if you are not familiar with this concept. You could look up the memoization pattern and you could / should also learn about how Promises work. But if you just create just one instance of mwbot on startup and just use that one everywhere (by reference) you won't need a memoization pattern.
I have what I think is a similar issue, but the error I get is Error: badtoken: Invalid CSRF token
. What's interesting is that I'm using getEditToken()
right before it attempts to edit, but that apparently isn't enough. I think the login is timing out, just as you describe.
I'm good enough with promises that I think I can make a solution, which I will post here, but the issue I'm running into is how to detect if the login expired (or if the token is still valid). Do you know of an easy way to do this? Or should I use a try/catch block?
Actually, I see that I can simply use .catch()
on the promise to capture the error. Easy peasy! However it's unclear why I'm getting the CSRF token error. Shouldn't I get something similar to what jusfeel got if the login had expired?
My code right before it edits is something like:
bot.getEditToken().then(() => {
bot.edit(page, content, summary);
});
In other words, I'm using the callback, so the edit token should be refreshed, right? The error only happens after a prolonged period, which is what led me to believe the login had expired.
Sorry if I'm hijacking this thread!
Hello @MusikAnimal !
thanks for joining the discussion!
Currently, the edit token is only fetched if the mwbot doesn't have one already. If the session expires (in my own usecase that never happens, so I haven't thought about that case sadly) the token is still there but invalid from now on.
It should be possible to reset it by setting mwbotInstance.editToken = undefined
or just creating a new instance of mwbot. In that case you need to get the right error and renew the mwbot instance.
The bot is very "simple" regarding the response data or error data. It just returns what the MW API is returning. That may change with different MW versions and is not streamlined by this library.
Does this help? I'm sorry that this is a more complicated issue at the moment, as mwbot was not designed with this use case in mind!
Best, Simon
Currently, the edit token is only fetched if the mwbot doesn't have one already. It should be possible to reset it by setting mwbotInstance.editToken = undefined
Yes! I somehow missed this when looking at the mwbot source code. I will give this a go and report back here if it works. For this I'm checking if the badtoken
error is received. I'm also checking assertbotfailed
(because mine has assert: 'bot'
) and if that's present, it will create a new mwbot instance and login again.
I'm going to make sure this works then try to create a PR. Is it reasonable to have the bot auto-login/auto-refresh tokens? For logins, I can also look for assertuserfailed
.
That sounds good! Thanks for working out a PR.
Currently I don't have the setup to test this properly, but I'm happy to provide feedback along the way!
@Fannon Last you recall, did the tests pass? I'm running into similar issues that are reported here, mainly that re-logging in seems to error out. I setup loginCredentials.json
to point to my local MediaWiki installation (master @ version 1.31). Do you know what version of MediaWiki this was last tested on? Thanks for the info!
with MW 1.27 bot works fine
Yes, the bot in general works for me on production WMF sites which are running 1.31.0-wmf.7.
In my scenario, I am connecting to EventStreams and trying to keep the bot's session alive. However after enough time passes, I get either an invalid CSRF token, or the login session as a whole is lost. I want to tackle this issue and have the bot library recover automatically. For now, when one of these errors happen I'm doing process.exit(1)
, which will force the Kubernetes pod to automatically restart my bot. Very much not ideal!
If I try to re-login every time there's an error (with a new bot instance), I get the same error as jusfeel, Cannot log in when using MediaWiki\\Session\\BotPasswordSessionProvider sessions
. The tests are returning the same error, mixed in with Could not login: NeedToken -- Fetching a token via "action=login" is deprecated
. I don't get the latter error with my bot code, not sure why, but it sounds like maybe the tests were written for a much older version of MediaWiki (before logging in was a two-step process)?
Hi, My issue might be not related to this library.
I have put your code under a route. The first login and read request works fine. But the next request was rejected by the server because the wiki api claims that 'Cannot log in when using MediaWiki\Session\BotPasswordSessionProvider sessions' .
So do I need to login on every request? If I don't, how to I get the "bot". If I do, should I log out on every request, how?
I am using express, in a route, I am calling this function where it returns json to the client containing page content in data.