Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Microsoft Bot Framework WebChat:禁用上一条消息的AdaptiveCards提交按钮_C#_Button_Botframework_Adaptive Cards_Web Chat - Fatal编程技术网

C# Microsoft Bot Framework WebChat:禁用上一条消息的AdaptiveCards提交按钮

C# Microsoft Bot Framework WebChat:禁用上一条消息的AdaptiveCards提交按钮,c#,button,botframework,adaptive-cards,web-chat,C#,Button,Botframework,Adaptive Cards,Web Chat,如何在Microsoft Bot Framework(C#)中的BotChat-AdaptiveCards的上一次对话中禁用输入/提交按钮操作我想象您希望向用户显示一张仅使用一次的卡片,如中所示的日历提醒 机器人的主要功能是拥有与人类相同的通道访问权限,因此它们无法返回并修改已发送的消息(除非特定通道允许像Slack那样进行编辑)。虽然您不能禁用卡中已经是对话历史记录一部分的按钮,但您可以更改bot响应该卡生成的消息的方式。您要做的是跟踪按钮是否已被单击,然后在后续时间单击按钮时做出不同的响应

如何在Microsoft Bot Framework(C#)中的BotChat-AdaptiveCards的上一次对话中禁用输入/提交按钮操作

我想象您希望向用户显示一张仅使用一次的卡片,如中所示的日历提醒

机器人的主要功能是拥有与人类相同的通道访问权限,因此它们无法返回并修改已发送的消息(除非特定通道允许像Slack那样进行编辑)。虽然您不能禁用卡中已经是对话历史记录一部分的按钮,但您可以更改bot响应该卡生成的消息的方式。您要做的是跟踪按钮是否已被单击,然后在后续时间单击按钮时做出不同的响应

下面是一些对话框代码的基本示例,可以用三种方式响应消息。如果您键入任何消息并将其发送到bot,它将显示一张带有按钮的卡。如果您单击按钮,它将显示“您做到了!”以及您单击的按钮ID。如果您再次单击同一按钮,它将再次显示“您已经这样做了!”并附加ID

/// <summary>
/// You'll want a label like this to identify the activity
/// that gets generated in response to your submit button.
/// </summary>
private const string DO_SOMETHING = "DoSomething";

/// <summary>
/// This is passed into context.Wait() in your StartAsync method.
/// </summary>
private async Task MessageReceivedAsync(IDialogContext context,
    IAwaitable<IMessageActivity> result)
{
    var msg = await result;

    if (!string.IsNullOrWhiteSpace(msg.Text))
    {
        // If msg.Text isn't null or white space then that means the user
        // actually typed something, and we're responding to that with a card.
        var reply = context.MakeMessage();
        var attachment = MakeAdaptiveCardAttachment();
        reply.Attachments.Add(attachment);

        await context.PostAsync(reply);
    }
    else
    {
        // If the user didn't type anything then this could be an activity
        // that was generated by your submit button. But we want to make sure
        // it is by checking msg.Value.
        dynamic value = msg.Value;

        try
        {
            // If value doesn't have a type then this will throw a RuntimeBinderException
            if (value != null && value.type == DO_SOMETHING)
            {
                string id = value.id;

                // Check the ID to see if that particular card has been clicked before.
                if (!context.PrivateConversationData.ContainsKey(id))
                {
                    // This is how your bot will keep track of what's been clicked.
                    context.PrivateConversationData.SetValue(id, true);

                    await context.PostAsync("You did it! " + id);
                }
                else
                {
                    await context.PostAsync("You already did that! " + id);
                }
            }
        }
        catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
        {
            // Respond to messages that don't have values with a type (or id).
        }
    }

    context.Wait(MessageReceivedAsync);
}

private static Attachment MakeAdaptiveCardAttachment()
{
    var card = new AdaptiveCard();
    // We need to identify this specific card if we want to allow multiple
    // instances of the card to be clicked.
    // A timestamp could work but a GUID will do.
    var cardId = Guid.NewGuid().ToString();

    card.Body.Add(new TextBlock() { Text = cardId });

    card.Actions.Add(new SubmitAction()
    {
        Title = "Do something",
        // The data we put inside this action will persist.
        // I've found setting DataJson to be more reliable than using the Data property.
        // Note that if your WebApiConfig.cs has a CamelCasePropertyNamesContractResolver
        // (which is a default) and you use capitalized (Pascal case) identifiers,
        // they may be converted to camel case and you won't be able to retrieve
        // the data with the same identifiers.
        DataJson = JsonConvert.SerializeObject(new
        {
            // We need a type to differentiate this action from other actions.
            type = DO_SOMETHING,
            // We need an id to differentiate this card from other cards.
            id = cardId,
        }),
    });

    return new Attachment()
    {
        ContentType = AdaptiveCard.ContentType,
        Content = card,
    };
}
//
///您需要这样的标签来标识活动
///它是响应提交按钮生成的。
/// 
private const string DO_SOMETHING=“DoSomething”;
/// 
///这将传递到StartAsync方法中的context.Wait()中。
/// 
专用异步任务消息ReceivedAsync(IDialogContext上下文,
(可等待的结果)
{
var msg=等待结果;
如果(!string.IsNullOrWhiteSpace(msg.Text))
{
//如果msg.Text不是null或空白,则表示用户
//实际上,我们输入了一些东西,我们用一张卡片来回应。
var reply=context.MakeMessage();
var attachment=MakeAdaptiveCardAttachment();
答复.附件.增加(附件);
等待上下文。PostAsync(回复);
}
其他的
{
//如果用户没有键入任何内容,则这可能是一个活动
//这是由“提交”按钮生成的。但我们要确保
//这是通过检查msg.Value实现的。
动态值=消息值;
尝试
{
//如果值没有类型,则将抛出RuntimeBinderException
if(value!=null&&value.type==DO\u SOMETHING)
{
字符串id=value.id;
//检查ID以查看之前是否单击过该特定卡。
如果(!context.PrivateConversationData.ContainsKey(id))
{
//这就是你的机器人如何跟踪点击的内容。
context.PrivateConversationData.SetValue(id,true);
wait context.PostAsync(“你做到了!”+id);
}
其他的
{
wait context.PostAsync(“你已经做了!”+id);
}
}
}
捕获(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
{
//响应没有类型(或id)值的消息。
}
}
Wait(MessageReceivedAsync);
}
私有静态附件MakeAdaptiveCardAttachment()
{
var卡=新的自适应卡();
//如果我们想允许多张卡,我们需要识别这张特定的卡
//要单击的卡的实例。
//时间戳可以工作,但GUID可以。
var cardId=Guid.NewGuid().ToString();
Add(newtextblock(){Text=cardd});
card.Actions.Add(新提交()
{
Title=“做点什么”,
//我们在该操作中输入的数据将保持不变。
//我发现设置DataJson比使用Data属性更可靠。
//请注意,如果您的WebApiConfig.cs具有CamelCasePropertyNamesContractResolver
//(这是默认值)并使用大写(Pascal大小写)标识符,
//它们可能会转换为camel大小写,您将无法检索
//具有相同标识符的数据。
DataJson=JsonConvert.SerializeObject(新
{
//我们需要一个类型来区分此操作与其他操作。
类型=做某事,
//我们需要一个id来区分这张卡和其他卡。
id=卡迪德,
}),
});
返回新附件()
{
ContentType=AdaptiveCard.ContentType,
内容=卡片,
};
}
下面是它在Bot框架模拟器中的外观。请注意,即使您单击了一张卡并且无法从该卡获得第一个响应,您仍然可以从另一张卡获得第一个响应


欢迎来到SO。请参观一下。请参见如何提问。你需要提到的是,到目前为止你已经尝试了什么。你面临的问题是什么?我可以问一下你说的聊天是什么意思吗?这是WebChat机器人的简写吗?BotChat-AdaptiveCards是指一个特定的机器人还是教程?另外,我想确定你什么时候想要禁用提交按钮操作。Bot框架有对话、对话框等。您想仅从以前的对话或任何以前的“消息”或什么禁用提交按钮操作吗?如果您正在使用该频道,可能有一种方法:您可以自行完成项目并实现该功能。我仍然在工作,我会发布它作为答复时,它的工作。