Search code examples
c#botframeworkmicrosoft-graph-teams

Teams Bot Create Conversation In Controller


I want to build a Teams bot that can send proactive messages, including creating conversations even if the user has never had a conversation with the bot.

I followed the proactive sample and adapted it to send a notification as POST in the notify controller. I am able to continue a conversation, but when I try to create one, the user does not get any messages.

Here is my code to create a conversation from the notify controller:

// I got the following 4 values logging them on the bot in a conversation started by a user
const string botAppId = "<MicrosoftApptId GUID>";
const string serviceUrl = "<my service URL>";
const string tenantId = "<my tenant ID>";
const string recipientId = "<recipient ID xy:GUID>";

var title = "test title";
var activity = Activity.CreateMessageActivity();
activity.Type = ActivityTypes.Message;
activity.Text = "test message";

await ((BotAdapter)_adapter).CreateConversationAsync(
    botAppId: botAppId, 
    channelId: Microsoft.Bot.Connector.Channels.Msteams, 
    serviceUrl: serviceUrl, 
    audience: null, 
    conversationParameters: new ConversationParameters
    {
        Activity = (Activity)activity,
        Bot = new ChannelAccount(botAppId),
        IsGroup = false,
        Members = new List<ChannelAccount> { new ChannelAccount(recipientId) },
        TopicName = title,
        TenantId = tenantId
    },
    callback: (turnContext, cancellationToken) => Task.CompletedTask,
    cancellationToken: default(CancellationToken));

What am I doing wrong here? Am I missing things in the conversation parameters? Should I populate the audience? How?

Thanks for any help!

Note that this is a new post based on my comment on https://stackoverflow.com/a/60024372/1322336


Solution

  • You can't start a conversation with a user that has never talked to your bot and when they did that you stored a conversation reference somewhere to use it when sending the proactive message.

    What the proactive sample does is precisely that, store in memory the references to the conversations.

    Teams assigns a user id that's unique to the bot-user relationship, so there's no way you can start a conversation even if you knew the user's active directory object id. Or at least not without using it to create the conversation reference.

    Following the Proactive Sample

    https://github.com/microsoft/BotBuilder-Samples/blob/95f2fa8440b4cf3f984c3f1cb82966b8b45d71e8/samples/csharp_dotnetcore/16.proactive-messages/Bots/ProactiveBot.cs#L26 That method is the one storing the conversation reference. Then the notify endpoint loops through the stored conversation references and send notifications. If your user didn't trigger that method ever, then the notify endpoint won't do anything with that user. I see that you modified the notify controller, but I'm not sure how you are getting the recipientId for a user that never talked to you.

    Talking to a user for the first time, Microsoft Graph Approach.

    To do that you'll need access to the Microsoft Graph API in the AAD tenant and use it to:

    1. Get the user
    2. Get the AppInstallationId if the user has installed your bot or potentially force the installation
    3. Use that to get the ChatId between the bot and that AppInstallation
    4. Use that ChatId to create the conversation reference for that user.
    5. Optionally store somewhere the reference to the user id and the conversation reference you created so you don't have to do all the previous steps for that user again.

    Check this project out: https://github.com/microsoft/microsoft-teams-apps-company-communicator