[英]Update already posted Adaptive Card in Bot Framework v4 in C#
I'm working on a Bot with the Bot Framework v4 in C#.我正在使用 C# 中的 Bot Framework v4 开发 Bot。 What I want now is, that after sending an Adaptive Card to the user, with Actions, that I can update this card after the Action is fired.
我现在想要的是,在使用 Actions 向用户发送自适应卡片后,我可以在触发 Action 后更新这张卡片。 For example, that the button will disappear after the click.
例如,该按钮将在单击后消失。
Link to NodeJS Solution 链接到 NodeJS 解决方案
here I have a Solution in NodeJS, but I'm not able to transfer it to C#.在这里,我在 NodeJS 中有一个解决方案,但我无法将其转移到 C#。 Can anybody help?
有人可以帮忙吗?
More Project details: I have an Adaptive Card that looks like this:更多项目详细信息:我有一张如下所示的自适应卡:
This Card will be generated, after I searched with the MS Graph from a SharePoint Library.在我使用 SharePoint 库中的 MS Graph 搜索后,将生成这张卡片。
The Main Goal is, that i can use the Refiners to update the Card with a new Card from JSON.主要目标是,我可以使用 Refiners 用 JSON 的新卡更新卡。 The "OK" button is a Submit Action which can be catched in the OnMessageActivityAsync Method.
“确定”按钮是一个提交操作,可以在 OnMessageActivityAsync 方法中捕获。 The Input Values are in the Activity Value so can create a Filter Method.
输入值在活动值中,因此可以创建过滤方法。 my Problem is, that I can't update the Card that is already send to the User.
我的问题是,我无法更新已经发送给用户的卡。
Before I sended the first Card with the Results to the User I write the Activity into a State, so I can Access OnMessageActivityAsync Method, but I'm not sure if this is the right approach.在将第一张带有结果的卡片发送给用户之前,我将 Activity 写入 State,因此我可以访问 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);
}
This Code gives me the following Error Message:此代码给了我以下错误消息:
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'.
Has anybody a good idea to solve this?有没有人解决这个问题的好主意?
Have a look at this answer to get an idea of how to update Adaptive Cards.查看此答案以了解如何更新自适应卡片。
You can either write code to remove the submit action from an Adaptive Card dynamically, or you can have two different versions of your card: one with the submit action and one without.您可以编写代码以动态地从自适应卡片中删除提交操作,或者您可以拥有两种不同版本的卡片:一种带有提交操作,一种没有。
If you want this whole process to be made easier with prebuilt code that you can install in NuGet packages, feel free to voice your support for these ideas on GitHub:如果您希望使用可以安装在 NuGet 包中的预构建代码来简化整个过程,请随时在 GitHub 上表达您对这些想法的支持:
You can update adaptive card in channel like MS Teams not in directline.您可以在 MS Teams 等渠道中更新自适应卡,而不是直接使用。 For updating card you need one Accessor to store ActivityId which is generated while sending current message.
要更新卡片,您需要一个访问器来存储发送当前消息时生成的 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);
After this in next waterfallstep you need to write logic to update this posted message.在此之后的下一个瀑布步骤中,您需要编写逻辑来更新此发布的消息。
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);
Just addition info: For me goal was to disable buttons of adaptive card after click.只是添加信息:对我来说,目标是在点击后禁用自适应卡的按钮。 So second time when I was posting adaptive card, I just removed all actions from buttons.
因此,当我第二次发布自适应卡片时,我只是从按钮中删除了所有操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.