如何使用主动频道对话框在频道中启动新线程?

How to start a new thread in channel with a Proactive Channel Dialog?

我的机器人可以在像 this 这样的频道中创建一个新线程。现在我想在这个新线程中开始主动对话。我在随后的 ContinueConversationAsync 回调中启动对话框。对话框似乎开始了,但是一旦提示用户,用户的回复就不是由对话框处理,而是由 MainDialog 处理。

如果我启动与用户发送的对话 activity,则对话会正确处理提示。只有主动对话在新创建的频道中似乎不起作用。

这是我的代码

var conversationParameters = new ConversationParameters
{
    IsGroup = true,
    ChannelData = new TeamsChannelData
    {
        Channel = new ChannelInfo(teamsChannelId)
    },
    Activity = (Activity)message
};

ConversationReference newConversationReference = null;
await adapter.CreateConversationAsync(
    teamsChannelId,
    serviceUrl,
    credentials,
    conversationParameters,
    (t, c) =>
    {
        newConversationReference = t.Activity.GetConversationReference();
        return Task.CompletedTask;
    }, cancellationToken);


await adapter.ContinueConversationAsync(
    _appId,
    newConversationReference,
    async (t, c) =>
    {
        var dialogStateAccessor = this.conversationState.CreateProperty<DialogState>(nameof(DialogState));
        var dialogState = await dialogStateAccessor.GetAsync(t, () => new DialogState());

        var dialogSet = new DialogSet(dialogStateAccessor);
        dialogSet.Add(dialog);
        var dialogContext = await dialogSet.CreateContextAsync(t, cancellationToken);
        await dialogContext.BeginDialogAsync(dialog.Id, options, cancellationToken);
        await conversationState.SaveChangesAsync(t, false, cancellationToken);
    },
    cancellationToken);

有什么想法吗?

我的问题是我从新创建的通道 post 的回调中获取了 ConversationReference 并试图在 ContinueConverationAsync() 中使用它。然而 ConversationReference 是不够的。所以我将原来的 ConversationReference 与新的 ConversationReference 合并并使用了它。现在它就像一个魅力。

这是我更新后的代码:

ConversationReference newConversationReference = null;
await adapter.CreateConversationAsync(
    conversationChannelId,
    serviceUrl,
    credentials,
    conversationParameters,
    (t, c) =>
    {
        newConversationReference = t.Activity.GetConversationReference();
        return Task.CompletedTask;
    }, cancellationToken);

if (dialog != null)
{
    // Proactive channel dialogs dont seem to work with the newConversationReference: responses to the dialog are handled by the MainDialog.
    // So I just create a new ConversationReference from the topic subscription and the new conversation. That works.
    var newNewConversationReference = new ConversationReference
    {
        ActivityId = newConversationReference.ActivityId,
        Bot = conversationReference.Bot,
        ChannelId = conversationReference.ChannelId,
        ServiceUrl = conversationReference.ServiceUrl,
        User = conversationReference.User,
        Conversation = new ConversationAccount
        {
            Id = newConversationReference.Conversation.Id,
            AadObjectId = conversationReference.Conversation.AadObjectId,
            ConversationType = conversationReference.Conversation.ConversationType,
            IsGroup = conversationReference.Conversation.IsGroup,
            Name = conversationReference.Conversation.Name,
            Properties = conversationReference.Conversation.Properties,
            TenantId = conversationReference.Conversation.TenantId,
            Role = conversationReference.Conversation.Role,
        },
    };

    await adapter.ContinueConversationAsync(
        _appId,
        newNewConversationReference,
        async (t, c) =>
        {
            var dialogStateAccessor = this.conversationState.CreateProperty<DialogState>(nameof(DialogState));
            var dialogState = await dialogStateAccessor.GetAsync(t, () => new DialogState());

            var dialogSet = new DialogSet(dialogStateAccessor);
            dialogSet.Add(dialog);
            var dialogContext = await dialogSet.CreateContextAsync(t, cancellationToken);
            await dialogContext.BeginDialogAsync(dialog.Id, options, cancellationToken);
            await conversationState.SaveChangesAsync(t, false, cancellationToken);
        },
        cancellationToken);
}