ExpectedConstraintError: Invalid string format discord.js - node.js

I am trying to make a slashcommandbuilder for my coinflip command but something is going on. Btw I am new to discord.js. This is the error I get.
return regex.test(input) ? Result.ok(input) : Result.err(new ExpectedConstraintError(type, "Invalid string format", input, expected));
^
ExpectedConstraintError: Invalid string format
at Object.run (C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#sapphire\shapeshift\dist\index.js:1564:64)
at C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#sapphire\shapeshift\dist\index.js:142:66
at Array.reduce (<anonymous>)
at StringValidator.parse (C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#sapphire\shapeshift\dist\index.js:142:29)
at validateName (C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#discordjs\builders\dist\index.js:782:17)
at SlashCommandUserOption.setName (C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#discordjs\builders\dist\index.js:856:5)
at C:\Users\dhart\Desktop\Projects\ExistentialThreat\commands\coinflip.js:8:37
at MixedClass._sharedAddOptionMethod (C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#discordjs\builders\dist\index.js:1256:50)
at MixedClass.addUserOption (C:\Users\dhart\Desktop\Projects\ExistentialThreat\node_modules\#discordjs\builders\dist\index.js:1230:17)
at Object.<anonymous> (C:\Users\dhart\Desktop\Projects\ExistentialThreat\commands\coinflip.js:8:4) {
constraint: 's.string.regex',
given: 'my guess',
expected: 'expected /^[\\p{Ll}\\p{Lm}\\p{Lo}\\p{N}\\p{sc=Devanagari}\\p{sc=Thai}_-]+$/u.test(expected) to be true'
My code looks like this.
const { EmbedBuilder } = require("discord.js");
const { SlashCommandBuilder } = require('#discordjs/builders');
module.exports = {
data: new SlashCommandBuilder()
.setName('coinflip')
.setDescription('Returns value heads or tails.')
.addUserOption((option) => option.setName('my guess').setDescription('Enter heads or tails.').setRequired(false)),
//.addChoices({ name: 'Heads', value: 'guess heads'}, { name: 'Tails', value: 'guess tails'}, { name: 'Other', value: 'You are making a mistake. The chance of this is low.'}),
async execute(interaction) {
let coinflip = (Math.random() * 100).toFixed(0) % 2;
let embedThumbnail = `https://m.media-amazon.com/images/I/51bcZy+HZpL._AC_.jpg`;
console.log(coinflip);
let result = 'tails';
if (coinflip == 1){
result = 'heads';
embedThumbnail = `https://i.ebayimg.com/images/g/xtcAAOSwLwBaZigS/s-l400.jpg`;
}
let guess = interaction.options.getString('my guess');
let guessedmessage = 'You guessed it correct!'
if (!result == guess){
guessedmessage = 'You guessed it wrong, but good try.';
};
I would appreciate some help in fixing this issue.

The 'my guess' option is a user option, not a string option. Change it to:
.addStringOption((option) => option.setName('my guess').setDescription('Enter heads or tails.').setRequired(false)),

Related

How to check for existing interaction in discord.js?

I began working on my discord bot few days ago, and while creating my rps (rock, paper, scissors) command I encountered a minor problem, when I run the command twice without finishing the game my bot crushes. Here's my code:
module.exports = {
name: 'rps',
cooldown: 0,
aliases: [],
permissions: [],
description: 'Rock Paper Scissors.',
async execute(message, args, client, Discord) {
let hand = [{ txt: 'Rock', emoji: '✊', index: 0 }, { txt: 'Paper', emoji: '🤚', index: 1 }, { txt: 'Scissors', emoji: '✌️', index: 2 }]; // Defining Moves
let botMove = hand[Math.floor(Math.random() * 3)]; // Making a random move
let rpsMsg = await message.channel.send({ // Prompting user to make a move
embeds: [
new Discord.MessageEmbed() // RPS embed
.setColor('RANDOM')
.setTitle('Rock Paper Scissors')
.setDescription('Choose a handsign')
],
components: [
new Discord.MessageActionRow() // Rock, paper, scissors buttons
.addComponents(
new Discord.MessageButton()
.setCustomId(`rps_rock`)
.setLabel("✊ Rock")
.setStyle('PRIMARY'),
new Discord.MessageButton()
.setCustomId(`rps_paper`)
.setLabel("🤚 Paper")
.setStyle('PRIMARY'),
new Discord.MessageButton()
.setCustomId(`rps_scissors`)
.setLabel("✌️ Scissors")
.setStyle('PRIMARY')
)
]
});
let win = 0; // 0 = Loss; 1 = Tie; 2 = Win
let userMove;
// If you already / want to handle this in your interactionCreate.js, ignore this part.
let f = async (interaction) => {
if (!interaction.isButton()) return; // Checking if the interaction is a button
if (interaction.customId.startsWith('rps')) {
await interaction.deferUpdate() // Deffering the interaction
let move = interaction.customId.split('_')[1]
userMove = hand.find(v => v.txt.toLowerCase() == move)
switch (move) { // Calculating if player wins, losses, or a tie
case 'rock':
win = botMove.index == 0 ? 1 : (botMove.index == 1 ? 0 : 2); break;
case 'paper':
win = botMove.index == 0 ? 2 : (botMove.index == 1 ? 1 : 0); break;
case 'scissors':
win = botMove.index == 0 ? 0 : (botMove.index == 1 ? 2 : 1); break;
}
let embed = rpsMsg.embeds[0];
// Editing the embed
embed.description = `I chose ${botMove.txt}! ${win == 0 ? 'You lost!' : (win == 1 ? 'We tied!' : 'You win!')} (${userMove.emoji} ${win == 0 ? '<' : (win == 1 ? '=' : '>')} ${botMove.emoji})`;
let components = rpsMsg.components
// Disabling all buttons
components[0].components.forEach(comp => {
if (comp.customId == interaction.customId) { comp.disabled = true; comp.style = 'SECONDARY' }
else comp.disabled = true
})
// Editing the message
interaction.message.edit({ embeds: [embed], components: components })
// Removing this event.
client.off('interactionCreate', f)
}
}
client.on('interactionCreate', f) // Creates the event
}
}
Does anyone know how to check for an existing interaction or to delete it so my bot wont crush?
BTW, that's the terminal's output:
throw new DiscordAPIError(data, res.status, request);
^
DiscordAPIError: Interaction has already been acknowledged.
at RequestHandler.execute (C:\Users\bar_m\Desktop\DiscordBot\node_modules\discord.js\src\rest\RequestHandler.js:350:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RequestHandler.push (C:\Users\bar_m\Desktop\DiscordBot\node_modules\discord.js\src\rest\RequestHandler.js:51:14)
at async ButtonInteraction.deferUpdate (C:\Users\bar_m\Desktop\DiscordBot\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:185:5)
at async Client.f (C:\Users\bar_m\Desktop\DiscordBot\commands\rps.js:45:17) {
method: 'post',
path: '/interactions/996846575148081182/aW50ZXJhY3Rpb246OTk2ODQ2NTc1MTQ4MDgxMTgyOm1lOUhSNzhYY2JVcm8yYzk3S056UmJHdG5SNTZOQ0ZDQVlTVXMyZnNralVlc2l0bGNPYm8zUFNJaWFEY0hHTXpTT043TUZkUHc2ckNJRDJ5ZnVEY2o0RFZvVTQ4QUw1UURQODYybndFSzBRTE5pb0ROQ0VyNHdmdmt3MXdSU3U5/callback',
code: 40060,
httpStatus: 400,
requestData: { json: { type: 6 }, files: [] }
} ```
client.on('interactionCreate', f) is not what you need here. This results in any interaction the client receives being routed only to your function f, which can cause problems receiving interactions with your client.
Probably the best thing to use here is message.createMessageComponentCollector(...), check this (discord.js docs) for more information.
You can add the following code instead of client.on('interactionCreate', f):
const filter = (interaction) => interaction.customId.startsWith("rps"); // Only handle interactions whose id start with "rps"
const collector = rpsMsg.createMessageComponentCollector({ filter }); // Create a messageComponentCollector on the rps message
collector.on("collect", (interaction) => f(interaction)); // Execute the `f` function when a button is clicked
Using a component collector, you won't need to run client.off('interactionCreate', f), so you can remove that from your code as well.

Is there a way to check if a message contains a Unicode emoji

So im trying to make a poll command it works but there is just one problem it does not support normal emojis just custom emojis this is my code
const Discord = require("discord.js")
const { Permissions , MessageEmbed } = require("discord.js")
let wrong = "#F04A47"
module.exports = {
name: "poll",
usage: "poll <message>",
description: "poll idk",
category: "other",
run: async (client, message, args) => {
try {
if(!message.member.permissions.has(Permissions.FLAGS.KICK_MEMBERS)) {
let embed = new MessageEmbed()
.setDescription("**You do not have permissions to send polls/kick members**")
.setColor(wrong)
return message.channel.send({embeds:[embed]})
}
if(!args[0]) return message.channel.send("please type the first option example => $poll <pizza> <sushi> <🍕> <🍣>")
if(!args[1]) return message.channel.send("please type the second option example => $poll <pizza> <sushi> <🍕> <🍣>")
if(!args[2]) return message.channel.send("please type the first emoji example => $poll <pizza> <sushi> <🍕> <🍣>")
if(!args[3]) return message.channel.send("please type the second emoji example => $poll <pizza> <sushi> <🍕> <🍣>")
const hasEmoteRegex = /<a?:.+:\d+>/gm
const emoteRegex = /<:.+:(\d+)>/gm
const animatedEmoteRegex = /<a:.+:(\d+)>/gm
const normalemoji = /<::>/gm
if(args[3] && args[2].match(/<:\w+:[0-9]+>/)) {
const reportlog = new MessageEmbed()
.setTitle('Poll Time 🥳')
.setColor('RANDOM')
.setDescription(`${args[0]}${args[2]} or ${args[1]}${args[3]}`)
.setFooter(`Poll by ${message.author.tag}`)
.setTimestamp()
message.channel.send({embeds: [reportlog]}).then(sentMessage => {
sentMessage.react(args[2])
sentMessage.react(args[3])
})
}
else{
message.channel.send("you can only use custom emojis for now ")
}
message.delete()
} catch(e) {
message.channel.send(`an error occcured ${e}`)
}
}
}
When i try to use a normal emoji it just return you can only use custom emojis blah blah blah how can i filter custom animated and normal emojis and i made this im not really good with matching and Unicode emojis
If you would like to only match moving emojis:
const animated = /<a:.+:(\d+)>/gm
if(message.match(animated)) {
// do something...
}
Matching non-moving custom emojis
const animated = /<a:.+:(\d+)>/gm
const normal = /<::>/gm
if(message.match(normal) && !message.match(animated)) {
// do something...
}

Unable to run includes() method on string returned by fs.readFileSync()

having a bit of trouble:
let data = fs.readFileSync(pathToCsv, "utf8");
the value of data comes out to be:
clan,mem1,mem2,mem3,mem4,language,managerID,serverJoinedDate
pm,
pm
(through console.log())
but still data.toString().includes("pm") is false.
Here is my full code:
const filter = (m) => m.author.bot === false;
await ogMessage.author.dmChannel
.awaitMessages(filter, {
max: 1,
time: 60000,
})
.then((collected) => {
if (clans[parseInt(collected.toJSON()[0].content) - 1]) {
let clan = clans[parseInt(collected.toJSON()[0].content) - 1];
let data = fs.readFileSync(pathToCsv, "utf8");
console.log(typeof clan);
// let reg = new RegExp(clan, "g");
// let count = (data.match(reg) || []).length;
if (data.split(",").includes(clan)) {
ogMessage.author.send(
"People from this clan are already registered!\nPlease contact the hosts for help!"
);
return;
} else {
teamCheck = true;
}
} else {
ogMessage.author.send("Invalid Clan! Please try again!");
return;
}
})
.catch((collected) => {
try {
console.log("Error" + collected);
} catch (e) {
console.log(e);
}
});
if (teamCheck === false) {
return;
}
I have tried splitting the data, using regular expressions but nothing seems to work on the string returned by
readFileSync()
PS. I am making a discord bot.
In the source string you have pm with a space before it. That's why after calling split("," you end up with the element " pm" in the result array and "pm" is not equal to it.
You just need to trim spaces in all elements before searching some string in it
The problem was in the clans array.
I was defining it as such:
var clans = fs.readFileSync(pathToData, "utf8").split("\n");
but the problem was that the readFileSync() method added an "\r" after every string of the array. That is why it was not able to match the clan string to the data
So what worked was var clans = fs.readFileSync(pathToData, "utf8").split("\r\n");
Now, the array includes only the string, and the includes() method can find a match!

How do I get these properties to not be undefined when they're in an embed

const Discord = require('discord.js')
const prefix1 = '*add'
const prefix2 = '*what'
const prefix3 = '*remove'
const prefix4 = '*search'
const bot4 = new Discord.Client();
let a = []
let fakea = []
bot4.on('message', msg => {
if(msg.member.hasPermission('ADMINISTRATOR')){
if(msg.content.startsWith(prefix1)){
let splited = msg.content.split(' ')
let unchanged = msg.content.split(' ')
splited.splice('*info', 1)
splited.splice(msg.content[1], 1)
splited.splice(msg.content[2], 1)
let c = splited.join(' ')
b = {
namer: unchanged[1],
imformation: unchanged[2],
description: c
}
if(fakea.includes(unchanged[1])){
msg.channel.send('It already exists')
} else {
a.push(b)
fakea.push(unchanged[1])
}
console.log(a)
}
if(msg.content.startsWith(prefix3)){
let armay = msg.content.split(' ')
console.log(a)
console.log(fakea)
if(armay.length != 2){
msg.channel.send(`You have either less or more than two words. That either means you wrote *add on it's own or you had more than one word that you put with the command`)
} else {
if(!fakea.includes(armay[1])){
msg.channel.send(`That doesn't exist. You can't delete something that doesn't exist.`)
} else {
let fakeafind = fakea.find(plot => plot === armay[1])
let afind = a.find(plote => plote.namer === armay[1])
fakea.splice(fakeafind, 1)
a.splice(afind, 1)
}
console.log(a)
console.log(fakea)
}
}
if(msg.content.startsWith(prefix2)){
let coolon = fakea.join('\n')
let don = `_________\n[\n${coolon}\n]\n_________`
const notbot3embed = new Discord.MessageEmbed()
.setTitle('Everything you can search')
.setColor('15DD7C')
.addField('The things you can search', don)
msg.channel.send(notbot3embed)
}
if(msg.content.startsWith(prefix4)){
let mayi = msg.content.split(' ')
if(mayi.length != 2){
msg.channel.send(`You have either less or more than two words. That either means you wrote *search on it's own or you had more than one word that you put with the command`)
} else {
if(fakea.includes(mayi[1])){
let ft = a.filter(thing => thing.namer === mayi[1])
console.log(ft)
let secot = ft.namer
let thirt = ft.imformation
let fort = ft.description
const someembed = new Discord.MessageEmbed()
.setTitle(secot)
.setColor('FF4200')
.addField(thirt, fort)
msg.channel.send(someembed)
} else {
msg.channel.send('This is not a searchable term. Use *what to see the terms that are there.')
}
}
}
}
})
bot4.login(process.env.token4)
I wrote all of it because you would be confused about the properties if I didn't. In the last part I try to get the properties of the object with the name after '*search'. Then I want to put it an embed. Here's the problem I get. On the embed all three of the things say undefined. How do I fix this
If you're confused what I'm trying to do here's what I'm trying to do. I'm trying to make a system that you can put search things(I don't know how to frase it), remove them, check which ones exist and search something. Most of it is working. But in the search part it says for all of them in the embed undefined.
I found out that you need to use find instead of filter. Find works.

Bot framework (v4) Prompt choice in carousel using HeroCards not going to next step

I’m trying to use HeroCards along with a prompt choice in a carousel. So the options to be selected by the user are displayed as HeroCards. As soon as the user clicks in the button of a card it should goes to the next waterfall function.
Here is a working example in bot framework v3. It does work as expected.
const cards = (data || []).map(i => {
return new builder.HeroCard(session)
.title(`${i.productName} ${i.brandName}`)
.subtitle(‘product details’)
.text(‘Choose a product’)
.images([builder.CardImage.create(session, i.image)])
.buttons([builder.CardAction.postBack(session, `${i.id.toString()}`, ‘buy’)]);
});
const msg = new builder.Message(session);
msg.attachmentLayout(builder.AttachmentLayout.carousel);
msg.attachments(cards);
builder.Prompts.choice(session, msg, data.map(i => `${i.id.toString()}`), {
retryPrompt: msg,
});
Below I’m trying to do the same with bot framework v4 but it does not work. It never goes to the next function in my waterfall.
How can I do the same with v4?
…
this.addDialog(new ChoicePrompt(PRODUCTS_CAROUSEL));
…
const productOptions: Partial<Activity> = MessageFactory.carousel(
item.map((p: Product) =>
CardFactory.heroCard(
p.productName,
‘product details’,
[p.image || ''],
[
{
type: ActionTypes.PostBack,
title: ‘buy’,
value: p.id,
},
],
),
),
‘Choose a product’,
);
return await step.prompt(PRODUCTS_CAROUSEL, productOptions);
…
UPDATE:
Follow full code with the suggestion from #Drew Marsh
export class ProductSelectionDialog extends ComponentDialog {
private selectedProducts: Product[] = [];
private productResult: Product[][];
private stateAccessor: StatePropertyAccessor<State>;
static get Name() {
return PRODUCT_SELECTION_DIALOG;
}
constructor(stateAccessor: StatePropertyAccessor<State>) {
super(PRODUCT_SELECTION_DIALOG);
if (!stateAccessor) {
throw Error('Missing parameter. stateAccessor is required');
}
this.stateAccessor = stateAccessor;
const choicePrompt = new ChoicePrompt(PRODUCTS_CAROUSEL);
choicePrompt.style = ListStyle.none;
this.addDialog(
new WaterfallDialog<State>(REVIEW_PRODUCT_OPTIONS_LOOP, [
this.init.bind(this),
this.selectionStep.bind(this),
this.loopStep.bind(this),
]),
);
this.addDialog(choicePrompt);
}
private init = async (step: WaterfallStepContext<State>) => {
const state = await this.stateAccessor.get(step.context);
if (!this.productResult) this.productResult = state.search.productResult;
return await step.next();
};
private selectionStep = async (step: WaterfallStepContext<State>) => {
const item = this.productResult.shift();
const productOptions: Partial<Activity> = MessageFactory.carousel(
item.map((p: Product) =>
CardFactory.heroCard(
p.productName,
'some text',
[p.image || ''],
[
{
type: ActionTypes.ImBack,
title: 'buy',
value: p.id,
},
],
),
),
'Choose a product',
);
return await step.prompt(PRODUCTS_CAROUSEL, {
prompt: productOptions,
choices: item.map((p: Product) => p.id),
});
};
private loopStep = async (step: WaterfallStepContext<State>) => {
console.log('step.result: ', step.result);
};
}
PARENT DIALOG BELOW:
...
this.addDialog(new ProductSelectionDialog(stateAccessor));
...
if (search.hasIncompletedProducts) await step.beginDialog(ProductSelectionDialog.Name);
...
return await step.next();
...
MY BOT DIALOG STRUCTURE
onTurn()
>>> await this.dialogContext.beginDialog(MainSearchDialog.Name) (LUIS)
>>>>>> await step.beginDialog(QuoteDialog.Name)
>>>>>>>>> await step.beginDialog(ProductSelectionDialog.Name)
UPDATE
Replacing the ChoicePrompt with TextPromt (as suggested by Kyle Delaney) seems to have the same result (do not go to the next step) but I realised that if remove return from the prompt like this:
return await step.prompt(PRODUCTS_CAROUSEL, `What is your name, human?`); TO await step.prompt(PRODUCTS_CAROUSEL, `What is your name, human?`);
it does work but when I'm returning the original code with ChoicePrompt without return like this:
await step.prompt(PRODUCTS_CAROUSEL, {
prompt: productOptions,
choices: item.map((p: Product) => p.id),
});
I'm getting another error in the framework:
error: TypeError: Cannot read property 'length' of undefined
at values.sort (/xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/choices/findValues.js:84:48)
at Array.sort (native)
at Object.findValues (/xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/choices/findValues.js:84:25)
at Object.findChoices (/xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/choices/findChoices.js:58:25)
at Object.recognizeChoices (/xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/choices/recognizeChoices.js:75:33)
at ChoicePrompt.<anonymous> (/xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/prompts/choicePrompt.js:62:39)
at Generator.next (<anonymous>)
at /xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/prompts/choicePrompt.js:7:71
at new Promise (<anonymous>)
at __awaiter (/xxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/prompts/choicePrompt.js:3:12)
this is the line:
// Sort values in descending order by length so that the longest value is searched over first.
const list = values.sort((a, b) => b.value.length - a.value.length);
I can see the data from my state is coming properly
prompt: <-- the data is ok
choices: <-- the data is ok too
Sometimes I'm getting this error too:
error: TypeError: Cannot read property 'status' of undefined
at ProductSelectionDialog.<anonymous> (/xxxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/componentDialog.js:92:28)
at Generator.next (<anonymous>)
at fulfilled (/xxxx/Workspace/temp/13.basic-bot/node_modules/botbuilder-dialogs/lib/componentDialog.js:4:58)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
this line
// Check for end of inner dialog
if (turnResult.status !== dialog_1.DialogTurnStatus.waiting) {
You're using a ChoicePrompt, but when you call prompt you're only passing through an activity (the carousel). ChoicePrompt is going to try to validate the input against a set of choices that you should be passing in when you call prompt. Because you're not doing this, the prompt is not recognizing the post back value as valid and technically should be reprompting you with the carousel again to make a valid choice.
The fix here should be to call prompt with PromptOptions instead of just a raw Activity and set the choices of the PromptOptions to an array that contains all the values you expect back (e.g. the same value you set for the value of the post back button).
This should end up looking a little something like this:
Since you're providing the choices UX with your cards, you want to set the ListStyle on the ChoicePrompt to none
const productsPrompt = new ChoicePrompt(PRODUCTS_CAROUSEL);
productsPrompt.style = ListStyle.none;
this.addDialog(productsPrompt);
Then, set the available choices for the specific prompt:
return await step.prompt(PRODUCTS_CAROUSEL, {
prompt: productOptions,
choices: items.map((p: Product) => p.id),
});
Basically Drew Marsh was right.
I just would like to add some other details that I had to tweak to make it work. In case someone else is going crazy like I was. It could give some insights. It's all about how you handle the returns of nested dialogs.
First change. I had to transform the identifier of the Choice prompt into string:
{
type: ActionTypes.PostBack,
title: 'buy',
value: p.id.toString(),
},
and
return await step.prompt(PRODUCTS_CAROUSEL, {
prompt: productOptions,
choices: item.map((p: Product) => p.id.toString()),
});
Another problem that I found was in the parent dialog:
I was basically trying to do this:
if (search.hasIncompletedProducts) await step.beginDialog(ProductSelectionDialog.Name);
return await step.next();
Which makes no sense, then I changed it to:
if (search.hasIncompletedProducts) {
return await step.beginDialog(ProductSelectionDialog.Name);
} else {
return await step.next();
}
And then the final change in the parent of the parent dialog:
Before was like this:
switch (step.result) {
case ESearchOptions.OPT1:
await step.beginDialog(OPT1Dialog.Name);
break;
default:
break;
}
await step.endDialog();
Which again does not make sense since I should return the beginDialog or endDialog. It was changed to:
switch (step.result) {
case ESearchOptions.OPT1:
return await step.beginDialog(OPT1Dialog.Name);
default:
break;
}

Resources