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.