{"id":28,"date":"2022-01-27T19:52:42","date_gmt":"2022-01-27T19:52:42","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/coucoulr\/?p=28"},"modified":"2022-01-27T19:52:42","modified_gmt":"2022-01-27T19:52:42","slug":"creating-a-microsoft-teams-bot-part-4-bot-commands","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/coucoulr\/2022\/01\/27\/creating-a-microsoft-teams-bot-part-4-bot-commands\/","title":{"rendered":"Creating a Microsoft Teams Bot &#8211; Part 4: Bot Commands"},"content":{"rendered":"\n<p>This is the fourth 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>In the last installment, we learned how the bot processes input with its <code>onMessage<\/code> event handler. Now, we&#8217;ll learn how to populate the bot&#8217;s command menu to offer suggestions to the user about what commands the bot will process. The command menu, seen in the screenshot below, offers an intuitive way to signal to the user what the bot can be expected to do.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"630\" height=\"312\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/image-5.png\" alt=\"\" class=\"wp-image-23\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/image-5.png 630w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/image-5-300x149.png 300w\" sizes=\"auto, (max-width: 630px) 100vw, 630px\" \/><\/figure>\n\n\n\n<p>Searching the contents of the code reveals two places where this particular command menu is defined: <code>templates\/appPackage\/manifest.local.template.json<\/code> and <code>templates\/appPackage\/manifest.remote.template.json<\/code>. Intuition tells us (and the docs confirm) that these are configuration files for local and remote deployment; that is, local behavior will be defined by <code>manifest.local.template.json<\/code> and remote behavior will be defined by <code>manifest.remote.template.json<\/code>. In these files, the key property that is of interest to us is the bots array, which holds bot objects which take the form:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"botId\": &lt;string&gt;,\n  \"scopes\":&nbsp;[\"personal\", \"team\",\"groupchat\"],\n  \"supportsFiles\":&nbsp;&lt;boolean&gt;,\n  \"isNotificationOnly\":&nbsp;&lt;boolean&gt;,\n  \"commandLists\":&nbsp;[\n    {\n    \"scopes\": [\"personal\", \"team\",\"groupchat\"],\n    \"commands\":&nbsp;[\n      {\n        \"title\":&nbsp;\"welcome\",\n        \"description\":&nbsp;\"Resend&nbsp;welcome&nbsp;card&nbsp;of&nbsp;this&nbsp;Bot\"\n      },\n      {\n        \"title\":&nbsp;\"learn\",\n        \"description\":&nbsp;\"Learn&nbsp;about&nbsp;Adaptive&nbsp;Card&nbsp;and&nbsp;Bot&nbsp;Command\"\n      }\n    }\n  ]\n}<\/pre>\n\n\n\n<p>Clearly, <code>commandLists.commands<\/code> is the property of interest here. It takes the form of an array of <code>{ title, description }<\/code> objects. Let&#8217;s try replacing the commands here with the <code>hello<\/code> command we wrote in the previous post.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n  \"botId\": &lt;string&gt;,\n  \"scopes\":&nbsp;[\"personal\", \"team\",\"groupchat\"],\n  \"supportsFiles\":&nbsp;&lt;boolean&gt;,\n  \"isNotificationOnly\":&nbsp;&lt;boolean&gt;,\n  \"commandLists\":&nbsp;[\n    {\n    \"scopes\": [\"personal\", \"team\",\"groupchat\"],\n    \"commands\":&nbsp;[\n      {\n        \"title\":&nbsp;\"hello\",\n        \"description\":&nbsp;\"Echoes the user's input.\"\n      }\n    }\n  ]\n}<\/pre>\n\n\n\n<p>It works! We now have a way to signal to the user what commands are available in the bot.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"636\" height=\"307\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/image-7.png\" alt=\"\" class=\"wp-image-25\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/image-7.png 636w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/5205\/files\/2022\/01\/image-7-300x145.png 300w\" sizes=\"auto, (max-width: 636px) 100vw, 636px\" \/><\/figure>\n\n\n\n<p>Using the command menu along with the <code>onMessage<\/code> handler, we were able to define bot behavior and advertise that behavior to the user. In the next installment, we&#8217;ll implement some in-memory structures to preserve state in the bot between messages.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the fourth post in a series of posts documenting the creation of BeaverHours, a Microsoft Teams bot which handles office hours queueing. In the last installment, we learned how the bot processes input with its onMessage event handler. Now, we&#8217;ll learn how to populate the bot&#8217;s command menu to offer suggestions to the &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/blogs.oregonstate.edu\/coucoulr\/2022\/01\/27\/creating-a-microsoft-teams-bot-part-4-bot-commands\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Creating a Microsoft Teams Bot &#8211; Part 4: Bot Commands&#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-28","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts\/28","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=28"}],"version-history":[{"count":1,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts\/28\/revisions"}],"predecessor-version":[{"id":29,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/posts\/28\/revisions\/29"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/media?parent=28"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/categories?post=28"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/coucoulr\/wp-json\/wp\/v2\/tags?post=28"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}