更新已经在C#中的Bot Framework v4中发布的自适应卡

时间:2019-09-25 14:45:40

标签: c# botframework bots

我正在使用C#中的Bot Framework v4开发Bot。我现在想要的是,在使用操作将自适应卡发送给用户之后,可以在触发操作后更新该卡。 例如,单击后该按钮将消失。

Link to NodeJS Solution

这里我在NodeJS中有一个解决方案,但无法将其传输到C#。 有人可以帮忙吗?

更多项目详情: 我有一个自适应卡,看起来像这样: enter image description here

在我从SharePoint库中使用MS Graph搜索之后,将生成此卡片。

主要目标是,我可以使用精炼机通过JSON中的新Card更新Card。 “确定”按钮是一个提交动作,可以在OnMessageActivityAsync方法中捕获该动作。 输入值在活动值中,因此可以创建过滤方法。 我的问题是,我无法更新已经发送给用户的卡。

在我将带有结果的第一张卡片发送给用户之前,我将活动写入状态,这样就可以访问OnMessageActivityAsync方法,但是我不确定这是否是正确的方法。

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
    {
        Logger.LogInformation("Running dialog with Message Activity.");

        var txt = turnContext.Activity.Text;
        dynamic val = turnContext.Activity.Value;
        // Check if the activity came from a submit action
        if (string.IsNullOrEmpty(txt) && val != null)
        {
            await turnContext.SendActivityAsync(MessageFactory.Text($"Refiner Language: {val.id_language}"));
            await turnContext.SendActivityAsync(MessageFactory.Text($"Refiner MachType: {val.id_type}"));

            var r = new StreamReader("Cards/helloCard2.json");
            string json = r.ReadToEnd();
            AdaptiveCard card = AdaptiveCard.FromJson(json).Card;

            var docSearchState = await StateAccessor.GetAsync(turnContext);
            Activity activity = docSearchState.Activity;
            activity.Attachments = new List<Attachment>() {
                new Attachment()
                {
                    Name = "Card",
                    ContentType = AdaptiveCard.ContentType,
                    Content = card,
                }
            };

            await turnContext.UpdateActivityAsync(activity);
        }

此代码给我以下错误消息:

fail: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
  Exception caught : Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path 'DocumentSearchState.Activity.attachments.$values[0].content.body'.

有人有解决这个问题的好主意吗?

2 个答案:

答案 0 :(得分:1)

看看this answer,了解如何更新自适应卡。

您可以编写代码以动态地从Adaptive Card中删除提交动作,也可以具有两种不同版本的卡:一个带有提交动作,另一个不带有提交动作。

如果您希望通过可安装在NuGet软件包中的预构建代码简化整个过程,请在GitHub上表达对这些想法的支持:

答案 1 :(得分:0)

您可以在MS Teams之类的渠道中更新自适应卡,而不是在直线上。 要更新卡,您需要一个访问器来存储在发送当前消息时生成的ActivityId。

var response = await stepContext.Context.SendActivityAsync(reply);
//Customize object to store ID
UserProfile user = new UserProfile(response.Id);
//Accessor to store card values to update it and disable buttons after click
await CardStateAccessor.SetAsync(stepContext.Context, user, cancellationToken);

在接下来的瀑布步骤中,您需要编写逻辑以更新此已发布的消息。

UserProfile UserDataState = await CardStateAccessor.GetAsync(stepContext.Context, () => new UserProfile());
//Retrive accessor property
//Here I am updating adaptive card
var reply = stepContext.Context.Activity.CreateReply();
                string text = File.ReadAllText("./AdaptiveCards/UpdatedYesNo.json");
                var cardObj = JsonConvert.DeserializeObject(text);
                reply.Attachments = new List<Attachment>()
                {
                    new Attachment(){ContentType="application/vnd.microsoft.card.adaptive",Content=cardObj}
                };
                //Here you need to assign ID from accessor so that earlier posted msg gets updated
                reply.Id = UserDataState.ActivityId;
                //Use here UpdateActivityAsync to post updated message
                await stepContext.Context.UpdateActivityAsync(reply, cancellationToken);

只需添加信息: 对我来说,目标是单击后禁用自适应卡的按钮。 所以第二次发布自适应卡时,我只是删除了按钮上的所有操作。