Inquirer.js: ask multiple questions if one prompt is true - node.js

I'm writing an account creator using Inquirer.js, and wanted to ask for the user's e-mail and password only if the user asked for such protection. It goes like this:
inquirer.prompt([
{type:'input', name:'username', message:'Choose an username:'},
{type:'confirm', name:'protect_ask', message:'Do you want to password-protect your game list?'},
{type:'input', name:'email', message:'E-mail (for password recovering):', when:function(answers){return answers.protect_ask}},
{type:'password', name:'password', message:'Password:', when:function(answers){return answers.protect_ask}},
{type:'password', name:'confirm_password', message:'Confirm you password:', when:function(answers){return answers.protect_ask}}
]
As you can see, I'm running the exact same when statement three times, for it verifies if the password-protection was chosen or not. I want to know if there's a more intelligent, pragmatic way to do so, this is, to run this verification without repeating the when function.
Maybe nesting the three questions would do it, but how to do so without breaking the prompt flow?

Related

How to handle replies in with Pyrogram when using ForceReply?

I am building a telegram bot where I am attempting to get the user to fill in detail about an event and store them in a dictionary which is itself in a list.
However I want it be link a conversation. I want it to look like:
user: /create
bot-reply: What would you like to call it?
user-reply: Chris' birth day
bot-reply: When is it?
user-reply: 08/11/2021
bot-reply: Event Chris birth day on 08/11/2021 has been saved!
To achieve this I plan to use ForceReply which states in the documentation
This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode.
The problem is the documentation does not seem to explain how to handle responses.
Currently my code looks like this:
#app.on_message(filters.command('create'))
async def create_countdown(client, message):
global countdowns
countdown = {
'countdown_id': str(uuid4())[:8],
'countdown_owner_id': message.from_user.id,
'countdown_onwner_username': message.from_user.username,
}
try:
await message.reply('What do you want to name the countdown?',
reply_markup=ForceReply()
)
except FloodWait as e:
await asyncio.sleep(e.x)
Looking through the form I have found options like this:
python telegram bot ForceReply callback
which are exactly what I am looking for but they are using different libraries like python-telegram-bot which permit them to use ConversationHandler. It seems to not be part of pyrogram
How to I create user-friendly step-by-step interfaces with pyrogram?
Pyrogram doesn't have a ConversationHandler.
You could use a dict with your users' ID as the key and the state they're in as the value, then you can use that dictionary of states as your reference to know where your User is in the conversation.
Dan: (Pyrogram creator)
A conversation-like feature is not available yet in the lib. One way to do that is saving states into a dictionary using user IDs as keys. Check the dictionary before taking actions so that you know in which step your users are and update it once they successfully go past one action
https://t.me/pyrogramchat/213488

How can I use PromptDialog.Choice while allowing the user to type the options without worrying about accented letters?

How can I use PromptDialog.Choice while allowing the user to type the options without worrying about accented letters?
Given the following prompt to the user:
List<string> promptValues = new List<string> { "Sim", "Não" };
PromptDialog.Choice<string>(context,
AfterPrompt,
promptValues,
"Digite 'Sim' ou 'Não'",
"Opção inválida, por favor tente novamente.");
How can I allow the user to input "Nao" or "Não" without the prompt considering "Nao" as a wrong answer?
I can't use PromptDialog.Confirm because I need the dialogs to happen in Portuguese, and as far as I know I can't localize PromptDialog.Choice.
Also I want to know how can I ignore accents even with other kinds of prompt, not only Yes or No prompts.
Is there a way to do this?
I believe you might be able to localize the PromptConfirm options if you change the culture of the bot like:
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("de-DE");
because the options are being retrieved from a resource file (see this)
Now, it seems that the Portuguese resource is not implemented yet, which from my point of view it could be something great to contribute if you want to.
On the other hand, if you want to have some custom logic in the PromptChoice, you can always inherit from it and override the TryParse method to add your checks. Here is an example of a custom PromptChoice.

scope of questions in api.ai

Can anyone suggest me , how to allowed scope of questions in api.ai? i.e. I want to ask user "how many book can you carry at a time ?" : user can reply any positive integer number. Then my bot reply: "good , you can still better than others!". now, without any reference if user directly write "any positive integer number" at starting then also bot reply : "good , you can still better than others!" , instead of "I didn't get"(or default response.). This answer come only when previous question has been asked.How can I do this?
==== case : 1 ====
Bot: how many book can you carry at a time ?
User:5
Bot:good , you can still better than others!
=== case : 2 ===
(without any reference if users gives inputs at very starting of conversation)
User: 5
Bot: good , you can still better than others!
Thanks In Advance.
You should make a required parameter instead of putting numbers in User says:
In your intent configure your action to have one required parameter numBooks. Have the prompt for that parameter be "how many book can you carry at a time ?". Then for that intent, have the response be, "good , you can still better than others!". Finally, in the User says section, add anything you want the user to say to trigger the intent, for example: "hi". Save your intent. Now whenever a user says "hi" the bot will ask the question and the conversation will begin. But if the user randomly sends a number, it will respond with fallback intent.

Validating a Devise User password WITHOUT changing it

i am using Devise and devise_security_extension.
https://github.com/plataformatec/devise
https://github.com/phatworx/devise_security_extension
I tried to figure out how i could validate a provided password WITHOUT updating a User record.
Validation (password was not used before, password is complex enough ....)
For example:
john = User.find(1)
john.password = "Testing"
john.password_confirmation = "Testing"
result = john.save
Result would return true or false. With result.errors i would get the related error messages (Thats exactly what i want but without really change this user password).
My Problem is that this would really change the password of this user (object). That would cause problems with old_passwords.
Is there any way to do a dry run ? (result = john.save_dry_run)
FYI:
I already tried to change the User password and change it back after i got the result. But this is really ugly and also make much trouble with devise old_passwords table.
I hope my question is clear enough. If you need any further information please let me know !
You should call valid? rather than save in your example. This will only run the model validations without actually saving any data to the database:
john = User.find(1)
john.password = "Testing"
john.password_confirmation = "Testing"
result = john.valid?
You can find more information in the Rails documentation.

Returning a string from LINQ

For a school project we have to create an evaluation website that requires a login.
For the database connection I chose LINQ, because it's new and is supposed to be easier/better in use.
I managed to create a login check with the following:
public static Boolean Controle(int id, string wachtwoord)
{
DataClassesDataContext context = new DataClassesDataContext();
var loginGebruiker =
from p in dc.Gebruikers
where p.GebruikerID == id
where p.GebruikerWachtwoord == wachtwoord
select p;
return true;
}
Now I'm trying to create a "forgot password" option, where you enter your id and the password gets returned (later it would be emailed to you, don't know how I would do this either, suggestions?)
I tried with the following code:
public static string Forgot(int id)
{
var context = new DataClassesDataContext();
var wachtwoordLogin = (
from p in dc.Gebruikers
where p.GebruikerID == id
select p.GebruikerWachtwoord);
return wachtwoordLogin.ToString();
}
Code behind the button on the page:
lbl1.Text = Class1.Forgot(Convert.ToInt32(txt1.Text));
Now when I enter the an id of the first user (1), lbl1 becomes this:
SELECT [t0].[GebruikerWachtwoord] FROM
[dbo].[Gebruiker] AS [t0] WHERE
[t0].[GebruikerID] = #p0
I don't know how to solve this and I have been looking everywhere, I hope somebody can help me.
Thanks,
Thomas
LINQ uses delayed execution, so your 'wachtwoordLogin' is really just "how to get your data." Its not until you apply an operator that LINQ will actually attempt to retrieve your data.
Your first statement:
var loginGebruiker = (
from p in dc.Gebruikers
where p.GebruikerID == id
where p.GebruikerWachtwoord == wachtwoord
select p).FirstOrDefault()
if (loginGeruiker != null) {
//Valid login
} else {
// invalid
}
FirstOrDefault means, take the first item in the list, or return none.
In you other case you need the same thing:
user = wachtwoordLogin.FirstOrDefault();
Further reading: MSDN 101 LINQ Samples
For your question about emailing a forgotten password, have you ever thought about implementing the golden questions algorithm instead? Its simplified, and does the same thing.
Basically, at the time of registering just get them to answer some questions, and if they can verify them, allow them to reset the password.
you enter your id and the password gets returned
What, then, is the point of having a password if anybody who knows a username can see it? I know this isn't what you're asking, but for someone getting started in programming I feel a duty to point this out. What you're creating here is essentially a completely broken login model. Nobody should ever use a system like this.
You should never ever display a password. Not on the screen, not in an email, never.
Passwords, if they even need to be stored at all (CodingHorror has had a couple of good posts on this lately, advocating things like OpenID), should be stored in hashed form and essentially unable to be retrieved. When a user logs in, similarly hash the password they provide (immediately upon reaching the application code, before transporting it anywhere else in the system) and compare that to the stored hashed version.
If the user asks for his password, you don't have it. You can't give it to him. This is for his protection. Instead of providing the user with his password, if it's forgotten then you provide the user with a means to reset his password (sending an email to the address on file with a temporarily available URL, a set of "security questions" to verify his identity, etc.) so that he can enter a new one to overwrite the old one. But you shouldn't be able to "show" the user his password because even you as the administrator of the system shouldn't be able to see it in any usable form.
wachwoordLogin will be an IQueryable so you can get this by using FirstOrDefault() which will return null if not found:
(from p in dc.Gebruikers
where p.GebruikerID == id
select p.GebruikerWachtwoord).FirstOrDefault();

Resources