Search code examples
node.jsbotframeworkmicrosoft-graph-apimicrosoft-teams

Proactive messaging bot in Teams without mentioning the bot beforehand


I'm using the Microsoft bot-framework to create a bot and integrate it into teams. Part of the bot's requirements include proactively messaging users once per day. From what I understand, I can only message users that has been added to the team/groupChat after the bot, or that have messaged the bot directly. My question is - can I somehow bypass this limitation? A friend of my referred me to a new feature of graphAPI, as part of the new beta version - https://learn.microsoft.com/en-us/graph/api/user-add-teamsappinstallation?view=graph-rest-beta&tabs=http.

To me it doesn't seem like it could be related to the solution since I'm not getting any data back in the response, so if I have no conversationReference object I still can't message the user.

At the moment my solution is to simply broadcast a message in the channel when it's added, asking users to "register" with it by messaging it. Anyone has any other suggestion?


Solution

  • The easiest way is to:

    1. Install the bot for the team
    2. Query the Team Roster -- The link in Step 3 has an alternative way to do this towards the bottom
    3. Create a conversation with the user and send a proactive message

    There's a lot of code in those links and it's better to just visit them than to copy/paste it here.

    The end of Step 3 also mentions trustServiceUrl, which you may find handy if you run into permissions/auth issues when trying to send a proactive message.


    Edit for Node:

    Install Necessary Packages

    npm i -S npm install [email protected] botframework-connector
    

    Note: The @<version> is important!

    Prepare the Adapter

    In index.js

    const teams = require('botbuilder-teams');
    
    adapter.use(new teams.TeamsMiddleware());
    

    Get the Roster

    // Get Team Roster
    const credentials = new MicrosoftAppCredentials(process.env.MicrosoftAppId, process.env.MicrosoftAppPassword);
    const connector = new ConnectorClient(credentials, { baseUri: context.activity.serviceUrl });
    const roster = await connector.conversations.getConversationMembers(context.activity.conversation.id);
    

    Send the Proactive Message

    const { TeamsContext } = require('botbuilder-teams');
    
    // Send Proactive Message
    const teamsCtx = TeamsContext.from(context);
    const parameters = {
        members: [
            roster[0] // Replace with appropriate user
        ],
        channelData: {
            tenant: {
                id: teamsCtx.tenant.id
            }
        }
    };
    const conversationResource = await connector.conversations.createConversation(parameters);
    const message = MessageFactory.text('This is a proactive message');
    await connector.conversations.sendToConversation(conversationResource.id, message);
    

    Trust the ServiceUrl, as Necessary

    Read about it. You'd want this before the message is sent.

    MicrosoftAppCredentials.trustServiceUrl(context.activity.serviceUrl);