如何用Node.js BotBuilder在Microsoft Teams中调用含图片/Adaptive Cards的模态弹窗
Teams Bot 触发模态弹窗(含Adaptive Cards/图片)实现指南
一、响应用户操作触发模态弹窗
对话场景下触发模态弹窗,不能使用消息扩展专用的composeExtension/fetchTask(这是你报错“Bad argument unknown activity type”的核心原因),需构造**task/fetch类型的Invoke Activity**发送给用户。在Node.js BotBuilder的对话处理逻辑中(如onMessage或对话框处理器),直接生成并发送该Activity即可。
代码片段示例:
async run(context) { // 响应用户特定消息或按钮点击,触发弹窗 const taskModuleActivity = { type: 'invoke', name: 'task/fetch', value: { task: { type: 'adaptiveCard', value: { /* Adaptive Card 内容 */ }, width: 500, height: 400, title: '自定义模态弹窗' } } }; await context.sendActivity(taskModuleActivity); }
二、构建模态弹窗内容(含图片/Adaptive Cards)
模态弹窗支持adaptiveCard(推荐)和url两种内容类型,以下是具体实现:
1. 嵌入图片的Adaptive Cards弹窗
直接在Adaptive Card结构中加入图片元素,完整示例:
const adaptiveCardWithImage = { type: 'AdaptiveCard', version: '1.4', body: [ { type: 'TextBlock', text: '带图片的表单弹窗', size: 'Large', weight: 'Bolder' }, { type: 'Image', url: 'https://example.com/your-image.png', altText: '示例图片', width: '300px' }, { type: 'Input.Text', id: 'userInput', placeholder: '请输入内容' } ], actions: [ { type: 'Action.Submit', title: '提交', data: { action: 'submitForm' } } ] }; // 触发弹窗的Activity const taskActivity = { type: 'invoke', name: 'task/fetch', value: { task: { type: 'adaptiveCard', value: adaptiveCardWithImage, width: 550, height: 450, title: 'Adaptive Card弹窗' } } };
2. 直接展示图片的弹窗
若仅需展示图片,使用url类型指向图片地址:
const imageTaskActivity = { type: 'invoke', name: 'task/fetch', value: { task: { type: 'url', value: 'https://example.com/your-image.png', width: 600, height: 500, title: '图片预览弹窗' } } };
三、Teams环境额外配置
- Manifest文件配置:
- 在机器人
manifest.json的validDomains字段中,添加图片、Adaptive Card外部资源的域名,否则Teams会阻止加载。 - 确认
bots字段的scopes包含所需场景(personal、team、groupChat)。
- 在机器人
- 资源要求:图片必须是公开可访问的HTTPS地址,且域名在
validDomains列表内。 - 权限说明:机器人无需额外特殊权限,具备发送消息和Invoke Activity的基础权限即可。
四、完整代码示例与提交处理
const { ActivityHandler } = require('botbuilder'); class TeamsBot extends ActivityHandler { constructor() { super(); // 监听用户消息 this.onMessage(async (context, next) => { const text = context.activity.text.toLowerCase(); if (text.includes('打开弹窗')) { await this.sendTaskModule(context); } await next(); }); // 处理弹窗提交数据 this.onInvokeActivity(async (context) => { if (context.activity.name === 'task/submit') { const submitData = context.activity.value.data; await context.sendActivity(`你提交的内容:${submitData.userInput}`); return { status: 200 }; } }); } async sendTaskModule(context) { const adaptiveCard = { type: 'AdaptiveCard', version: '1.4', body: [ { type: 'TextBlock', text: '欢迎使用模态弹窗', size: 'Large' }, { type: 'Image', url: 'https://example.com/sample-image.png', altText: '示例图' }, { type: 'Input.Text', id: 'userInput', placeholder: '请输入反馈' } ], actions: [{ type: 'Action.Submit', title: '提交', data: { action: 'submitFeedback' } }] }; const taskActivity = { type: 'invoke', name: 'task/fetch', value: { task: { type: 'adaptiveCard', value: adaptiveCard, width: 500, height: 400, title: '用户反馈弹窗' } } }; await context.sendActivity(taskActivity); } } module.exports.TeamsBot = TeamsBot;
内容的提问来源于stack exchange,提问作者Abrar
相关产品推荐
相关产品推荐

