SDK Platform: .NET
SDK Version: 3.11.0.0
Active Channels: Skype, Telegram
Hi!
I have a global message handler in the bot, which intercepts "reset" messages and resets the current dialog:
public class ResetStackDialog : ScorableBase<IActivity, string, double>
{
//...
protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
{
Activity activity = item as Activity;
var client = new ConnectorClient(new System.Uri(activity.ServiceUrl), new MicrosoftAppCredentials());
var reply = activity.CreateReply();
reply.Text = "Operation canceled";
await client.Conversations.ReplyToActivityAsync(reply);
this.task.Reset();
}
//...
}
I want to intercept the "help" messages and call a special method in the current dialog object that would return a hint for working with a specific dialog.
Example:
public class HelpInfoDialog : ScorableBase<IActivity, string, double>
{
//...
protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
{
Activity activity = item as Activity;
var currentDialog = this.GetCurrentDialogObject(); // ???
if(currentDialog is IUsersGuide)
{
var client = new ConnectorClient(new System.Uri(activity.ServiceUrl), new MicrosoftAppCredentials());
var reply = activity.CreateReply();
reply.Text = (currentDialog as IUsersGuide).UsersGuide();
await client.Conversations.ReplyToActivityAsync(reply);
}
}
//...
}
But to do this, I need to get the object of the current dialog. How to do it?
Hello @verdysh. You can check the stack of dialogs by checking the Frames in the IDialogTask object.
In order to have access to the "IDialogTask" object in your scorable, you need to pass it as a parameter when registering your scorable in the dependency injection container.
Example:
Cancel Scorable:
[Serializable]
class CancelScorable : ScorableBase<IActivity, string, double>
{
private readonly IDialogTask task; //this is the object you need
public CancelScorable(IDialogTask task)
{
SetField.NotNull(out this.task, nameof(task), task);
}
//your scorable logic
}
Registering your scorable:
builder.Register(c => new CancelScorable(c.Resolve<IDialogTask>()))
.As<IScorable<IActivity, double>>()
.InstancePerLifetimeScope();
To check the dialog the user is currently at, you can do it the following way:
var dialog = task.Frames.First().Target;
I'm using this strategy to check if the dialog I am currently at has an Attribute, and based on that apply some logic on my scorables.
If you're interested on doing that you could try this:
protected override async Task<string> PrepareAsync(IActivity item, CancellationToken token)
{
var dialog = task.Frames.First().Target;
var attribute = dialog.GetType().GetCustomAttribute<SpellCheckAttribute>(inherit: true);
if (attribute != null)
{
//if attribute exists
}
}
Hope this helps!
@xjose97x, thanks for the detailed answer! It looks like it's what I need.
There (task.Frames.First().Method) I can get and the current method of dialogue. Excellent!! :)
Great Job @xjose97x!!
Most helpful comment
@xjose97x, thanks for the detailed answer! It looks like it's what I need.
There (task.Frames.First().Method) I can get and the current method of dialogue. Excellent!! :)