{"id":17,"date":"2022-01-18T18:45:52","date_gmt":"2022-01-18T18:45:52","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/coucoulr\/?p=17"},"modified":"2022-01-18T18:45:52","modified_gmt":"2022-01-18T18:45:52","slug":"creating-a-microsoft-teams-bot-part-3-bot-operations","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/coucoulr\/2022\/01\/18\/creating-a-microsoft-teams-bot-part-3-bot-operations\/","title":{"rendered":"Creating a Microsoft Teams Bot &#8211; Part 3: Bot Operations"},"content":{"rendered":"\n<p>This is the third post in a series of posts documenting the creation of BeaverHours, a Microsoft Teams bot which handles office hours queueing.<\/p>\n\n\n\n<p>Previously, the architecture of a Microsoft Teams bot was inspected and found to be a REST API endpoint wrapping a <code>TeamsBot<\/code> object. In this post, we\u2019ll explore the class that object is an instance of and how it handles commands.<\/p>\n\n\n\n<p>Inspecting the boilerplate code, the <code>TeamsBot<\/code> class is defined in <code>bot\/teamsBot.ts<\/code>. The example bot comes with two built-in commands: \u201cwelcome\u201d and \u201clearn\u201d; searching the source file for these words reveals that the handlers are defined in the constructor, which looks something like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">constructor() {\r\n    this.onMessage(async (context, next) =&gt; {\r\n      let txt = context.activity.text;\r\n      \/\/ some text sanitizing here\r\n\r\n      switch (txt) {\r\n        case \"welcome\": {\r\n          const card =\r\n            AdaptiveCards.declareWithoutData(rawWelcomeCard).render();\r\n          await context.sendActivity({\r\n            attachments: [CardFactory.adaptiveCard(card)],\r\n          });\r\n          break;\r\n        }\r\n        case \"learn\": {\r\n          this.likeCountObj.likeCount = 0;\r\n          const card = AdaptiveCards.declare&lt;DataInterface&gt;(\r\n            rawLearnCard\r\n          ).render(this.likeCountObj);\r\n          await context.sendActivity({\r\n            attachments: [CardFactory.adaptiveCard(card)],\r\n          });\r\n          break;\r\n        }\r\n      }\r\n      await next();\r\n    });\r\n}\r<\/pre>\n\n\n\n<p>By inspection, it appears that the <code>onMessage<\/code> event handler fires when the bot receives a message and provides a <code>context<\/code> object, describing the received event and the contextual state, and a <code>next<\/code> function which the handler is expected to pass control to when it\u2019s 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 <code>txt<\/code>, which contains the sanitized value of <code>context.activity.text<\/code>, the body of the received message.<\/p>\n\n\n\n<p>Using the existing cases as a guide, we can change the body of the switch statement to handle the command we want. The <code>context.sendActivity<\/code> method appears to be what prompts the bot to send a reply, so we can use that, in conjunction with <code>txt<\/code>, to create an echo bot.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">switch (txt) {\r\n  case \"hello\": {\r\n    await context.sendActivity(`Hi there! You sent \"${txt}\".`);\r\n    break;\r\n  }\r\n}\r<\/pre>\n\n\n\n<p>The result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"657\" height=\"249\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/Screenshot-2022-01-18-103821.png\" alt=\"\" class=\"wp-image-18\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/Screenshot-2022-01-18-103821.png 657w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/Screenshot-2022-01-18-103821-300x114.png 300w\" sizes=\"auto, (max-width: 657px) 100vw, 657px\" \/><\/figure>\n\n\n\n<p>It works!<\/p>\n\n\n\n<p>Next time, we\u2019ll dig into adding commands into the command menu and implementing more complex logic in commands.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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\u2019ll explore the class that object &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blogs.oregonstate.edu\/coucoulr\/2022\/01\/18\/creating-a-microsoft-teams-bot-part-3-bot-operations\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Creating a Microsoft Teams Bot &#8211; Part 3: Bot Operations&#8221;<\/span><\/a><\/p>\n","protected":false},"author":12039,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-17","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts\/17","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/users\/12039"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/comments?post=17"}],"version-history":[{"count":1,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts\/17\/revisions"}],"predecessor-version":[{"id":19,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts\/17\/revisions\/19"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/media?parent=17"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/categories?post=17"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/tags?post=17"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}