-
Notifications
You must be signed in to change notification settings - Fork 198
{Debug} Teams Toolkit VS Code Tasks
A Teams Toolkit generated project has pre-defined a set of VS Code tasks in its .vscode/tasks.json
. These tasks are for debugging and have corresponding arguments as inputs. This page shows the details about how these tasks are defined and how to customize with your own args.
Note: these tasks are generated by Teams Toolkit (>= 4.1.0). To use these tasks in old Teams Toolkit project, see Upgrade section.
Aligning with the official VS Code schema, the tasks.json
contains tasks
top-level properties, which defines all the tasks and execution sequence used by Teams Toolkit. Following shows the summary of those pre-defined tasks:
Task Label (Type:Command) |
Description |
---|---|
Start Teams App Locally | The entry task of debug, to be referenced by launch.json . |
Validate & Install prerequisites (teamsfx:debug-check-prerequisites) |
Check and auto-resolve prerequisites required by debugging. |
Install NPM packages (teamsfx:debug-npm-install) |
NPM install for each sub-project. |
Install Azure Functions binding extensions (shell:dotnet ...) |
Install extension for Azure Functions sub-project. |
Start local tunnel (teamsfx:debug-start-local-tunnel) |
Start local tunneling for bot sub-project. |
Set up tab (teamsfx:debug-set-up-tab) |
Prepare local launch information for Tab. |
Set up bot (teamsfx:debug-set-up-bot) |
Register resources and prepare local launch information for Bot. |
Set up SSO (teamsfx:debug-set-up-sso) |
Register resources and prepare local launch information for SSO functionality. |
Build & Upload Teams manifest (teamsfx:debug-prepare-manifest) |
Build then upload Teams App manifest. |
Start services (shell:npm run ...) |
Launch all local services. |
Note: Depend on your project type, your
tasks.json
may contain a subset of above tasks.For customization, all teamsfx:debug- tasks contain
args
as inputs. See each section of task definition about theargs
schema.
This sections shows the details of each task.
This task is the entry point of all other tasks. It represents the full flow to launch Teams app locally. If you'd like to skip any step(s), just comment it out, e.g.,
{
"label": "Start Teams App Locally",
"dependsOn": [
"Validate & Install prerequisites",
//// comment out any step(s) you'd like to skip
// "Install NPM packages",
"Install Azure Functions binding extensions",
"Start local tunnel",
"Set up Tab",
"Set up Bot",
"Set up SSO",
"Build & Upload Teams manifest",
"Start services"
],
"dependsOrder": "sequence"
}
This task is to validate and install prerequisites that will be used in followed debug steps. If you'd like to skip checking any prerequisite(s), just comment it out.
Arguments | type | required | description |
---|---|---|---|
prerequisites | array | required | The enabled prerequisite checkers. Checkers: nodejs, m365Account, devCert, func, ngrok, dotnet, portOccupancy |
portOccupancy | array | required | The ports to check if they are in use. |
prerequisites | description |
---|---|
nodejs | Validate if Node.js is installed. |
m365Account | Sign-in prompt for Microsoft 365 account, then validate if the account enables the sideloading permission. |
devCert | Install localhost SSL certificate. It's used to serve the development sites over HTTPS to debug the Tab app in Teams. |
func | Install Azure Functions Core Tools. It's used to serve Azure Functions hosted project locally. |
ngrok | Install Ngrok. Bot project requires a public message endpoint, and ngrok can help create public tunnel for your local service. |
dotnet | Ensure .NET Core SDK is installed. TeamsFx Azure Functions project depends on extra .NET binding extensions for HTTP trigger authorization. |
portOccupancy | Validate available ports to ensure those debug ones are not occupied. |
Note: Teams Toolkit downloads npm package ngrok@4.3.3 which contains NGROK v2.3.40. Customer must have a valid license to use NGROK software. Microsoft does not license use of the NGROK.
{
"label": "Validate & Install prerequisites",
"type": "teamsfx",
"command": "debug-check-prerequisites",
"args": {
"prerequisites": [
"nodejs",
"m365Account",
"func",
//// comment out any checker(s) you'd like to skip
// "ngrok",
"portOccupancy"
],
"portOccupancy": [
53000, // tab service port
3978, // bot service port
//// add or update your own port(s) to be validated
// 9239, // bot debug port
2233
]
}
},
For newly created project, there may be following ports to be validated:
- 53000: the default port for local tab service
- 3978: the default port for local bot service
- 9239: the default debugger port for local bot service
- 7071: the default port for local api/backend service
- 9229: the default debugger port for local api/backend service
- 4321: the default port for local SPFx service
This task is to install npm packages for all sub projects.
Arguments | Type | Required | Description |
---|---|---|---|
projects | array | required | The configuration for each subproject. |
forceUpdate | boolean | optional | Default: false. false: only install when dependency changes. true: always run npm install script. |
projects | Type | Required | Description |
---|---|---|---|
npmInstallArgs | array | optional | The args of the npm install command. e.g. ["--no-audit"] means execute the npm install --no-audit command. |
cwd | string | required | Target folder. |
{
"label": "Install NPM packages",
"type": "teamsfx",
"command": "debug-npm-install",
"args": {
"projects": [
{
"cwd": "${workspaceFolder}/tabs",
"npmInstallArgs": [
"--no-audit",
// use your own npm install args
"--registry=https://my-npm-reg/..."
]
},
{
"cwd": "${workspaceFolder}/bot",
"npmInstallArgs": ["--no-audit"]
}
],
"forceUpdate": false
}
}
This task is to install TeamsFx Azure Functions binding extensions for your backend API project. It's a VS Code built-in shell
task so you can follow the VS Code doc to customize your own options.
{
"label": "Install Azure Functions binding extensions",
"type": "shell",
"command": "dotnet extensions.csproj -o ./bin --ignore-failed-sources",
"options": {
"cwd": "${workspaceFolder}/api",
"env": {
"PATH": "${command:fx-extension.get-dotnet-path}${env:PATH}"
}
},
"presentation": {
"reveal": "silent"
}
}
Note: the
${command:fx-extension.get-dotnet-path}
variable reference is to get dotnet path installed by Teams Toolkit (from the Validate & Install prerequisites task).
This task is to start local tunnel service (ngrok) to make your local bot message endpoint public.
Arguments | Type | Required | Description |
---|---|---|---|
ngrokArgs | string or string[] | required | The ngrok command line arguments to start the tunnel. Full references can be found in ngrok document. |
tunnelInspection | string | optional | Teams Toolkit tries to get tunnel public URL from ngrok log first, then the first PublicURL via default inspection "http://127.0.0.1:4040/api/tunnels". If you specify your own ngrokArgs with different log format or inspection, set this arg to provide your own inspection location. |
1. The default one used by TeamsFx templates. Teams Toolkit installs its own ngrok binary and start tunnel with command ngrok http 3978 --log=stdout --log-format=logfmt
.
{
"label": "Start local tunnel",
"type": "teamsfx",
"command": "debug-start-local-tunnel",
"args": {
"ngrokArgs": "http 3978 --log=stdout --log-format=logfmt",
},
"isBackground": true,
"problemMatcher": "$teamsfx-local-tunnel-watch"
},
2. Change port. To use another port for local bot service (e.g., 3922), you can change the one in ngrokArgs
. Note that you also need to change the port in bot code (index.js
or index.ts
).
{
"label": "Start local tunnel",
"type": "teamsfx",
"command": "debug-start-local-tunnel",
"args": {
// change port here
"ngrokArgs": "http 3922 --log=stdout --log-format=logfmt",
},
"isBackground": true,
"problemMatcher": "$teamsfx-local-tunnel-watch"
},
3. Use your own ngrok command or config. If you'd like to use your own ngork command (e.g., ngrok start
) or config (e.g., any-ngrok.yml
) for advances usages. Note that if you change the log format or set your own inspect path, you need to provide tunnelInspection
as well.
{
"label": "Start local tunnel",
"type": "teamsfx",
"command": "debug-start-local-tunnel",
"args": {
// change the command here
"ngrokArgs": "start --config any-ngrok.yml",
// to let Teams Toolkit know your ngrok endpoint
"tunnelInspection": "http://127.0.0.1:4040/api/tunnels",
},
"isBackground": true,
"problemMatcher": "$teamsfx-local-tunnel-watch"
},
4. Use your own ngrok binary.
Start your own ngrok with command ngrok http 3978
in the terminal and set the ngrok endpoint into the botMessagingEndpoint
.
{
"label": "Start Teams App Locally",
"dependsOn": [
...
// Remove/Comment out tunnel task
//"Start local tunnel",
"Set up bot",
...
],
"dependsOrder": "sequence"
},
...
{
"label": "Set up bot",
"type": "teamsfx",
"command": "debug-set-up-bot",
"args": {
...
// tell Teams Toolkit your message endpoint
"botMessagingEndpoint": "https://sample-id.ngrok.io/api/messages",
}
},
5. Totally get rid of ngrok. If your dev environment does not support ngrok or you'd like to use your own tunnel solution, you can skip/remove this tunnel task and just let Teams Toolkit know your message endpoint.
Alternative | Description |
---|---|
Cloud VM | Develop your project on cloud VM (e.g., Azure VMs or Azure DevTest Labs). You can choose either to still use ngrok on your cloud VM, or to directly expose your bot service via VM's public hostname and port. |
localtunnel | An alternative tunnel solution. You can install and run localtunnel instead of ngrok . |
{
"label": "Start Teams App Locally",
"dependsOn": [
...
// Remove/Comment out tunnel task
//"Start local tunnel",
"Set up bot",
...
],
"dependsOrder": "sequence"
},
...
{
"label": "Set up bot",
"type": "teamsfx",
"command": "debug-set-up-bot",
"args": {
...
// tell Teams Toolkit your message endpoint
"botMessagingEndpoint": "https://you-bot-host/api/messages",
}
},
This task is to prepare local launch information for Tab.
Arguments | Type | Required | Description |
---|---|---|---|
baseUrl | string | required | The base url that the Tab app will be hosted on. |
{
"label": "Set up Tab",
"type": "teamsfx",
"command": "debug-set-up-tab",
"args": {
"baseUrl": "https://localhost:53000"
//// or use your own local port
// "baseUrl": "https://localhost:23000",
}
}
This task is to register resources and prepare local launch information for Bot.
Arguments | Type | Required | Description |
---|---|---|---|
botId | string | optional | The Microsoft Entra app client id for bot. Set this argument to use an existing bot. |
botPassword | string | optional | The Microsoft Entra app client secret for bot. Set this argument to use an existing bot. |
botMessagingEndpoint | string | required | The bot messaging endpoint. If without hostname (e.g., api/messages), Teams Toolkit uses the ngrok host from Start Local Tunnel task. If with hostname (e.g., https://contoso.com/api/messages), Teams Toolkit uses the provided full URL. |
{
"label": "Set up Bot",
"type": "teamsfx",
"command": "debug-set-up-bot",
"args": {
//// Use your own Microsoft Entra App for bot
// "botId": "",
// "botPassword": "", // use plain text or environment variable reference like ${env:BOT_PASSWORD}
"botMessagingEndpoint": "api/messages"
}
}
This task is to register resources and prepare local launch information for SSO functionality.
Arguments | Type | Required | Description |
---|---|---|---|
clientId | string | optional | The Microsoft Entra app client id for SSO. Set this argument to use an existing Microsoft Entra App. |
clientSecret | string | optional | The Microsoft Entra app client secret for SSO. Set this argument to use an existing Microsoft Entra App. |
objectId | string | optional | The Microsoft Entra app object id for SSO. Set this argument to use an existing Microsoft Entra App. |
accessAsUserScopeId | string | optional | The Microsoft Entra app access_as_user scope id for SSO. Set this argument to use an existing Microsoft Entra App. |
{
"label": "Set up SSO",
"type": "teamsfx",
"command": "debug-set-up-sso",
"args": {
//// Use your own Microsoft Entra App for SSO
// "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
// "clientSecret": "plain-text or ${env:YOUR_CLIENT_SECRET}",
// "objectId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
// "accessAsUserScopeId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
}
}
This task is to build then upload Teams App manifest. If you specfic your own app package path, it skips building package but directly upload your own package.
Argument | Type | Required | Description |
---|---|---|---|
appPackagePath |
string | optional | Teams app package path. If undefined, Teams Toolkit will build and upload the manifest according to the template in templates/appPackage/manifest.template.json . If the value is a .zip file path, Teams Toolkit will upload the Teams app package without building. |
{
"label": "Build & Upload Teams manifest",
"type": "teamsfx",
"command": "debug-prepare-manifest",
"args": {
//// Enter your own Teams app package path if using the existing Teams manifest. ////
// "appPackagePath": "/path/to/your/appPackage.zip"
}
}
These tasks are standard VS Code shell tasks to execute npm commands on sub-projects, following the official schema defined by VS Code. For example,
-
command
defines the shell command to be executed -
isBackground: true
means the task keeps running in the background -
problemMatcher
is used to capture the begin/end or any problem from the task output
{
"label": "Start services",
"dependsOn": [
"Start frontend",
"Start backend",
"Start bot"
]
},
{
"label": "Start frontend",
"type": "shell",
"command": "npm run dev:teamsfx",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/tabs"
},
"problemMatcher": {
"pattern": {
"regexp": "^.*$",
"file": 0,
"location": 1,
"message": 2
},
"background": {
"activeOnStart": true,
"beginsPattern": ".*",
"endsPattern": "Compiled|Failed"
}
}
},
{
"label": "Start backend",
"type": "shell",
"command": "npm run dev:teamsfx",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/api",
"env": {
"PATH": "${command:fx-extension.get-func-path}${env:PATH}"
}
},
"problemMatcher": {
"pattern": {
"regexp": "^.*$",
"file": 0,
"location": 1,
"message": 2
},
"background": {
"activeOnStart": true,
"beginsPattern": "^.*(Job host stopped|signaling restart).*$",
"endsPattern": "^.*(Worker process started and initialized|Host lock lease acquired by instance ID).*$"
}
},
"presentation": {
"reveal": "silent"
}
},
{
"label": "Start bot",
"type": "shell",
"command": "npm run dev:teamsfx",
"isBackground": true,
"options": {
"cwd": "${workspaceFolder}/bot"
},
"problemMatcher": {
"pattern": {
"regexp": "^.*$",
"file": 0,
"location": 1,
"message": 2
},
"background": {
"activeOnStart": true,
"beginsPattern": "[nodemon] starting",
"endsPattern": "app listening to|Bot/ME service listening at|[nodemon] app crashed"
}
},
"presentation": {
"reveal": "silent"
}
}
Both old tasks and new tasks define the same F5 flow, so it's easy to upgrade old tasks to new tasks - just replace old task with the equivalent new task(s).
For quick replacement, here are tasks.json
samples that you can directly reference to overwrite the existing one.
Project Type | Project Language (JavaScript) |
Project Language (TypeScript) |
---|---|---|
Tab
|
tasks.json | tasks.json |
Tab
|
tasks.json | tasks.json |
Bot
|
tasks.json | tasks.json |
Bot
|
tasks.json | tasks.json |
SPFx | tasks.json | tasks.json |
Or, if you'd like to replace partial tasks, follow this mapping between old tasks and new tasks:
Old Task | New Task(s) |
---|---|
validate local prerequisites |
|
start ngrok | |
prepare local environment |
|
Note: After replacing these tasks, update the entry task's
dependsOn
property to use new tasks as well. E.g.,{ "version": "2.0.0", "tasks": [ { "label": "Pre Debug Check & Start All", "dependsOn": [ //// remove the old ones // "validate local prerequisites", // "prepare local environment", //// add new ones "Validate & install prerequisites", "Install npm packages", // "Start local tunnel", "Set up tab", // "Set up bot", // "Set up SSO", "Build & upload Teams manifest", "Start All" ], "dependsOrder": "sequence" }, ...
Or, if your project structure did not change too much, you can create a new empty project with all your features/components, and replace the whole .vscode/tasks.json
file with the newly generated one. (Since the entry task label changes, you will need to update "preLaunchTask" property in .vscode/launch.json
as well.)
For frontend:
- Change
portOccupancy
argument inValidate & Install prerequisites
task. - Set
baseUrl
argument inSet up tab
task.
For bot:
- Set the port value in bot service code or set the port environment variable in
bot/.env.teamsfx.local
. - Change
portOccupancy
argument inValidate & Install prerequisites
task. - Change
ngrokArgs
argument inStart local tunnel
task.
For backend:
- Set the port value in the start script in
api/package.json
. - Change
portOccupancy
argument inValidate & Install prerequisites
task. - If SSO is enabled, set the
REACT_APP_FUNC_ENDPOINT
environment variable intabs/.env.teamsfx.local
, and set theAPI_ENDPOINT
environment variable inapi/.env.teamsfx.local
. - If SSO is enabled and bot is included, set the
API_ENDPOINT
environment variable inbot/.env.teamsfx.local
.
For SPFx:
- Change the port value in
SPFx/config/serve.json
- Change
portOccupancy
argument inValidate & Install prerequisites
task. - Change the
staticTabs.contentUrl
andconfigurableTabs.configurationUrl
arguments intemplates/appPackage/manifest.template.json
.
- Set
objectId
,clientId
,clientSecret
andaccessAsUserScopeId
arguments inSet up SSO
task. ForclientSecret
, use plain text or environment variable reference like${env:CLIENT_SECRET}
. - If bot is included, set the
M365_CLIENT_SECRET
environment variable inbot/.env.teamsfx.local
. - If backend is included, set the
M365_CLIENT_SECRET
environment variable inapi/.env.teamsfx.local
.
- Set
botId
andbotPassword
arguments inSet up bot
task.
- Remove
Start local tunnel
dependency fromStart Teams App Locally
task. - Remove
ngrok
option inprerequisites
argument inValidate & install prerequisites
task. - Set the
botMessagingEndpoint
argument inSet up bot
task.
If the package manager is yarn, PNPM or other tools, user can use a self-defined task instead.
{
"label": "install packages",
"type": "shell",
"command": "yarn"
"options": {
"cwd": "${workspaceFolder}"
}
}
Build Custom Engine Copilots
- Build a basic AI chatbot for Teams
- Build an AI agent chatbot for Teams
- Expand AI bot's knowledge with your content
Scenario-based Tutorials
- Send notifications to Teams
- Respond to chat commands in Teams
- Respond to card actions in Teams
- Embed a dashboard canvas in Teams
Extend your app across Microsoft 365
- Teams tabs in Microsoft 365 and Outlook
- Teams message extension for Outlook
- Add Outlook Add-in to a Teams app
App settings and Microsoft Entra Apps
- Manage Application settings with Teams Toolkit
- Manage Microsoft Entra Application Registration with Teams Toolkit
- Use an existing Microsoft Entra app
- Use a multi-tenant Microsoft Entra app
Configure multiple capabilities
- How to configure Tab capability within your Teams app
- How to configure Bot capability within your Teams app
- How to configure Message Extension capability within your Teams app
Add Authentication to your app
- How to add single sign on in Teams Toolkit for Visual Studio Code
- How to enable Single Sign-on in Teams Toolkit for Visual Studio
Connect to cloud resources
- How to integrate Azure Functions with your Teams app
- How to integrate Azure API Management
- Integrate with Azure SQL Database
- Integrate with Azure Key Vault
Deploy apps to production