{"id":14900,"date":"2023-08-08T02:41:02","date_gmt":"2023-08-08T09:41:02","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/?p=14900"},"modified":"2023-08-18T02:16:35","modified_gmt":"2023-08-18T09:16:35","slug":"ai-pair-programming-build-a-product-inventory-app-with-github-copilot-and-teams-toolkit","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/ai-pair-programming-build-a-product-inventory-app-with-github-copilot-and-teams-toolkit\/","title":{"rendered":"AI pair programming: Build a product inventory app with GitHub Copilot and Teams Toolkit"},"content":{"rendered":"<p>Let&#8217;s dive into how AI pair programming can help you build your first application for Microsoft Teams specifically designed for a product inventory scenario. We will build a Teams app that allows users to insert business data into a Teams conversation. This is called a search message extension. We won&#8217;t be starting from the ground up; instead, we&#8217;ll leverage an existing sample app and repurpose it to become our very own &#8220;product inventory app.&#8221;<\/p>\n<h2>Tools you\u2019ll need<\/h2>\n<ul>\n<li><a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a><\/li>\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/microsoftteams\/platform\/toolkit\/install-teams-toolkit?tabs=vscode#install-teams-toolkit-for-visual-studio-code\">Teams Toolkit extension for Visual Studio Code<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/features\/copilot\">GitHub Copilot extension for Visual Studio Code<\/a> (Start with the free trial)<\/li>\n<\/ul>\n<h2>Get started<\/h2>\n<h3>Sample app in Codespaces<\/h3>\n<p>Go to this <a href=\"https:\/\/learn.microsoft.com\/en-us\/microsoftteams\/platform\/get-started\/build-message-extension?tabs=teamstoolkitcodespaces\">documentation link <\/a> and open the sample in GitHub Codespaces.<\/p>\n<p>First, we will open an existing sample project which will form the base of our product inventory app. For that, select the <strong>Open in GitHub Codespaces<\/strong> button in the documentation and create a new codespace.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-14901 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-1.png\" alt=\"Screenshot of a web page with documentation and a link to open the sample in GitHub codespaces.\" width=\"1378\" height=\"409\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-1.png 1378w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-1-300x89.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-1-1024x304.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-1-768x228.png 768w\" sizes=\"(max-width: 1378px) 100vw, 1378px\" \/><\/p>\n<p>Your codespace will be set up with a pre-loaded app that already has the &#8220;Message Extension&#8221; capability, enabling you to search npm packages and insert one into a Teams conversation. Don\u2019t worry about this scenario &#8211; we are going to make it more useful to search for products instead of the npm packages data.<\/p>\n<h3>Tool to run the Teams app<\/h3>\n<p>Now for Teams Toolkit, a tool to help you run this app without worrying too much about the plumping that goes on behind the scenes. You\u2019ll need a Microsoft 365 account where you have permission to install new apps. If you don&#8217;t have one, you\u2019ll need to create a test tenant.<\/p>\n<p>Select the Teams icon on the extension bar and go to <strong>Accounts<\/strong> and sign into Microsoft 365 using your developer tenant account (see steps <img decoding=\"async\" width=\"47\" height=\"45\" class=\"wp-image-14902\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-2.png\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-2.png 47w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-2-24x24.png 24w\" sizes=\"(max-width: 47px) 100vw, 47px\" \/> and <img decoding=\"async\" width=\"45\" height=\"45\" class=\"wp-image-14903\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-3.png\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-3.png 45w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-3-24x24.png 24w\" sizes=\"(max-width: 45px) 100vw, 45px\" \/> ). if you don\u2019t have one, get one by selecting <strong>Create a Microsoft 365 test tenant<\/strong>:<\/p>\n<p><img decoding=\"async\" class=\"wp-image-14904 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-4.png\" alt=\"Screenshot showing a link to create a Microsoft 365 Testing Tenant\" width=\"1380\" height=\"728\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-4.png 1380w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-4-300x158.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-4-1024x540.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-4-768x405.png 768w\" sizes=\"(max-width: 1380px) 100vw, 1380px\" \/><\/p>\n<h3>Run the sample<\/h3>\n<p>Before we proceed with updating the code, it is essential to understand the app&#8217;s existing functionality. Select the button next to &#8216;local&#8217; under <strong>Environments<\/strong> to start debugging and running the app locally.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-14905 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica.png\" alt=\"Screenshot of Teams Toolkit showing a red arrow pointing at the button next to 'local' under Environments to start debugging and running the app locally.\" width=\"1380\" height=\"838\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica.png 1380w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-300x182.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-1024x622.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-768x466.png 768w\" sizes=\"(max-width: 1380px) 100vw, 1380px\" \/><\/p>\n<p>The app will open up a browser tab which has an instance of Teams in a web browser with an install dialog as shown below. Add the app to your teams by selecting <strong>Add<\/strong> button.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-14906 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-6.png\" alt=\"A browser tab which has an instance of Teams in a web browser with an install dialog.\" width=\"1379\" height=\"835\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-6.png 1379w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-6-300x182.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-6-1024x620.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-6-768x465.png 768w\" sizes=\"(max-width: 1379px) 100vw, 1379px\" \/><\/p>\n<p>If for some reason the browser did not open with an install dialog, manually load it using the link highlighted below, which you will find in the Output pane.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-14907 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-1.png\" alt=\"A screenshot in VSCode showing how to manually load the install dialog using the link located in the Output pane.\" width=\"1379\" height=\"732\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-1.png 1379w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-1-300x159.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-1-1024x544.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/a-screenshot-of-a-computer-description-automatica-1-768x408.png 768w\" sizes=\"(max-width: 1379px) 100vw, 1379px\" \/><\/p>\n<p>Currently, our app is designed to search through the npm packages registry, fetching relevant information and displaying it in a card format. This serves as the base of our app&#8217;s functionality. However, we&#8217;ll be making a significant update by replacing this npm package search with a product inventory service. The new functionality will allow us to manage and showcase products for our inventory app.<\/p>\n<p><img decoding=\"async\" class=\"wp-image-14908 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-8.gif\" alt=\"Screenshot from Microsoft Teams displaying the scenario explained in the previous paragraph.\" width=\"2560\" height=\"1415\" \/><\/p>\n<h3>AI pair programming<\/h3>\n<p>Now comes the exciting part \u2013 the AI pair programming! First, let&#8217;s go ahead and install GitHub Copilot extension in VS Code which is our AI-based tool to help write code for our app to transform into a product inventory app.<\/p>\n<p>In the Extension pane as show in <img decoding=\"async\" width=\"47\" height=\"45\" class=\"wp-image-14909\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-9.png\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-9.png 47w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-9-24x24.png 24w\" sizes=\"(max-width: 47px) 100vw, 47px\" \/> , type copilot in the search box as shown in <img decoding=\"async\" width=\"45\" height=\"45\" class=\"wp-image-14910\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-10.png\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-10.png 45w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-10-24x24.png 24w\" sizes=\"(max-width: 45px) 100vw, 45px\" \/> . Select <strong>GitHub Copilot.<\/strong><\/p>\n<p><img decoding=\"async\" class=\"wp-image-14911 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-11.png\" alt=\"Cropped screenshot of the extensions pane In the Extension pane with copilot typed in the search box and GitHub Copilot shown as a selected result.\" width=\"513\" height=\"768\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-11.png 513w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/word-image-14900-11-200x300.png 200w\" sizes=\"(max-width: 513px) 100vw, 513px\" \/><\/p>\n<p>Let&#8217;s jump straight into refactoring the code! Go to the file <em>teamsBot.js<\/em> and locate the function <strong>handleTeamsMessagingExtensionQuery<\/strong>.<\/p>\n<p>In this function, the code fetches data from the npm packages API, which we need to replace with our own custom service that we&#8217;ll be writing. Before we dive into that, let&#8217;s begin by creating our mock product data.<\/p>\n<p>To do this, go ahead and create a new file named <em>products.js<\/em>, where we&#8217;ll store and export our mock product data to be used in the service. Once the file is ready, let\u2019s get our AI programmer to write mock data for us. For this demo, we are only asking for three products; you can go ahead and ask for ten if you need a longer list of products.<\/p>\n<p>AI pair programmer writes code for you line by line. You\u2019ll just need to keep tabbing to add the prompted code until it is complete.<\/p>\n<p><strong>Prompt:<\/strong> <span style=\"color: #008000;\">\/\/ create a const array of products with length 3 and properties: id, name, description<\/span><\/p>\n<p><strong>Output: <\/strong><\/p>\n<p>https:\/\/gist.github.com\/rabwill\/9fc7bbda83c77decead232f95a37ab02<\/p>\n<p>Next write a prompt to export the array.<\/p>\n<p><strong>Prompt: <\/strong><span style=\"color: #008000;\">\/\/ export the products array<\/span><\/p>\n<p><strong>Output: <\/strong><span style=\"color: #0000ff;\">module.exports<\/span> =<span style=\"color: #0000ff;\"> products;<\/span><\/p>\n<p>Finished <a id=\"post-14900-OLE_LINK1\"><\/a><em>products.js<\/em> file will appear the same as what is seen below:<\/p>\n<p>https:\/\/gist.github.com\/rabwill\/a9903b4c136690b03034843ae35b4add<\/p>\n<p>Now it&#8217;s time to create the service. Head over to your project\u2019s <em>index.js<\/em> file, and let&#8217;s get started.<\/p>\n<p>To begin, import the necessary products module into the <em>index.js<\/em> file.<\/p>\n<p><strong>Prompt:<\/strong> <span style=\"color: #008000;\">\/\/ import products from products.js file<\/span><\/p>\n<p><strong>Output:<\/strong><\/p>\n<p>https:\/\/gist.github.com\/rabwill\/8e0a4412d63413e2cb6f952df92c33f4<\/p>\n<p>Next, we&#8217;ll use this module to set up and handle the service for our product inventory app. Let&#8217;s take this step before moving on to the next stage of the implementation.<\/p>\n<p><strong>Prompt:<\/strong> <span style=\"color: #008000;\">\/\/ create an asynchoronous API service to return product searching the products array by name, not case sensitive and includes string<\/span><\/p>\n<p><strong>Output:<\/strong><\/p>\n<p>https:\/\/gist.github.com\/rabwill\/e1afd263703a9c4e1f9fee1cf0a7d744<\/p>\n<p>Next, it&#8217;s time to integrate the API for products instead of the npm call. Go to the <em>teamsBot.js<\/em> file and locate the function <strong>handleTeamsMessagingExtensionQuery<\/strong>.<\/p>\n<p>In this function, you&#8217;ll find the axios.get call that we need to replace. Comment out the axios.get call and instead write a prompt to fetch data from the newly written API service to get products. This refactoring will enable our app to interact with the products API.<\/p>\n<p><strong>Prompt:<\/strong> <span style=\"color: #008000;\">\/\/ get response to get product based on name from querystring using the product API<\/span><\/p>\n<p><strong>Output:<\/strong><\/p>\n<p>https:\/\/gist.github.com\/rabwill\/83cf2a2cd195c594471bc49029e96b82<\/p>\n<p>Tidy up the response code below to create the rich card. Unlike the npm API, which returns <em>data.object<\/em> or <em>object.package<\/em>, we don&#8217;t have such properties in our product service. So, let&#8217;s remove the additional properties to ensure the card is generated correctly and avoid any potential errors.<\/p>\n<p>Cleaned <strong>handleTeamsMessagingExtensionQuery<\/strong> function looks like this:<\/p>\n<p>https:\/\/gist.github.com\/rabwill\/84c1ac655ab25342a2e33564ffd3bfd5<\/p>\n<h3>Let\u2019s run the app<\/h3>\n<p>Now, let&#8217;s return to the Teams conversation and give the search-based message extension another go. Type in \u201cpro\u201d and you should see the products showing up. Select and embed the card into the conversation.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/Products-ME-1.gif\"><img decoding=\"async\" class=\"aligncenter size-full\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2023\/08\/Products-ME-1.gif\" alt=\"Screenshot inside Microsoft Teams running the app created with the sample, displaying a Teams conversation using the search-based message extension.\" width=\"2512\" height=\"1333\" \/><\/a><\/p>\n<p>Watch a live demo below:<\/p>\n<p><iframe loading=\"lazy\" title=\"GitHub Copilot with Teams\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/a06rT7Jxyr8?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<p>Happy coding and AI pair-programming!<\/p>\n<p>More resources:<\/p>\n<ul>\n<li>Visit our <a href=\"https:\/\/developer.microsoft.com\/en-us\/microsoft-365\">Microsoft 365 Dev Center.<\/a><\/li>\n<li>Follow us on <a href=\"https:\/\/twitter.com\/Microsoft365Dev\">Microsoft 365 Developer (@Microsoft365Dev) \/ Twitter<\/a> for the latest news and announcements.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Learn how AI can help you build your first app for Microsoft Teams, specifically designed for a product inventory scenario.<\/p>\n","protected":false},"author":71938,"featured_media":15044,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,128],"tags":[255,70,251],"class_list":["post-14900","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-365-developer","category-microsoft-teams","tag-ai-pair-programming","tag-github","tag-microsoft-365-copilot"],"acf":[],"blog_post_summary":"<p>Learn how AI can help you build your first app for Microsoft Teams, specifically designed for a product inventory scenario.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/14900","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/71938"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=14900"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/14900\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/15044"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=14900"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=14900"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=14900"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}