向 Teams 应用添加消息扩展功能
消息扩展允许用户在 Microsoft Teams 中撰写消息时与 Web 服务进行交互。 用户可以从邮件撰写框或搜索栏调用 Web 服务来协助邮件撰写。
消息扩展基于 Teams 中的 Bot Framework 体系结构构建。 有关详细信息,请参阅 生成消息扩展。
先决条件
若要在应用中配置消息扩展功能,请确保满足以下先决条件:
- Teams 应用及其清单 (以前称为 Teams 应用清单) 文件
- Microsoft 365 帐户 来测试应用
- Microsoft Azure 帐户
向 Teams 应用添加消息扩展
若要向选项卡应用添加消息扩展,请执行以下步骤:
使用 Microsoft Teams 工具包创建消息扩展应用
若要使用 Teams 工具包创建消息扩展应用,请参阅 使用 Teams 工具包创建消息扩展应用。
在应用清单中配置消息扩展
可以在 文件中配置消息扩展功能 appPackage/manifest.json
。 有关详细信息,请参阅 应用清单架构。
以下代码片段是一个示例:
"composeExtensions": [
{
"botId": "${{BOT_ID}}",
"commands": [
{
"id": "createCard",
"context": [
"compose"
],
"description": "Command to run action to create a Card from Compose Box",
"title": "Create Card",
"type": "action",
"parameters": [
{
"name": "title",
"title": "Card title",
"description": "Title for the card",
"inputType": "text"
},
{
"name": "subTitle",
"title": "Subtitle",
"description": "Subtitle for the card",
"inputType": "text"
},
{
"name": "text",
"title": "Text",
"description": "Text for the card",
"inputType": "textarea"
}
]
},
{
"id": "shareMessage",
"context": [
"message"
],
"description": "Test command to run action on message context (message sharing)",
"title": "Share Message",
"type": "action",
"parameters": [
{
"name": "includeImage",
"title": "Include Image",
"description": "Include image in Hero Card",
"inputType": "toggle"
}
]
},
{
"id": "searchQuery",
"context": [
"compose",
"commandBox"
],
"description": "Test command to run query",
"title": "Search",
"type": "query",
"parameters": [
{
"name": "searchQuery",
"title": "Search Query",
"description": "Your search query",
"inputType": "text"
}
]
}
],
"messageHandlers": [
{
"type": "link",
"value": {
"domains": [
"*.botframework.com"
]
}
}
]
}
]
将消息扩展代码添加到项目
在 Visual Studio Code 中的选项卡项目中创建一个
bot/
文件夹。 将邮件扩展应用的源代码复制到 文件夹中。 项目的文件夹结构如下所示:|--.vscode/ |--appPackage/ |--env/ |--infra/ |--public/ |--bot/ <!--message extension source code--> | |--index.ts | |--config.ts | |--teamsBot.ts | |--package.json | |--tsconfig.json | |--web.config | |--.Webappignore |--src/ <!--your current source code--> | |--app.ts | |--static/ | |--views/ |--package.json |--tsconfig.json |--teamsapp.local.yml |--teamsapp.yml
按如下所示重新组织文件夹结构:
提示
使用 命令
npm init -y
创建根package.json
文件。|--.vscode/ |--appPackage/ |--env/ |--infra/ |--bot/ <!--message extension source code--> |--index.ts | |--config.ts | |--teamsBot.ts | |--package.json | |--tsconfig.json | |--web.config | |--.Webappignore |--tab/ <!--move your current source code to a new sub folder--> | |--src/ | | |--app.ts | | |--static/ | | |--views/ | |--package.json | |--tsconfig.json |--package.json <!--root package.json--> |--teamsapp.local.yml |--teamsapp.yml
将以下代码添加到根
package.json
:"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "install:bot": "cd bot && npm install", "install:tab": "cd tab && npm install", "install": "concurrently \"npm run install:bot\" \"npm run install:tab\"", "dev:bot": "cd bot && npm run dev", "start:tab": "cd tab && npm run start", "build:tab": "cd tab && npm run build", "build:bot": "cd bot && npm run build", "build": "concurrently \"npm run build:tab\" \"npm run build:bot\"" }, "dependencies": { "concurrently": "^7.6.0" },
注意
在 JavaScript 项目中,可以在没有文件夹的情况下
build
运行项目。 必须删除脚本并将build:bot
脚本更新build
为npm run build:tab
。
设置本地调试环境
更新
.vscode/tasks.json
如下:- 添加三个新任务:
Start local tunnel
、Start bot
和Start frontend
。 - 更新
Start application
任务的dependsOn
数组以包括Start bot
和Start frontend
。 -
cwd
配置Start bot
和Start frontend
的选项。 需要此操作,因为之前已在重新组织文件夹结构时将选项卡和机器人的代码移到其各自的文件夹中。 - 将 添加到
Start local tunnel
Start Teams App Locally
任务的dependsOn
数组。
"tasks":[ { // Start the local tunnel service to forward public URL to local port and inspect traffic. // See https://aka.ms/teamsfx-tasks/local-tunnel for the detailed args definitions. "label": "Start local tunnel", "type": "teamsfx", "command": "debug-start-local-tunnel", "args": { "type": "dev-tunnel", "ports": [ { "portNumber": 3978, "protocol": "http", "access": "public", "writeToEnvironmentFile": { "endpoint": "BOT_ENDPOINT", // output tunnel endpoint as BOT_ENDPOINT "domain": "BOT_DOMAIN" // output tunnel domain as BOT_DOMAIN } } ], "env": "local" }, "isBackground": true, "problemMatcher": "$teamsfx-local-tunnel-watch" }, { "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": "restify listening to|Bot/ME service listening at|[nodemon] app crashed" } } }, { "label": "Start frontend", "type": "shell", "command": "npm run dev:teamsfx", "isBackground": true, "options": { "cwd": "${workspaceFolder}/tab" }, "problemMatcher": { "pattern": { "regexp": "^.*$", "file": 0, "location": 1, "message": 2 }, "background": { "activeOnStart": true, "beginsPattern": ".*", "endsPattern": "listening to|Compiled|Failed|compiled|failed" } } }, { "label": "Start application", "dependsOn": [ "Start bot", "Start frontend" ] }, { "label": "Start Teams App Locally", "dependsOn": [ "Validate prerequisites", "Start local tunnel", "Provision", "Deploy", "Start application" ], "dependsOrder": "sequence" }, ]
- 添加三个新任务:
在
teamsapp.local.yml
文件下:- 在 下
provision
,添加botAadApp/create
和botFramework/create
操作。 - 在 下
deploy
,更新操作的代码file/createOrUpdateEnvironmentFile
。
provision: - uses: botAadApp/create with: # The Microsoft Entra application's display name name: bot-${{TEAMSFX_ENV}} writeToEnvironmentFile: # The Microsoft Entra application's client id created for bot. botId: BOT_ID # The Microsoft Entra application's client secret created for bot. botPassword: SECRET_BOT_PASSWORD # Create or update the bot registration on dev.botframework.com - uses: botFramework/create with: botId: ${{BOT_ID}} name: bot messagingEndpoint: ${{BOT_ENDPOINT}}/api/messages description: "" channels: - name: msteams deploy: - uses: file/createOrUpdateEnvironmentFile # Generate runtime environment variables with: target: ./tab/.localConfigs envs: BROWSER: none HTTPS: true PORT: 53000 SSL_CRT_FILE: ${{SSL_CRT_FILE}} SSL_KEY_FILE: ${{SSL_KEY_FILE}} - uses: file/createOrUpdateEnvironmentFile # Generate runtime environment variables with: target: ./bot/.localConfigs envs: BOT_ID: ${{BOT_ID}} BOT_PASSWORD: ${{SECRET_BOT_PASSWORD}}
有关详细信息,请参阅 示例应用。
- 在 下
在 “运行和调试”下,选择“ 调试 (Edge) ”或“调试 (Chrome) ”。
选择 F5 键在本地调试和预览 Teams 应用。
将应用预配到 Azure
复制 文件夹,
botRegistration/
并在 下infra/
添加 。将以下代码添加到
azure.bicep
文件:param resourceBaseName2 string param webAppName2 string = resourceBaseName2 @maxLength(42) param botDisplayName string @description('Required when create Azure Bot service') param botAadAppClientId string @secure() @description('Required by Bot Framework package in your bot project') param botAadAppClientSecret string resource webApp2 'Microsoft.Web/sites@2021-02-01' = { kind: 'app' location: location name: webAppName2 properties: { serverFarmId: serverfarm.id httpsOnly: true siteConfig: { alwaysOn: true appSettings: [ { name: 'WEBSITE_RUN_FROM_PACKAGE' value: '1' // Run Azure APP Service from a package file } { name: 'WEBSITE_NODE_DEFAULT_VERSION' value: '~18' // Set NodeJS version to 18.x for your site } { name: 'RUNNING_ON_AZURE' value: '1' } { name: 'BOT_ID' value: botAadAppClientId } { name: 'BOT_PASSWORD' value: botAadAppClientSecret } ] ftpsState: 'FtpsOnly' } } } // Register your web service as a bot with the Bot Framework module azureBotRegistration './botRegistration/azurebot.bicep' = { name: 'Azure-Bot-registration' params: { resourceBaseName: resourceBaseName botAadAppClientId: botAadAppClientId botAppDomain: webApp2.properties.defaultHostName botDisplayName: botDisplayName } } // The output will be persisted in .env.{envName}. Visit https://aka.ms/teamsfx-actions/arm-deploy for more details. output BOT_AZURE_APP_SERVICE_RESOURCE_ID string = webApp2.id output BOT_DOMAIN string = webApp2.properties.defaultHostName
若要确保正确设置必要的参数,请使用
azure.parameters.json
以下代码更新文件:{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "resourceBaseName": { "value": "tab${{RESOURCE_SUFFIX}}" }, "webAppSku": { "value": "B1" }, "botAadAppClientId": { "value": "${{BOT_ID}}" }, "botAadAppClientSecret": { "value": "${{SECRET_BOT_PASSWORD}}" }, "botDisplayName": { "value": "bot" }, "resourceBaseName2":{ "value": "bot${{RESOURCE_SUFFIX}}" } }
在
teamsapp.yml
文件下:- 在 下
provision
添加botAadApp/create
操作。 有关详细信息,请参阅 示例应用。 - 在
deploy
部分下,添加以下代码:
deploy: - uses: cli/runNpmCommand # Run npm command with: args: install - uses: cli/runNpmCommand # Run npm command with: args: run build # Deploy bits to Azure Storage Static Website - uses: azureAppService/zipDeploy with: workingDirectory: ./tab # Deploy base folder artifactFolder: . # Ignore file location, leave blank will ignore nothing ignoreFile: .webappignore # The resource id of the cloud resource to be deployed to. # This key will be generated by arm/deploy action automatically. # You can replace it with your existing Azure Resource id # or add it to your environment variable file. resourceId: ${{TAB_AZURE_APP_SERVICE_RESOURCE_ID}} - uses: azureAppService/zipDeploy with: workingDirectory: ./bot # Deploy base folder artifactFolder: . # Ignore file location, leave blank will ignore nothing ignoreFile: .webappignore # The resource id of the cloud resource to be deployed to. # This key will be generated by arm/deploy action automatically. # You can replace it with your existing Azure Resource id # or add it to your environment variable file. resourceId: ${{BOT_AZURE_APP_SERVICE_RESOURCE_ID}}
- 在 下
转到 “查看>命令面板...” 或选择 Ctrl+Shift+P。
输入
Teams: Provision
以将 bicep 应用到 Azure。输入
Teams: Deploy
以将选项卡应用代码部署到 Azure。在 “运行和调试”下,选择“ 启动远程 (Edge) ”或 “启动远程 (Chrome) ”。
选择 F5 键以调试和预览 Teams 应用。