4

I am looking to send a welcome message when a user installs my Teams bot.

I've looked at the Teams API documentation and have received mixed messages on whether this should be possible. I have read in various places that my bot should receive a conversationUpdate when the bot is installed, as well as reading in various issues that I will not receive such an event.

However, a bot exists which has this functionality. Hipmunk, when installed with private scope, sends me a message without being provoked further. How is this bot able to do this, and how can I replicate this functionality?

Thanks

Brendan Hart
  • 199
  • 1
  • 8

1 Answers1

9

Documentation likely conflicts because the MS Teams team is making very fast progress in implementing all of the botframework features. We also have made some pretty big changes to activity handlers--I'm personally not aware whether or not these specific changes made it so the bot can receive the Teams ConversationUpdate or if it works because of something else.

These tables should fairly accurately reflect the current state of activities by channel.

I just tested a Teams bot that captures every activity with a few scenarios and here's what activity handlers fire:

When A User Adds the Bot For the First Time (1:1 Welcome Message):

  • OnConversationUpdate
  • OnTurn
  • OnMembersAdded
  • OnDialog

When a Bot Is Installed to a Channel (Group Welcome Message):

Note: These should also fire when a user is added to a Team (not the channel within the team) where the bot already exists, but I'm not able to test this.

  • OnTurn
  • OnConversationUpdate
  • OnMembersAdded
  • OnDialog

When a Bot Is Messaged:

  • OnTurn
  • OnMessage
  • OnDialog

Here's the code I used to test this (from bot.ts, built from Echo Bot Sample):

import { ActivityHandler, MessageFactory, TurnContext } from 'botbuilder';

export class MyBot extends ActivityHandler {
    constructor() {
        super();
        // See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types.
        this.onTurn(async (turnContext, next) => { await this.sendTeamsMessage('onTurn', turnContext); await next();});
        this.onMembersAdded(async (turnContext, next) => { await this.sendTeamsMessage('onMembersAdded', turnContext); await next();});
        this.onMembersRemoved(async (turnContext, next) => { await this.sendTeamsMessage('onMembersRemoved', turnContext); await next();});
        this.onEvent(async (turnContext, next) => { await this.sendTeamsMessage('onEvent', turnContext); await next();});
        this.onConversationUpdate(async (turnContext, next) => { await this.sendTeamsMessage('onConversationUpdate', turnContext); await next();});
        this.onMessage(async (turnContext, next) => { await this.sendTeamsMessage('onMessage', turnContext); await next();});
        this.onTokenResponseEvent(async (turnContext, next) => { await this.sendTeamsMessage('onTokenResponseEvent', turnContext); await next();});
        this.onUnrecognizedActivityType(async (turnContext, next) => { await this.sendTeamsMessage('onUnrecognizedActivityType', turnContext); await next();});
        this.onDialog(async (turnContext, next) => { await this.sendTeamsMessage('onDialog', turnContext); await next();});
    }

    private sendTeamsMessage = async (activityHandlerName: string, turnContext: TurnContext) => {

        const message = MessageFactory.text(`**[${activityHandlerName}]** event received`);

        await turnContext.sendActivity(message);
        console.log(`Sent: ${message.text}`)
    }
}

Note: await next() ensures that all appropriate activity handlers can be called for a given activity instead of stopping after the first one (onTurn) is called.

Sending a 1:1 Welcome Message

Something like this should work (from the Core Bot Sample):

this.onMembersAdded(async (context) => {
    const membersAdded = context.activity.membersAdded;
    for (const member of membersAdded) {
        if (member.id !== context.activity.recipient.id) {
            const welcomeCard = CardFactory.adaptiveCard(WelcomeCard);
            await context.sendActivity({ attachments: [welcomeCard] });
        }
    }
});

We're working on writing samples with the new activity handlers, but you can comb through this Samples Branch to get some ideas. I wrote mine in TypeScript, but it works and there are samples in C#, too.

mdrichardson
  • 7,141
  • 1
  • 7
  • 21
  • This seems to work great when I first create an app and add it. Is there a way to get notified of uninstalling and reinstalling the app, or should I only expect an event when my app is added for the first time? Thanks for your help! – Brendan Hart Apr 05 '19 at 09:26
  • Unfortunately, you pretty much have to create a new Web App Bot in Azure so you get a new AppId. See [this answer](https://stackoverflow.com/a/55181937/10860086), from Wajeed, who is on the MS Teams team. – mdrichardson Apr 05 '19 at 14:44
  • ...I ran into that same issue while testing this, too. Instead of making a new Web App Bot every time, I had my coworkers try installing it. If you come across something easier, let me know! I didn't test using Team scope, like Wajeed mentions in that answer. – mdrichardson Apr 05 '19 at 15:15
  • Just to update this issue, if anybody would like to test their welcome message in the future without having to install the bot with a different user, it is possible to start a new conversation with the Bot Framework Emulator which will receive the welcome message each time. – Brendan Hart Jun 06 '19 at 22:33