【问题标题】:How to fix a Bad Request while trying to display chat history with the BotFramework?如何在尝试使用 BotFramework 显示聊天记录时修复错误请求?
【发布时间】:2020-02-08 22:41:40
【问题描述】:

我正在尝试显示用户与我的机器人的聊天历史记录,以便当他们回来时可以看到他们之前的对话。当我尝试“SendConversationHistory(conversationId, transcripts)”功能时,我不断收到 Bad Request (400) 并且聊天机器人中不显示历史记录。有人知道如何解决这个问题吗?

我在 C# 中使用 BotFramework SDK v.3。

我所做的是: 1. 检查是否存储了任何对话 ID,以便能够使用该对话 ID 重新连接 2.我向机器人发送一个事件来恢复历史 3. 我能够获取以前的活动并创建成绩单

设置我的成绩单后,我尝试了这个不起作用的 SendConversationHistory 函数。

即使使用旧对话 ID 失败,我也可以与机器人聊天。我还尝试让机器人做一个回复活动,这很有效。

我关注了a js sample (v4)this stackoverflow questionthis thread about history in github,但这些都没有帮助解决这个问题。

MessageController.cs(在 HandleSystemMessage 中)

else if (message.Name.Equals("restoreHistory"))
{
    string convId = message.Conversation.Id;
    List<Activity> activities = JsonConvert.DeserializeObject<List<Activity>>((string)message.Value);
    var incrementId = 0;

    if (message.Id.Contains("|"))
        int.TryParse(message.Id.Split('|')[1], out incrementId);

    foreach(var a in activities)
    {
        incrementId++;
        a.Id = string.Concat(convId, "|", incrementId.ToString().PadLeft(7, '0'));
        a.ChannelData = string.Empty;
    }

    if (activities != null && activities.Count > 0)
    {
        var connector = new ConnectorClient(new System.Uri(message.ServiceUrl));
        var transcripts = new Transcript(activities);
        connector.Conversations.SendConversationHistory(convId, transcripts);
    }
}

default.htm

var botConnection = new BotChat.DirectLine({
    secret: ...,
    conversationId: getPersistedConversationId(),
    token: params['t'],
    domain: params['domain'],
    webSocket: params['webSocket'] && params['webSocket'] === "true"
});
BotChat.App({
    botConnection: botConnection,
    user: { id: ... },
    bot: { id: ... },
    speechOptions: speechOptions
}, document.getElementById("BotChatGoesHere"));

botConnection.connectionStatus$
    .subscribe(function (connectionStatus) {
        switch (connectionStatus) {
            case 2:
                if (botConnection.conversationId === localStorage.getItem('conversationId')) {
                    botConnection.postActivity({
                        from: user,
                        type: 'event',
                        name: 'restoreHistory',
                        text: '',
                        value: localStorage.getItem('conversations')
                    }).subscribe(function (activityId) {
                        console.log('sending chat history.');
                    });
                } else {
                    saveConversationId(botConnection.conversationId);
                }
        }
    });

function saveConversationId(conversationId) {
    localStorage.setItem('conversationId', conversationId);
}
function getPersistedConversationId() {
    return localStorage.getItem('conversationId');
}

我得到的错误是那些:

Exception thrown: 'Microsoft.Rest.TransientFaultHandling.HttpRequestWithStatusException' in Microsoft.Rest.ClientRuntime.dll
Response status code indicates server error: 400 (BadRequest).

活动的 Json

[  
    {  
        "type":"message",
        "id":"6Tklwkie30H7oCI1eyWx9i-h|0000001",
        "timestamp":"2019-06-19T10:37:40.1175096Z",
        "channelId":"directline",
        "from":{  
            "id":"MyBotName",
            "name":"MyBotName"
        },
        "conversation":{  
            "id":"6Tklwkie30H7oCI1eyWx9i-h"
        },
        "text":"Hello, I'm MyBotName. How can I help you? To get started ask me a question.",
        "attachments":[  

        ],
        "entities":[  

        ],
        "replyToId":"7E6AtBm9iXL"
    },
    {  
        "type":"message",
        "id":"6Tklwkie30H7oCI1eyWx9i-h|0000003",
        "timestamp":"2019-06-19T10:37:43.4034223Z",
        "localTimestamp":"2019-06-19T10:37:43.2484146+00:00",
        "channelId":"directline",
        "from":{  
            "id":"MyBotName",
            "name":"MyBotName"
        },
        "conversation":{  
            "id":"6Tklwkie30H7oCI1eyWx9i-h"
        },
        "attachmentLayout":"carousel",
        "locale":"en-US",
        "text":"",
        "attachments":[  
            {  
                "contentType":"application/vnd.microsoft.card.hero",
                "content":{  
                    "title":"Title1",
                    "subtitle":"",
                    "text":"",
                    "images":[  
                        {  
                            "url":"http://..."
                        }
                    ],
                    "buttons":[  
                        {  
                            "type":"openUrl",
                            "title":"Button1",
                            "value":"https://..."
                        },
                        {  
                            "type":"openUrl",
                            "title":"Button2",
                            "value":"https://..."
                        }
                    ]
                }
            },
            {  
                "contentType":"application/vnd.microsoft.card.hero",
                "content":{  
                    "title":"Title2",
                    "subtitle":"",
                    "text":"",
                    "images":[  
                        {  
                            "url":"http://..."
                        }
                    ],
                    "buttons":[  
                        {  
                            "type":"openUrl",
                            "title":"Button1",
                            "value":"https://..."
                        },
                        {  
                            "type":"openUrl",
                            "title":"Button2",
                            "value":"https://..."
                        }
                    ]
                }
            },
            {  
                "contentType":"application/vnd.microsoft.card.hero",
                "content":{  
                    "title":"Title3",
                    "subtitle":"",
                    "text":"",
                    "images":[  
                        {  
                            "url":"http://..."
                        }
                    ],
                    "buttons":[  
                        {  
                            "type":"openUrl",
                            "title":"Button1",
                            "value":"https://..."
                        },
                        {  
                            "type":"openUrl",
                            "title":"Button2",
                            "value":"https://..."
                        }
                    ]
                }
            }
        ],
        "entities":[  

        ],
        "replyToId":"6Tklwkie30H7oCI1eyWx9i-h|0000000"
    },
    {  
        "type":"message",
        "id":"6Tklwkie30H7oCI1eyWx9i-h|0000000",
        "timestamp":"2019-06-19T10:37:33.8526334Z",
        "serviceUrl":"https://directline.botframework.com/",
        "channelId":"directline",
        "from":{  
            "id":"anonymous",
            "name":"Anonymous"
        },
        "conversation":{  
            "id":"6Tklwkie30H7oCI1eyWx9i-h"
        },
        "recipient":{  
            "id":"MyBotName@WI6mwV4z0jY",
            "name":"MyBotName"
        },
        "textFormat":"plain",
        "locale":"en-US",
        "text":"i'm looking for this",
        "entities":[  
            {  
                "type":"ClientCapabilities",
                "requiresBotState":true,
                "supportsTts":true,
                "supportsListening":true
            }
        ],
        "channelData":{  
            "clientActivityId":"1560940638882.6146258363791712.0"
        }
    }
]

【问题讨论】:

  • 你用的是什么渠道?
  • @KyleDelaney 我正在使用 DirectLine 频道
  • 您使用的是网络聊天还是自定义 Direct Line 客户端?
  • 我们正在使用网络聊天。我们连接到类似于this 的机器人
  • 您使用的是网络聊天 v3 还是 v4?

标签: c# botframework


【解决方案1】:

如果你在 Visual Studio 中调试,可以点击“查看详细信息”查看整个异常对象。

对于ErrorResponseException,您可以看到在 HTTP 响应中返回的实际错误消息。在这种情况下,它会显示“无效活动”,这表明您尝试发送的活动有问题。

事实证明,您没有指定活动的接收者。如果您指定收件人,那么您应该通过“BadRequest”异常。

然而:您可能会遇到更多问题。即使您没有遇到异常,也有一些事情可以使SendConversationHistory 失败而不会出现错误,同时不会就您的活动未显示在聊天中的原因提供任何反馈。

您填充 ID 属性的策略是有风险的,因为您的机器人可能会在调用 SendConversationHistory 之前向对话发送消息。如果您的机器人在同一轮次中向用户发送了一条消息,它将具有您尝试分配给对话历史记录中活动的相同活动 ID。这将导致冲突,您不会看到活动显示。我建议以某种与 Direct Line 自动生成的 ID 值不同的独特方式格式化 ID。

通过修改如下代码,我能够成功发送您的活动:

foreach (var a in activities)
{
    incrementId++;
    // Use your own ID format
    a.Id = string.Concat("history|", incrementId.ToString().PadLeft(7, '0'));
    a.ChannelData = null;
    a.Conversation = new ConversationAccount(id: convId);

    if (a.From.Name == message.Recipient.Name)
    {
        // If the activity was from the bot, assign the user as the recipient
        a.Recipient = message.From;
        a.From = message.Recipient;
    }
    else
    {
        // If the activity was from the user, assign the bot as the recipient
        a.Recipient = message.Recipient;
        a.From = message.From;
    }
}

【讨论】:

  • 谢谢。它帮助我展示了机器人的活动。来自用户的那个仍未呈现。即使我在调试 Javascript 时看到它们出现在某一时刻。我是否缺少其他属性?感谢您花时间回答并帮助我解决这个问题。
  • @Shamrock - 我已经更新了代码,以便每个活动都设置其FromRecipient 属性。但是,我通过运行代码来响应用户发起的消息活动来测试代码。如果您正在运行代码以响应来自网络聊天的您自己的反向通道事件,您需要确保该事件包含所有必要的信息:conversationfromrecipient。这些都应该与当前的对话相匹配,并且它们可能不会与旧活动的对话相匹配。我正在检查代码中机器人的名称,因为它可能是相同的。
  • 我尝试添加 From 但它并没有改变用户的消息没有显示的事实。由于我公司决定用“匿名”作为名称和id来初始化用户,所以我认为当前活动中的用户名称应该保持与上一个相同,不是吗?
  • @Shamrock - 我可以看到您发送给机器人的反向通道活动不包含 recipient 属性。您应该包含该属性或修改 C# 以使用内部存储的机器人名称/ID,而不是从活动中检索它们。
  • 抱歉回复太晚了,我正在度假。所以我一直在尝试,因为我仍然看不到用户聊天,而且我的 botchat.js 版本似乎是剩下的问题。感谢您的时间和帮助,因为我可能不会自己想出收件人。我会将您的答案标记为正确。
猜你喜欢
  • 1970-01-01
  • 2019-05-30
  • 2012-09-01
  • 1970-01-01
  • 2018-08-31
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多