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

如何让Teams机器人无需用户添加即可直接发送私信

Teams机器人向团队成员发送个人消息(Go实现)

问题原因

你之前调用创建对话API时未指定团队ID,Teams默认判定你要创建用户个人对话,但机器人并未在用户个人范围安装,因此报错"Bot is not installed in user's personal scope"。当机器人仅安装在团队中时,必须通过团队上下文发起与成员的对话。

解决方案步骤

1. 确认权限配置

确保机器人应用已配置以下应用权限(需管理员同意):

  • Chat.Create:允许机器人创建对话
  • TeamMember.Read.All:可选,用于获取团队成员列表
  • ChatMessage.Send:允许机器人发送消息

2. 正确调用对话创建API

请求中必须包含团队ID,明确机器人基于团队权限发起对话。示例请求:

POST https://smba.trafficmanager.net/teams/v3/conversations
Content-Type: application/json

{
  "bot": {
    "id": "<机器人ID>",
    "name": "<机器人名称>"
  },
  "members": [
    {
      "id": "<目标用户ID>",
      "name": "<目标用户名>"
    }
  ],
  "channelData": {
    "tenant": {
      "id": "<租户ID>"
    },
    "team": {
      "id": "<机器人已安装的团队ID>"
    }
  },
  "topicName": "<对话主题(如:团队通知)>"
}

3. Go语言实现示例

以下是完整的HTTP请求实现,包含令牌获取(需自行实现OAuth2逻辑):

package main

import (
	"bytes"
	"encoding/json"
	"log"
	"net/http"
)

// CreateConversationRequest 定义创建对话的请求结构体
type CreateConversationRequest struct {
	Bot struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	} `json:"bot"`
	Members []struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	} `json:"members"`
	ChannelData struct {
		Tenant struct {
			ID string `json:"id"`
		} `json:"tenant"`
		Team struct {
			ID string `json:"id"`
		} `json:"team"`
	} `json:"channelData"`
	TopicName string `json:"topicName"`
}

func main() {
	// 替换为实际参数
	request := CreateConversationRequest{
		Bot: struct {
			ID   string `json:"id"`
			Name string `json:"name"`
		}{
			ID:   "your-bot-id",
			Name: "Your Bot Name",
		},
		Members: []struct {
			ID   string `json:"id"`
			Name string `json:"name"`
		}{
			{
				ID:   "target-user-id",
				Name: "Target User Name",
			},
		},
		ChannelData: struct {
			Tenant struct {
				ID string `json:"id"`
			} `json:"tenant"`
			Team struct {
				ID string `json:"id"`
			} `json:"team"`
		}{
			Tenant: struct {
				ID string `json:"id"`
			}{
				ID: "your-tenant-id",
			},
			Team: struct {
				ID string `json:"id"`
			}{
				ID: "team-id-where-bot-is-installed",
			},
		},
		TopicName: "Team Notification",
	}

	// 序列化请求体
	jsonBody, err := json.Marshal(request)
	if err != nil {
		log.Fatalf("序列化请求体失败: %v", err)
	}

	// 获取机器人OAuth2令牌(需自行实现,使用client credentials flow)
	authToken := "Bearer your-bot-access-token"

	// 创建HTTP请求
	req, err := http.NewRequest("POST", "https://smba.trafficmanager.net/teams/v3/conversations", bytes.NewBuffer(jsonBody))
	if err != nil {
		log.Fatalf("创建请求失败: %v", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", authToken)

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 解析响应
	var response map[string]interface{}
	if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
		log.Fatalf("解析响应失败: %v", err)
	}
	log.Printf("对话创建响应: %v", response)

	// 若对话创建成功,可使用返回的conversationId发送消息
	conversationID, ok := response["id"].(string)
	if ok {
		sendMessage(conversationID, authToken)
	}
}

// sendMessage 向指定对话发送消息
func sendMessage(conversationID, authToken string) {
	messageBody := map[string]interface{}{
		"type": "message",
		"text": "这是来自团队机器人的个人消息",
	}
	jsonBody, err := json.Marshal(messageBody)
	if err != nil {
		log.Fatalf("序列化消息失败: %v", err)
	}

	req, err := http.NewRequest("POST", "https://smba.trafficmanager.net/teams/v3/conversations/"+conversationID+"/activities", bytes.NewBuffer(jsonBody))
	if err != nil {
		log.Fatalf("创建消息请求失败: %v", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", authToken)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("发送消息失败: %v", err)
	}
	defer resp.Body.Close()

	log.Printf("消息发送响应状态码: %d", resp.StatusCode)
}

关键注意事项

  • 机器人必须已安装在目标团队中,且目标用户是该团队成员
  • 必须使用应用权限而非委托权限,并完成管理员同意
  • 令牌需通过机器人的客户端凭据流(Client Credentials Flow)获取,确保以机器人身份发起请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:49:54