You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Microsoft Teams BotBuilder:ID以thread.skype结尾的团队无法获取频道列表

问题:Teams机器人调用TeamsInfo.getTeamChannels获取thread.skype团队频道返回空列表

我在两个不同的Microsoft Teams团队中安装了机器人。当为ID以thread.tacv2结尾的团队调用TeamsInfo.getTeamChannels方法时,可成功获取频道列表;但对ID以thread.skype结尾的团队执行相同代码,返回的却是空列表。

完整代码

TestChannelList.java

package com.mytest;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import com.microsoft.bot.builder.BotFrameworkAdapter;
import com.microsoft.bot.builder.TurnContext;
import com.microsoft.bot.builder.teams.TeamsInfo;
import com.microsoft.bot.connector.authentication.AppCredentials;
import com.microsoft.bot.connector.authentication.SimpleCredentialProvider;
import com.microsoft.bot.schema.ConversationAccount;
import com.microsoft.bot.schema.ConversationReference;
import com.microsoft.bot.schema.teams.ChannelInfo;

public class TestChannelList {

  private String appId;
  private String appPassword;
  private BotFrameworkAdapter bot;
  private ConversationReference installationReference = new ConversationReference();

  public TestChannelList() {
    this.appId = "***";
    this.appPassword = "***";
    this.bot = new BotFrameworkAdapter(new SimpleCredentialProvider(appId, appPassword));

    installationReference.setChannelId("msteams");
    installationReference.setServiceUrl("https://smba.trafficmanager.net/amer/");

//    这段代码可以正常工作:
//    ConversationAccount conversation = new ConversationAccount(true,
//            "19:***@thread.tacv2",null);
//        conversation.setConversationType("channel");
//        conversation.setTenantId("***");

//    这段代码返回空列表:
    ConversationAccount conversation = new ConversationAccount(true,
        "19:***@thread.skype", "***");
    conversation.setConversationType("channel");
    conversation.setTenantId("***");
    installationReference.setConversation(conversation);

    TurnContext tc = getTurnContextForConversationReference(installationReference);
    CompletableFuture<List<ChannelInfo>> cf = TeamsInfo.getTeamChannels(tc,
        installationReference.getConversation().getId());
    List<ChannelInfo> channels = cf.get();
    System.out.println(channels.size()); // 对于`thread.skype`团队返回0,`thread.tacv2`团队返回非0值
  }

  public TurnContext getTurnContextForConversationReference(ConversationReference cr)
      {
    // 避免401错误需要执行此操作
   AppCredentials.trustServiceUrl(cr.getServiceUrl());
    TeamsBotCallbackHandler callback = new TeamsBotCallbackHandler();
    CompletableFuture<Void> cf = bot.continueConversation(appId, cr, callback);
    try {
      cf.get();
      return callback.getTurnContext();
    } catch (InterruptedException | ExecutionException e) {
      System.out.println("捕获到异常");
      e.printStackTrace();
      return null;
    }
  }

  public static void main(String[] args) {
    new TestChannelList();
  }
}

TeamsBotCallbackHandler.java

package com.mytest;

import com.microsoft.bot.builder.BotCallbackHandler;
import com.microsoft.bot.builder.TurnContext;
import java.util.concurrent.CompletableFuture;

public class TeamsBotCallbackHandler implements BotCallbackHandler {

  private TurnContext turnContext;

  @Override
  public CompletableFuture<Void> invoke(TurnContext turnContext) {
    // 设置实例字段,然后Future立即返回
    this.turnContext = turnContext;
    return CompletableFuture.completedFuture(null);
  }

  public TurnContext getTurnContext() {
    return turnContext;
  }
}

原因分析

会话ID以thread.skype结尾的不是标准的Teams团队(Team),而是私人聊天组(Group Chat)。TeamsInfo.getTeamChannels方法仅适用于标准Teams团队(会话ID以thread.tacv2结尾,会话类型为channel),私人聊天组没有“频道”这个概念,因此调用该方法会返回空列表。

解决方案

  1. 区分会话类型:

    • 标准Teams团队的会话类型为channel,会话ID后缀为thread.tacv2;
    • 私人聊天组的会话类型为groupChat,会话ID后缀为thread.skype。
      可以通过ConversationAccount.getConversationType()来判断当前会话类型,再决定是否调用getTeamChannels。
  2. 代码调整示例:
    在调用getTeamChannels前加入判断逻辑:

    String conversationType = installationReference.getConversation().getConversationType();
    if ("channel".equals(conversationType)) {
        CompletableFuture<List<ChannelInfo>> cf = TeamsInfo.getTeamChannels(tc, installationReference.getConversation().getId());
        List<ChannelInfo> channels = cf.get();
        System.out.println(channels.size());
    } else {
        System.out.println("当前会话不是标准Teams团队,无法获取频道列表");
        // 针对私人聊天组的逻辑,比如获取成员列表
        CompletableFuture<List<ChannelAccount>> membersCf = TeamsInfo.getMembers(tc);
        List<ChannelAccount> members = membersCf.get();
        System.out.println("聊天组成员数量:" + members.size());
    }
    
  3. 权限验证:确保机器人在私人聊天组中拥有足够的权限,但即使权限足够,私人聊天组也不存在频道结构,因此无需调用getTeamChannels。

内容的提问来源于stack exchange,提问作者nvioli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 17:02:51