Я хочу обновить чаты Microsoft Teams (один на один/канал) программно через C# .NET6. Кроме того, я хочу загружать и удалять вложения с разрешением уровня приложения.
В API Microsoft Graph есть раздел «Обновить сообщение чата».
https://learn.microsoft.com/en-us/graph/api/chatmessage-update?view=graph-rest-1.0&tabs=http
Может ли кто-нибудь подтвердить, можем ли мы обновлять/удалять сообщения чата, а также удалять и загружать вложения через Graph API?
Если да, не могли бы вы предоставить пример кода?
Спасибо.
Ниже приведено сообщение чата с файлом вложений, отправленное пользователю с именем «Шри» в командах MS:
Изначально зарегистрируйте одно приложение и добавьте API permissions
делегированного типа, предоставив согласие следующим образом:
При использовании интерактивного потока обязательно включите общедоступный клиентский поток и добавьте URI перенаправления на платформе «Мобильные и настольные приложения»:
Теперь используйте приведенный ниже пример кода C#, который загружает вложение сообщения чата по указанному пути после успешной аутентификации:
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models.ODataErrors;
using System.Text;
namespace DownloadFile
{
class Program
{
static async Task Main(string[] args)
{
var scopes = new[] { "User.Read", "Chat.ReadWrite", "Files.Read" };
var tenantId = "tenantId";
var clientId = "appId";
var options = new InteractiveBrowserCredentialOptions
{
TenantId = tenantId,
ClientId = clientId,
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
RedirectUri = new Uri("http://localhost"),
};
var interactiveCredential = new InteractiveBrowserCredential(options);
var graphClient = new GraphServiceClient(interactiveCredential, scopes);
try
{
var chatId = "chatId";
var messageId = "messageId";
var message = await graphClient.Me.Chats[chatId].Messages[messageId].GetAsync();
Console.WriteLine($"Message Content: {message.Body.Content}");
var attachment = message.Attachments[0];
Console.WriteLine($"Attachment Name: {attachment.Name}");
Console.WriteLine($"Attachment URL: {attachment.ContentUrl}");
var base64Url = Convert.ToBase64String(Encoding.UTF8.GetBytes(attachment.ContentUrl));
// Convert to unpadded base64url format
base64Url = base64Url.TrimEnd('=').Replace('/', '_').Replace('+', '-');
var encodedUrl = $"u!{base64Url}";
var path = @"C:\Users\xxxx\Downloads\Folder1";
var filePath = Path.Combine(path, attachment.Name);
Directory.CreateDirectory(path);
// Get the file using the OneDrive sharing link
var driveItem = await graphClient.Shares[encodedUrl].DriveItem.GetAsync();
var downloadUrl = driveItem.AdditionalData["@microsoft.graph.downloadUrl"]?.ToString();
if (string.IsNullOrEmpty(downloadUrl))
{
throw new Exception("Unable to get the download URL.");
}
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(downloadUrl);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync(filePath, content);
Console.WriteLine($"\nAttachment downloaded successfully at: {filePath}");
}
else
{
Console.WriteLine($"Failed to download attachment. Status code: {response.StatusCode}");
var errorContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Error details: {errorContent}");
}
}
catch (ODataError odataError)
{
Console.WriteLine($"Error Code: {odataError.Error.Code}");
Console.WriteLine($"Error Message: {odataError.Error.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
}
Ответ:
Когда я проверил указанный путь, вложение сообщения чата было успешно загружено следующим образом:
Чтобы обновить сообщение чата и удалить вложение, используйте приведенный ниже модифицированный код:
using Azure.Identity;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Graph.Models.ODataErrors;
namespace UpdateMsg
{
class Program
{
static async Task Main(string[] args)
{
var scopes = new[] { "User.Read", "Chat.ReadWrite", "Files.Read" };
var tenantId = "tenantId";
var clientId = "appId";
var options = new InteractiveBrowserCredentialOptions
{
TenantId = tenantId,
ClientId = clientId,
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
RedirectUri = new Uri("http://localhost"),
};
var interactiveCredential = new InteractiveBrowserCredential(options);
var graphClient = new GraphServiceClient(interactiveCredential, scopes);
try
{
var chatId = "chatId";
var messageId = "messageId";
var requestBody = new ChatMessage
{
MessageType = ChatMessageType.Message,
Subject = null,
Summary = null,
Importance = ChatMessageImportance.Normal,
Locale = "en-us",
From = new ChatMessageFromIdentitySet
{
Application = null,
Device = null,
User = new Identity
{
Id = "userId",
DisplayName = "User",
AdditionalData = new Dictionary<string, object>
{
{
"userIdentityType" , "aadUser"
},
},
},
AdditionalData = new Dictionary<string, object>
{
{
"conversation" , null
},
},
},
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "Attachment deleted", //Updated message
},
Attachments = new List<ChatMessageAttachment>
{
},
Mentions = new List<ChatMessageMention>
{
},
Reactions = new List<ChatMessageReaction>
{
},
MessageHistory = new List<ChatMessageHistoryItem>
{
},
};
var msg = await graphClient.Me.Chats[chatId].Messages[messageId].PatchAsync(requestBody);
Console.WriteLine("Message updated");
}
catch (ODataError odataError)
{
Console.WriteLine($"Error Code: {odataError.Error.Code}");
Console.WriteLine($"Error Message: {odataError.Error.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
}
}
Ответ:
Чтобы подтвердить это, я проверил то же самое в чате MS Teams, где вложение было удалено, а сообщение обновлено следующим образом:
Ссылка:
Обновить ChatMessage — Microsoft Graph
ОБНОВЛЯТЬ:
Чтобы сделать то же самое, используя разрешения на уровне приложения, внесите следующие изменения:
Замените метод graphClient.Me.Chats[chatId].Messages[messageId].GetAsync()
на graphClient.Chats[chatId].Messages[messageId].GetAsync().Result
.
Обязательно создайте Graph Client с использованием поставщика аутентификации потока учетных данных клиента, воспользовавшись этим MS Document.
Привет, Шридеви, я хотела сообщить вам, что я успешно использовала ваш код для загрузки вложения с разрешением на уровне приложения. Хотя, как вы указали, функции чата доступны только через делегированное разрешение. Я внес несколько изменений для загрузки файлов с разрешением уровня приложения. Вот изменения, которые я внес: вместо использования ключевого слова «me» с методом GraphClient.Me.Chats[chatId].Messages[messageId].GetAsync() я использовал это:graphClient.Chats[chatId].Messages[messageId]. ].GetAsync().Result. GraphApiClient создается с разрешением уровня приложения.
Пожалуйста, проверьте обновленный ответ и дайте мне знать, если требуются какие-либо изменения.
Приношу свои извинения, я пропускаю упоминание о том, что мне нужны эти функции с разрешением уровня приложения. Можете ли вы подтвердить возможность с разрешением уровня приложения?