March 21, 2025

SharePoint Site Provisioning: A Guide to Site Scripts & Site Designs with PowerShell

Introduction: Site Scripts and Site Designs

Automating site provisioning in contemporary SharePoint Online environments is essential for ensuring consistency, upholding governance, and enhancing collaboration within an organization. Site Scripts and Site Designs are key tools that facilitate this process, helping to standardize site creation and maintain organizational standards.


What is Site Design?

Site Design is a predefined set of actions that allows users to create new sites with a Modern UI in SharePoint Online (Office 365). It helps SharePoint consultants enhance consistency across multiple site collections within the same tenant. For example, with SharePoint Site Design, users can create new lists and libraries, define the site and list columns, establish content types, set themes, and choose a site logo, among other features.

Site Design is often associated with templates, but it is important to understand that it is not the same as a traditional template tied to a specific site. Many users mistakenly believe that changes made in Site Design will automatically apply to their existing sites. However, this is not how SharePoint Site Design functions. To implement the modifications from Site Design on existing sites, you must actively apply the Site Design to those sites.

SharePoint consultants have the option to choose Site Design when creating a new site through the user interface. Additionally, Site Designs can be applied to existing sites using various methods such as REST, CSOM, or PowerShell scripts. Essentially, Site Designs consist of a collection of scripts that operate in the background during the selection of a design for the creation of a new site. This functionality streamlines the process of site setup and ensures consistency across different SharePoint sites.

What are Site Scripts?

Site Scripts are JSON files that outline a specific sequence of actions to be executed when a Site Design is applied to an existing site or when a new site is created. These scripts can be run multiple times on the same site. They have a non-destructive nature, meaning they will only add missing elements to SharePoint sites.

As of now, you can add the below actions to your Site Script:
  1. Create a new list or library (or alter the default one created with the site).
  2. Create the site columns, and content types, and configure other list settings.
  3. Set site branding properties such as navigation layout, header layout, and header background.
  4. Apply a theme and also Set a site logo.
  5. Triggering a Microsoft Flow.
  6. Include principals (users and groups) in SharePoint roles.

NOTE: For constructing a JSON schema and its valid verbs, you can check the following resources.

Why Use Site Scripts and Site Designs?

  1. Standardization & Consistency
    • Ensures all sites follow the same structure, branding, and compliance requirements.
    • Reduces manual errors by applying predefined settings.
  2. Automation & Efficiency
    • Eliminates repetitive tasks such as manually creating lists, libraries, columns, or permissions.
    • Reduces setup time for new SharePoint sites.
  3. Customization without Custom Code
    • Site Scripts enable customization using JSON, eliminating the need for complex development efforts.
    • It can be enhanced using PnP PowerShellPower Automate, and various other SharePoint automation tools.
  4. Easy Updates & Scalability
    • Site Designs can be updated centrally and re-applied to existing sites.
    • Ideal for large organizations managing multiple SharePoint sites.

Creating a New Site Design and Site Script

Let us develop a new site script and design to enhance our understanding and generate additional ideas regarding the site script and design.

Create a JSON file named "Site-Script.json" and include the following code within it. The code defines five actions: 
  1. The first two actions create site columns.
  2. The third action creates a new content type in the site, named "User," and adds the two previously created site columns to this content type.
  3. The fourth action creates a new list in the SharePoint site, named "User Information," utilizing the newly created content type.
  4. The fifth action creates a new document library in the SharePoint site, named "User Documents", utilizing the created content type.

{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design.json#",
  "actions": [
    {
      "verb": "createSiteColumn", //verb to create SiteColumn
      "fieldType": "Text", //column type you want to create
      "displayName": "First Name", //Column Display Name
      "internalName": "FirstName",//Column Internal Name
      "isRequired": false, 
      "id": "2d738560-6a73-4d1b-854e-8b195f9021eb", //Unique gui-id for your site column you can genrate it manuualy.
      "group": "Test Site Columns" //give group name to identify
    },
    {
      "verb": "createSiteColumn",
      "fieldType": "DateTime",
      "displayName": "Date of Birthday",
      "internalName": "DateOfBirthday",
      "isRequired": false,
      "id": "da840479-d27e-490d-8624-cd1144ee07cc",
      "group": "Test Site Columns"
    },
    {
      "verb": "createContentType", //verb to create content type in site
      "name": "User", //ContentType Name
      "id": "0x0101009D1CB255DA76424F860D91F20E6C411800B609FEFDEFAA484299C6DE254182E666", //Unique content typeID
      "description": "User content type containing personal information",
      "parentId": "0x0101009D1CB255DA76424F860D91F20E6C4118", //Parent content type id
      "hidden": false,
      "subactions": [
        // you can add your site columns as many as you can..
        {
          "verb": "addSiteColumn",
          "internalName": "FirstName"
        },
        {
          "verb": "addSiteColumn",
          "internalName": "DateOfBirthday"
        }
      ]
    },
    {
      "verb": "createList", //Verb for Create a List
      "listType": "GenericList", //List type you want to create Ex:GenericList(CustomList),Document Library,Task List etc...
      "title": "User Information", //Title of your list
      "description": "List to store user personal information.", //Desciption of your list
      "templateType": 100, //Gave templtype for custom list it's 100, for document library it's 101
      "contentTypesEnabled": true, 
      "subactions": [
        {
          "verb": "addContentType",
          "name": "User"
        }
      ]
    },
    {
      //Creates a new Document Library
      "verb": "createList",
      "listType": "DocumentLibrary", //List type Document Library 
      "title": "User Documents", 
      "description": "Library for storing user-related documents.",
      "templateType": 101,
      "contentTypesEnabled": true,
      "subactions": [
        {
          "verb": "addContentType",
          "name": "User"
        }
      ]
    }
  ],
  "version": 1
}
If you want to create a list directly with its columns, you need to add the below JSON schema structure in the site script to accomplish this.

{
  "verb": "createList",
  "listType": "GenericList",
  "title": "User Information",
  "description": "List to store user personal information.",
  "templateType": 100,
  "subactions": [
    {
      "verb": "addField",
      "fieldType": "Text",
      "displayName": "First Name",
      "internalName": "FirstName",
      "isRequired": false
    },
    {
      "verb": "addField",
      "fieldType": "DateTime",
      "displayName": "Date of Birthday",
      "internalName": "DateOfBirthday",
      "isRequired": false
    }
  ]
}

How we can add Taxonomy Fields (Managed Metadata Fields) as Site Columns in Site-Script

In SharePoint, taxonomy fields, also known as managed metadata fields, are used to connect content types and lists with the Term Store. When creating site scripts, you can incorporate taxonomy fields as site columns and attach them to content types. Below is an example of how to construct the JSON schema to create a taxonomy field as a site column and add it to a content type using SharePoint site scripts.

First, you need to create a hidden site column associated with your actual taxonomy field. This column is already created with your managed property when you registered your managed property in the term store. Enter the below JSON schema to add the site column and change the value as per your managed property.

These fields are essential for backend processing, calculations, or metadata purposes but should remain hidden from end-users, especially when utilized for taxonomy management.

{
  "verb": "createSiteColumnXml",
  "schemaXml": "<Field ID=\"{"Unique Field GUID of your Managed Property"}\" Type=\"Note\" Name=\"DegreeTaxnomyField\" StaticName=\"DegreeTaxnomyField\" Group=\"Test Site Columns\" DisplayName=\"DegreeTaxnomyField\" ShowInViewForms=\"FALSE\" Required=\"FALSE\" Hidden=\"TRUE\" CanToggleHidden=\"TRUE\" />"
}
NOTE: Ensure that the Hidden attribute is set to true, and the Field ID matches exactly as it was created in the term store.

As mentioned before, these fields are hidden from the end-user and cannot be seen in the term store anywhere. To find the term's unique field ID, you can acquire it using the below PnP commands.

$adminSite = "https://<<Your-TenantName>>-admin.sharepoint.com"

Connect-PnPOnline -Url $adminSite -UseWebLogin

$TermField = Get-PnPField -Identity "<<Your Term-Name>>"
$fieldID = $TermField.TextField

write-Host "Field Id: $fieldID"
These commands return the Term's Field ID like: "Field Id: 6b9b1fd5-474c-4f08-820c-f1fc4352c1ba"

Now we create the Taxonomy Field Site Column, which we can add as site columns in our content type or anywhere else we choose to use it.
  • To create a taxonomy field as a site column in a site script, you need to define the field’s properties such as the Term Store, Term Set, and whether the field allows multiple selections.
  • Below is an example of creating a TaxonomyFieldType (managed metadata field) as a site column:
{
    "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design.json#",
    "actions": [
        {
            "verb": "createSiteColumnXml",
            "schemaXml": "<Field ID=\"{Random unique Field-ID}\" Type=\"TaxonomyFieldType\" Name=\"Degree\" SourceID=\"http://schemas.microsoft.com/sharepoint/v3\" StaticName=\"Degree\" DisplayName=\"Degree\" Group=\"Test Site Columns\" ShowField=\"Term1033\" Required=\"FALSE\" EnforceUniqueValues=\"FALSE\" Mult=\"TRUE\"> \
      <Default></Default> \
      <Customization> \
          <ArrayOfProperty> \
              <Property> \
                  <Name>SspId</Name> \
                  <Value><<Your TaxonomyStoreSSPID>></Value> \
              </Property> \
              <Property> \
                  <Name>GroupId</Name> \
                  <Value><<Your TermStoreGroupID>></Value> \
              </Property> \
              <Property> \
                  <Name>TermSetId</Name> \
                  <Value><<DegreeTermSetID>></Value> \
              </Property> \
              <Property> \
                  <Name>TextField</Name> \
                  <Value>{<<Your Taxonomy Field ID>>  // same as per the Your Hidden column's FieldID
            }</Value>      
              </Property> \
              <Property> \
                  <Name>AnchorId</Name> \
                  <Value>00000000-0000-0000-0000-000000000000</Value> \
              </Property> \
              <Property> \
                  <Name>IsPathRendered</Name> \
                  <Value>false</Value> \
              </Property> \
              <Property> \
                  <Name>IsKeyword</Name> \
                  <Value>false</Value> \
              </Property> \
              <Property> \
                  <Name>Open</Name> \
                  <Value>false</Value> \
              </Property> \
          </ArrayOfProperty> \
      </Customization> \
  </Field>"
        }
    ]
}
Explanation of the JSON Schema:
  • Type: TaxonomyFieldType – Defines that this field will be used as a managed metadata field.
  • SourceID: Points to the SharePoint schema.
  • ShowField: Defines the language to be used to show the term (e.g., Term1033 for English).
  • Required: If the field is mandatory (FALSE means optional).
  • Mult: Allows multiple terms to be selected from the Term Set (TRUE).
  • Customization: Contains additional configuration for the taxonomy field, such as:
  • SspId: The ID for the taxonomy store.
  • GroupId: The ID of the Term Set group.
  • TermSetId: The ID of the Term Set from the Term Store.
  • TextField: The GUID of the field that will render the term text.
  • IsPathRendered: Whether to show the term path (hierarchy).
  • AnchorId: A default value (usually 00000000-0000-0000-0000-000000000000 for root terms).
  • IsKeyword: Defines whether the term is a keyword.
  • Open: Specifies whether the term set is open.
This is how we can create our site script with desired Content Types, Ste Columns, Predefined List Configurations, Document Libraries, and much more.

Now, we'll deploy our JSON Schema as a site script for our SharePoint tenant. Please refer to the PnP commands below for more information.

$adminSite = "https://<<Your-TenantName>>-admin.sharepoint.com" #Your Sharepoint admin site URL
$siteScriptFile ="c:\scripts\site-script.json" #File path of JSON file.

Connect-PnPOnline -Url $adminSite -UseWebLogin

$content = [IO.File]::ReadAllText($siteScriptFile)

$SPSiteScript = Add-PnPSiteScript -Content $content -Title "Test Site-Script"

$SiteScriptId = $SPSiteScript.Id

Write-Host "Site-Script ID: $SiteScriptId"
NOTE: Please save the Script ID that we used to create the Site Design.

Now, We create a new site design from the newly created site script. Please refer to the PnP commands below to create the site design.

$adminSite = "https://<<Your-TenantName>>-admin.sharepoint.com" #Your Sharepoint admin site URL

Connect-PnPOnline -Url $adminSite -UseWebLogin

$SiteDesignDetails = Add-PnPSiteDesign -Title $SiteDesignTitle -SiteScriptIds $SPSiteScript.Id -Description $SiteDesignTitle -WebTemplate TeamSite

Write-Host "Site Design is deployed successfully the GUID is:$($SiteDesignDetails.Id)"
NOTE: Please save the Site Design ID that we can use anywhere else.

After creating the site design, we can apply it to any site within our tenant. To do this, we need to run the following command.

$adminSite = "https://<<Your-TenantName>>-admin.sharepoint.com" #Your Sharepoint admin site URL

Connect-PnPOnline -Url $adminSite -UseWebLogin

# Run this Command If Your Site-Script has 30 Or less than 30 Actions
Invoke-PnPSiteDesign -Identity "<<Site-DesigneeID>>" -WebUrl "<<Site url>>"

# Run this Command If Your Site-Script has More than 30 actions
Add-PnPSiteDesignTask -SiteDesignId "<<Site-DesigneeID>>" -WebUrl "<<Site url>>"
NOTE: Execute the command based on the number of actions defined in your site script.

Summary 

This blog post discusses how Site Scripts and Site Designs in SharePoint Online simplify the site provisioning process by automating the creation of lists, libraries, content types, and branding. These tools help maintain consistency and governance across sites. 

 

Site Designs specify the configurations for a site, while Site Scripts—created using JSON—execute specific actions. These actions can include adding site columns, applying themes, and integrating Power Automate. By using these tools, organizations can reduce manual effort, enforce standardization, and achieve customization without the need for complex coding.


If you have any questions you can reach out our SharePoint Consulting team here.

Setting Up a Local Kubernetes Cluster with Minikube.

Kubernetes has become the go-to container orchestration platform for deploying, scaling, and managing applications. However, setting up a full-scale Kubernetes cluster can be complex, especially for local development. That’s where Minikube comes in! Minikube allows you to run a lightweight Kubernetes cluster locally, perfect for development and testing purposes.

In this Blog, I’ll walk through the steps to set up a local Kubernetes cluster using Minikube, ensuring that you can start experimenting with Kubernetes in no time.


What is Minikube?

Minikube is a tool that sets up a single-node Kubernetes cluster on your local machine. It supports multiple container runtimes like Docker, containerd, and CRI-O, and it’s an excellent option for developers who want to test Kubernetes deployments before pushing them to production.


Prerequisites

Before we dive into the setup process, you’ll need:

  • A machine with at least 2 CPUs and 2GB of RAM
  • A hypervisor like VirtualBox or Hyper-V (if using Windows)
  • kubectl (Kubernetes CLI tool)
  • Minikube

Step 1: Install Minikube

First, you need to install Minikube on your machine. The installation process varies depending on your operating system. Follow these instructions based on your platform:

For macOS (via Homebrew):

brew install minikube

For Linux (via curl):

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

For Windows (via Chocolatey):

choco install minikube





Step 2: Install kubectl

The Kubernetes command-line tool, kubectl, is essential for interacting with the cluster.

For macOS (via Homebrew):

brew install kubectl

For Linux:

sudo apt-get install -y kubectl

For Windows (via Chocolatey):

choco install kubernetes-cli









Step 3: Start Minikube

Once Minikube is installed, start it with the following command:

minikube start

This command automatically sets up a Kubernetes cluster using the hypervisor installed on your machine (VirtualBox, Hyper-V, Docker, etc.). You can also specify the driver using the --driver flag, like so:

minikube start --driver="ANY REQUIRED"

Note: By default, Minikube will use Docker as the container runtime. If you prefer containerd or CRI-O, you can specify it with the required flag





Step 4: Verify the Setup

After Minikube has started, you can verify that your cluster is running by checking the nodes in the cluster:

kubectl get nodes






Step 5: Deploy an Application on Minikube

A deployment in Kubernetes is a higher-level abstraction that manages the rollout and scaling of applications. It defines how to create and update instances of the application (called pods) consistently across a cluster. Deployments ensure that the desired number of pod replicas are running, and they automatically handle updates, rollbacks, and scaling based on user-defined conditions.

The main purpose of Deployments is because they are essential for handling production workloads and managing containerized apps in a reliable, automated way. This ensures high availability by running multiple instances of an application and scale the application dynamically in response to traffic or resource usage.

Now that Minikube is running, let’s deploy a simple application. We’ll use a sample NGINX deployment to demonstrate.

First, create a Kubernetes deployment:

kubectl create deployment nginx --image=nginx

Verify that the deployment has been created:

kubectl get deployments





Step 6: Expose the Application

By default, the NGINX deployment is not accessible from outside the cluster. To expose it, we’ll create a service:

kubectl expose deployment my-nginx --port=80






Step 7: Access the Application

Now that the service is exposed, you can access the NGINX web server using Minikube’s IP. To get the Minikube IP, run:

minikube ip: 19X.XXX.XXX.XXX:PORT

Combine this IP with the NodePort value from the previous step to access the application in your browser:







Step 8: Stop the Cluster

Once you’re done experimenting, you can stop the Minikube cluster using the following command:

minikube stop

If you want to delete the cluster entirely, run:

minikube delete


Conclusion

Minikube is a fantastic tool for local Kubernetes development, offering a quick and easy way to spin up a local cluster. In this Blog, we went through the setup process, deployed a simple application, and exposed it for external access. Now you can start experimenting with Kubernetes features and workflows in a local environment before deploying them to a production environment.

Start your Kubernetes journey with Minikube today, and happy developing!


Reference Links:

March 6, 2025

Step-by-Step Guide: Building, Integrating, and Deploying a Microsoft Teams Bot Using Visual Studio, OpenAI, and Azure - Part 2


What is a Bot and Its Advantages?
A bot is a software application designed to automate tasks, often simulating human interaction. Bots are widely used in customer support, data retrieval, and task automation, making workflows efficient and reducing manual effort. With advancements in AI, bots can now engage in intelligent conversations and provide personalized assistance.

Advantages of Bots:
  • Efficiency: Automates repetitive tasks, saving time and resources.
  • 24/7 Availability: Provides uninterrupted support to users.
  • Scalability: Handles multiple interactions simultaneously.
  • Cost-Effective: Reduces the need for extensive human resources.

This tutorial is part of a series. To understand it fully, make sure to check out Part 1: Azure Configuration for Your Bot.

  1. Add the Bot Framework v4 SDK Templates to Visual Studio.
  2. Bot Framework SDK(Software Development Kit): This SDK provides essential tools and configurations for building bots. Visual Studio makes it easy to integrate and manage your bot's development.|

    1. Click on the 'Download' link to open the Bot Framework v4 SDK page.
    2. Once the page opens, find the green "Download" button.
    3. Click the green button to download the Bot SDK. 
    4. After the download is complete, install the SDK on your system.


    5. This template includes default bot configurations, making it easier to get started with your bot development.


  3. Create an Echo Bot Solution in Visual Studio.
    1. Open Visual Studio and choose "Create a new project.
    2. Search bar in search ‘bot’. 
    3. Select template  ‘Echo Bot (Bot Framework V4) 


    4. Add a Project name and create a project.



  4. Configure the OpenAI API in the Echo Bot Solution.
    • Add Dependencies: Install the System.Net.Http and Newtonsoft.Json packages via NuGet for handling HTTP requests and JSON.
    • Implement the ChatGPT Service: 
      1. Go to solution explore and Open file EchoBot.cs
      2. Add a new method in the following code to interact with the OpenAI API
        // New method to implement for retrieving OpenAI API responses and  returning them in the
        //proper format

         private async Task<string> GPTResponseAsync(string userQuery)
         {
            // API key for accessing Azure OpenAI service (replace this with your actual key)
            string apiKey = "API_KEY";
         
            // Endpoint URL of the Azure OpenAI deployment with the correct API version
            string endPoint = "AZURE_API";
         
            // Creating an HttpClient to send HTTP requests to the API
            var client = new HttpClient();
         
            // Preparing an HTTP POST request with the specified endpoint
            var request = new HttpRequestMessage(HttpMethod.Post, endPoint);
         
            // Adding the API key to the request header for authentication
            request.Headers.Add("api-key", apiKey);
         
            // Constructing the request body in JSON format
            // - `messages`: Contains the conversation with roles (`system`, `user`, `assistant`)
            // - `max_tokens`: Defines the maximum response length
            // - `temperature`: Controls the randomness of the response (higher values make output
            //    more creative)
            // - `top_p`, `frequency_penalty`, `presence_penalty`: Other parameters to fine-tune
            //    the response generation
             var content = new StringContent($@"{{
             ""messages"": [{{
               ""role"": ""system"",
               ""content"": ""You are an AI assistant designed to help people discover information.""
             }}, {{
               ""role"": ""user"",
               ""content"": ""{userQuery}""
             }}, {{
               ""role"": ""assistant"",
               ""content"": ""Hello! How can I assist you today?""
             }}],
             ""max_tokens"": 800,
             ""temperature"": 0.7,
             ""frequency_penalty"": 0,
             ""presence_penalty"": 0,
             ""top_p"": 0.95,
             ""stop"": null
           }}", null, "application/json");
         
            // Setting the content of the request to the JSON string prepared above
            request.Content = content;
         
            // Sending the request asynchronously and awaiting the response
            var response = await client.SendAsync(request);
         
            // Ensuring the response status code is successful (2xx), throwing an error if not
            response.EnsureSuccessStatusCode();
         
            // Reading the response content as a string
            var result = await response.Content.ReadAsStringAsync();

            // Parsing the result string into a JSON object    
            var resultObject = JObject.Parse(result);      

            // Returning the assistant's response from the JSON object    
             return Convert.ToString(resultObject["choices"][0]["message"]["content"]);
         }
        Note:
         Please double-check your API and API key to ensure they are working. (This code uses the Azure OpenAI API.)

    • Integrate ChatGPT with the Bot: 
      1. In your bot's main dialogue or message handler (e.g., EchoBot.cs), integrate the ChatGPT service: 
      2. Method Purpose: This method is triggered whenever a user sends a message in the conversation (e.g., in Microsoft Teams). It takes the message, forwards it to OpenAI's GPT API, and sends the response back to the user.
      3. TurnContext: This object contains all the relevant details about the conversation, including the message sent by the user. turnContext.Activity.Text gets the message text that the user sent. 
      4. GPTResponseAsync: The method sends the user's message to the GPT model hosted on Azure OpenAI and waits for the AI's response. It returns the response, which will be sent back to the user. 
      5. MessageFactory.Text: This creates a new message to be sent back to the user. The same text is passed twice; the first parameter is what will be displayed, and the second is for any formatting or processing. 
      6. CancellationToken: This parameter is used to manage the cancellation of asynchronous tasks. It ensures that the operation can be cancelled if needed without blocking the application. 
          protected override async Task OnMessageActivityAsync(
            ITurnContext<IMessageActivity> turnContext,
             CancellationToken cancellationToken)
         {
             //var replyText = $"Echo: {turnContext.Activity.Text}";
             var gptResponse = await GPTResponseAsync(turnContext.Activity.Text);
             await turnContext.SendActivityAsync(
                    MessageFactory.Text(gptResponse, gptResponse),
                    cancellationToken);
         }


  5. Test the Bot Locally in BotFramework-Emulator.
    1.  Go to the following link to directly 'download' BotFramework-Emulator exe file.
    2. Once the Bot Framework Emulator is downloaded, install it.
    3. Run your Project When successfully running the solution open the Bot window and copy the URL. 

    4. Open the Emulator > “Open Bot” > set your URL plus “api/messages” > Connect

    5. Test your bot.



  6. Deploy the Bot to Azure App Service.
    • Prerequisite
      • Azure Tenant ID
      • MicrosoftAppId
      • MicrosoftAppPassword

    1. Azure Tenant ID: Azure Portal > Azure Active Directory > Overview > Directory ID (copy this value)
    2. Microsoft App ID: Azure Portal > All services > Bot Services (or Azure Bot) > [Your Bot] > Settings > Microsoft App ID (copy this value)
    3. Microsoft App Password: Azure Portal > All services > Bot Services (or Azure Bot) > [Your Bot] > Settings > Manage > Certificates & secrets > New client secret > Add (copy the value of the newly created client secret)
    4. Open the Visual Studio solution(6) for your Echo Bot and navigate to the appsettings.json file. Add the following configuration (paste the IDs)


    5. Visual Studio > Solution Explorer > Right-click on your project > Publish > Add New Profile > Azure 


    6. Sign in to Azure (if required) and select Created app service for the bot. then Finish

    7. Click on 'Publish' to deploy the app to Azure App Service.

  7. Create a manifest.json for Microsoft Teams.
    1. Create a new file named manifest.json in your project folder.
    2. Add the following basic structure to your manifest.json file: Need more information click manifest.json

          {
              "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
              "manifestVersion": "1.16",
              "version": "1.0.9",
              "id": "<YOUR_TEAMS_APP_ID>",
              "packageName": "com.microsoft.teams.extension",
              "developer": {
                  "name": "Teams App, Inc.",
                  "websiteUrl": "<YOUR_WEBSITE_URL>",
                  "privacyUrl": "<YOUR_WEBSITE_URL>",
                  "termsOfUseUrl": "<YOUR_WEBSITE_URL>"
              },
              "icons": {
                  "color": "color.png",
                  "outline": "outline.png"
              },
              "name": {
                  "short": "Gangbox ChatBot",
                  "full": "Gangbox ChatBot"
              },
              "description": {
                  "short": "This is AI Chatbot.",
                  "full": "This is AI Chatbot."
              },
              "accentColor": "#FFFFFF",
              "bots": [
                  {
                      "botId": "<YOUR_TEAMS_APP_ID>",
                      "scopes": [
                          "personal",
                          "team",
                          "groupchat"
                      ],
                      "supportsFiles": false,
                      "isNotificationOnly": false,
                      "commandLists": [
                          {
                              "scopes": [
                                  "personal",
                                  "team",
                                  "groupchat"
                              ],
                              "commands": [
                                  {
                                      "title": "welcome",
                                      "description": "Resend welcome card of this Bot"
                                  },
                                  {
                                      "title": "learn",
                                      "description": "Learn about Adaptive Card and Bot Command"
                                  }
                              ]
                          }
                      ]
                  }
              ],
              "composeExtensions": [],
              "configurableTabs": [],
              "staticTabs": [],
              "permissions": [
                  "identity",
                  "messageTeamMembers"
              ],
              "validDomains": []
          }
         

    3. Replace Placeholders
      • id: Your bot's Microsoft App ID.
      • developer: Fill in details about your name/company and URLs for your website, privacy policy, and terms of use.
      • botId: The same as your Microsoft App ID.
      • icons: Add the paths to your bot's icon images (color and outline versions).

        Add two images (icon files) in your folder:
        - color.png (192x192 pixels)
        - outline.png (32x32 pixels)

    4. Compress Files into a Zip
      Include the following files in a zip file:
      - manifest.json
      - color.png
      - outline.png

      The zip file will be your Teams app package.



  8. Add the App to Microsoft Teams.
    1. Go to Microsoft Teams > Apps > Upload a custom app > Upload for me or my teams.



    2. Upload your .zip file, and your bot will be added to Microsoft Teams.

    Thank you for reading! We hope this guide helped you successfully configure your bot. Feel free to share your thoughts or questions in the comments below!

    If you have any questions you can reach out our SharePoint Consulting team here.