Creating a Microsoft Teams Bot – Part 3: Bot Operations

This is the third post in a series of posts documenting the creation of BeaverHours, a Microsoft Teams bot which handles office hours queueing.

Previously, the architecture of a Microsoft Teams bot was inspected and found to be a REST API endpoint wrapping a TeamsBot object. In this post, we’ll explore the class that object is an instance of and how it handles commands.

Inspecting the boilerplate code, the TeamsBot class is defined in bot/teamsBot.ts. The example bot comes with two built-in commands: “welcome” and “learn”; searching the source file for these words reveals that the handlers are defined in the constructor, which looks something like:

constructor() {
    this.onMessage(async (context, next) => {
      let txt = context.activity.text;
      // some text sanitizing here

      switch (txt) {
        case "welcome": {
          const card =
            AdaptiveCards.declareWithoutData(rawWelcomeCard).render();
          await context.sendActivity({
            attachments: [CardFactory.adaptiveCard(card)],
          });
          break;
        }
        case "learn": {
          this.likeCountObj.likeCount = 0;
          const card = AdaptiveCards.declare<DataInterface>(
            rawLearnCard
          ).render(this.likeCountObj);
          await context.sendActivity({
            attachments: [CardFactory.adaptiveCard(card)],
          });
          break;
        }
      }
      await next();
    });
}

By inspection, it appears that the onMessage event handler fires when the bot receives a message and provides a context object, describing the received event and the contextual state, and a next function which the handler is expected to pass control to when it’s finished. In this way, the message handler is much like standard middleware in common backend frameworks. The true meat of this function is the switch statement on the variable txt, which contains the sanitized value of context.activity.text, the body of the received message.

Using the existing cases as a guide, we can change the body of the switch statement to handle the command we want. The context.sendActivity method appears to be what prompts the bot to send a reply, so we can use that, in conjunction with txt, to create an echo bot.

switch (txt) {
  case "hello": {
    await context.sendActivity(`Hi there! You sent "${txt}".`);
    break;
  }
}

The result:

It works!

Next time, we’ll dig into adding commands into the command menu and implementing more complex logic in commands.

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *