Proactive Dialog with the Bot Framework from Group chat to Personal chat in MS Teams

269 Views Asked by At

It's possible to send a proactive message (=private) to the sender of a message in a teams groups chat using the next part of code:

if (stepContext.Context.Activity.ChannelId == Channels.Msteams &&
    stepContext.Context.Activity.Conversation.IsGroup.HasValue &&
    stepContext.Context.Activity.Conversation.IsGroup.Value) {
        var teamConversationData = stepContext.Context.Activity.GetChannelData<TeamsChannelData>();
        var connectorClient = new ConnectorClient(new Uri(stepContext.Context.Activity.ServiceUrl), _credentialOptions.MicrosoftAppId, _credentialOptions.MicrosoftAppPassword);
        var userId = stepContext.Context.Activity.From.Id;
        var tenantId = teamConversationData.Tenant.Id;
        var parameters = new ConversationParameters
            {
                  Members = new[] { new ChannelAccount(userId) },
                  ChannelData = new TeamsChannelData
                  {
                       Tenant = new TenantInfo(tenantId),
                  },
            };
        var conversationResource = await connectorClient.Conversations.CreateConversationAsync(parameters, cancellationToken: cancellationToken);
        var message = Activity.CreateMessageActivity();
        message.Text = "This is a proactive message. I've sent it from a group conversation.";
        await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message, cancellationToken: cancellationToken);
}

But the issue is that I also want to be able to trigger a Dialog for that calling user instead of sending an Activity. It doesn't looks like that is possible after searching the web? I played a bit with the code and found out that I could replace

await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message, cancellationToken: cancellationToken);

with

stepContext.Context.Activity.Conversation.Id = conversationResource.Id;
stepContext.Context.Activity.Conversation.IsGroup = false;

This way it is possible to send dialogs to the private chat of the sending user.

When I look in the database I can see the saved dialog stack of the user populated with the dialog (waiting for user interaction). I can also see the group conversation dialog stack which remains empty, so the bot is still responsive in the group chat and for other users.

When the dialog ends I put the Conversation.Id and .IsGroup back to the previous group chat values I've saved on the context and it's able to pass the final answer(s) in the group chat just like I would like it to be.

Basically my code can switch to send stuff in private mid dialog, and at any other point in the dialog it can switch back to the group conversation.

The question is about me changing the Conversation Id mid dialog. Is this something normal to do? Will this break stuff I didn't think about yet?

1

There are 1 best solutions below

0
On BEST ANSWER

I don't see any problem with this approach, but I think typically you'd start a new dialog rather than continue to use the same one.

I think any code accessing state prior to the hack would be persisted under the new id when state is saved. Middleware running prior to the turn, vs after the turn completes, would have two separate conversation ids.