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

能否通过Microsoft Graph API在C# .NET6中以应用级权限管理Teams聊天及附件?

可行方案及C# .NET 6示例代码

这些操作都可以通过Microsoft Graph API实现,以下是具体权限要求和代码示例:


应用级权限要求

需在Azure AD应用注册中添加以下权限:

  • 一对一聊天操作:ChatMessage.ReadWrite.All
  • 频道聊天操作:ChannelMessage.ReadWrite.All
  • 云存储附件下载:Files.Read.All

初始化GraphServiceClient

使用客户端凭据流完成应用级认证,初始化Graph客户端:

using Microsoft.Graph;
using Azure.Identity;

var clientId = "你的应用客户端ID";
var tenantId = "你的租户ID";
var clientSecret = "你的应用客户端密钥";

var scopes = new[] { "https://graph.microsoft.com/.default" };
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);

1. 更新聊天消息

一对一聊天消息更新

string chatId = "19:xxxxxx@thread.v2";
string messageId = "169xxxxxxxxx";

try
{
    var updatedMessage = new ChatMessage
    {
        Body = new ItemBody
        {
            Content = "<p>更新后的消息内容</p>",
            ContentType = BodyType.Html
        }
    };

    await graphClient.Chats[chatId].Messages[messageId]
        .Request()
        .UpdateAsync(updatedMessage);
    Console.WriteLine("消息更新成功");
}
catch (ServiceException ex)
{
    Console.WriteLine($"更新失败: {ex.Message}");
}

频道聊天消息更新

string teamId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxx";
string channelId = "19:xxxxxx@thread.tacv2";
string messageId = "169xxxxxxxxx";

try
{
    var updatedMessage = new ChatMessage
    {
        Body = new ItemBody
        {
            Content = "<p>频道消息已更新</p>",
            ContentType = BodyType.Html
        }
    };

    await graphClient.Teams[teamId].Channels[channelId].Messages[messageId]
        .Request()
        .UpdateAsync(updatedMessage);
    Console.WriteLine("频道消息更新成功");
}
catch (ServiceException ex)
{
    Console.WriteLine($"更新失败: {ex.Message}");
}

2. 删除聊天消息

一对一聊天消息删除

string chatId = "19:xxxxxx@thread.v2";
string messageId = "169xxxxxxxxx";

try
{
    await graphClient.Chats[chatId].Messages[messageId]
        .Request()
        .DeleteAsync();
    Console.WriteLine("消息删除成功");
}
catch (ServiceException ex)
{
    Console.WriteLine($"删除失败: {ex.Message}");
}

频道聊天消息删除

string teamId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxx";
string channelId = "19:xxxxxx@thread.tacv2";
string messageId = "169xxxxxxxxx";

try
{
    await graphClient.Teams[teamId].Channels[channelId].Messages[messageId]
        .Request()
        .DeleteAsync();
    Console.WriteLine("频道消息删除成功");
}
catch (ServiceException ex)
{
    Console.WriteLine($"删除失败: {ex.Message}");
}

3. 下载附件

方式1:直接获取附件字节(适用于小附件)

string chatId = "19:xxxxxx@thread.v2";
string messageId = "169xxxxxxxxx";
string attachmentId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxx";

try
{
    var attachment = await graphClient.Chats[chatId].Messages[messageId].Attachments[attachmentId]
        .Request()
        .GetAsync();

    if (attachment.ContentBytes != null)
    {
        byte[] fileBytes = Convert.FromBase64String(attachment.ContentBytes);
        File.WriteAllBytes("下载的文件.ext", fileBytes);
        Console.WriteLine("附件下载成功");
    }
}
catch (ServiceException ex)
{
    Console.WriteLine($"下载失败: {ex.Message}");
}

方式2:通过ContentUrl下载(适用于云存储附件)

string chatId = "19:xxxxxx@thread.v2";
string messageId = "169xxxxxxxxx";
string attachmentId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxx";

try
{
    var attachment = await graphClient.Chats[chatId].Messages[messageId].Attachments[attachmentId]
        .Request()
        .GetAsync();

    if (!string.IsNullOrEmpty(attachment.ContentUrl))
    {
        var httpClient = new HttpClient();
        var token = await clientSecretCredential.GetTokenAsync(new Azure.Core.TokenRequestContext(scopes));
        httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.Token);

        var fileStream = await httpClient.GetStreamAsync(attachment.ContentUrl);
        using var fileWriter = new FileStream("云附件下载.ext", FileMode.Create);
        await fileStream.CopyToAsync(fileWriter);
        Console.WriteLine("云附件下载成功");
    }
}
catch (ServiceException ex)
{
    Console.WriteLine($"下载失败: {ex.Message}");
}

4. 删除附件

方式1:更新消息移除附件(适合批量操作)

string chatId = "19:xxxxxx@thread.v2";
string messageId = "169xxxxxxxxx";
string targetAttachmentId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxx";

try
{
    var message = await graphClient.Chats[chatId].Messages[messageId]
        .Request()
        .Expand(m => m.Attachments)
        .GetAsync();

    var remainingAttachments = message.Attachments.Where(a => a.Id != targetAttachmentId).ToList();

    var updatedMessage = new ChatMessage
    {
        Attachments = remainingAttachments
    };

    await graphClient.Chats[chatId].Messages[messageId]
        .Request()
        .UpdateAsync(updatedMessage);
    Console.WriteLine("附件移除成功");
}
catch (ServiceException ex)
{
    Console.WriteLine($"移除失败: {ex.Message}");
}

方式2:直接删除附件资源

string chatId = "19:xxxxxx@thread.v2";
string messageId = "169xxxxxxxxx";
string attachmentId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxx";

try
{
    await graphClient.Chats[chatId].Messages[messageId].Attachments[attachmentId]
        .Request()
        .DeleteAsync();
    Console.WriteLine("附件删除成功");
}
catch (ServiceException ex)
{
    Console.WriteLine($"删除失败: {ex.Message}");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:45:03