I am very new to Teams and Microsoft Graph.
My aim: To send a message to a channel from a C# desktop app.
I think I've made some progress, I got the Team ID, Channel ID and Client ID. I installed the Graph Beta package from NuGet.
string clientId = "xxxSomeIDxxx";
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create(clientId)
.Build();
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var chatMessage = new ChatMessage
{
Subject = null,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = "<attachment id=\"74d20c7f34aa4a7fb74e2b30004247c5\"></attachment>"
},
Attachments = new List<ChatMessageAttachment>()
{
new ChatMessageAttachment
{
Id = "74d20c7f34aa4a7fb74e2b30004247c5",
ContentType = "application/vnd.microsoft.card.thumbnail",
ContentUrl = null,
Content = "Here is some body text.",
Name = null,
ThumbnailUrl = null
}
}
};
await graphClient.Teams["xxxSomeIDxxx"].Channels["xxSomeIdxxx"].Messages
.Request()
.AddAsync(chatMessage);
I dont know how to make the Authentication Provider.
By looking at it it seems like this is the right one:
InteractiveAuthenticationProvider authProvider = new InteractiveAuthenticationProvider(publicClientApplication, scopes);
But scopes is undefined.
Can someone please assist and tell met which Microsoft Graph authentication provider to use for ChatMessage in C#
I use Visual studio 2017 C# windows form app Microsoft Teams
The interface IAuthenticationProvider
only has a single method:
Task AuthenticateRequestAsync(HttpRequestMessage request);
We use a simple AuthenticationProvider that looks like this:
public class AuthenticationProvider : IAuthenticationProvider
{
private readonly string _accessToken;
public AuthenticationProvider(string accessToken)
{
_accessToken = accessToken;
}
public Task AuthenticateRequestAsync(HttpRequestMessage request)
{
request.Headers.Add("Authorization", $"Bearer {_accessToken}");
return Task.CompletedTask;
}
}
We use this to save our access token in MemoryCache since we have a service calling the Graph API and not a specific user. I hope it can give some guidance anyway:
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Graph;
using Microsoft.Identity.Client;
using Project.Repository.Models;
using Project.Repository.Models.Azure.ADB2C;
using Project.Repository.Models.Constants;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Project.Repository.Services.External
{
public class GraphApiService
{
private readonly IHttpClientFactory _clientFactory;
private readonly IMemoryCache _memoryCache;
private readonly Settings _settings;
private readonly string _accessToken;
public GraphApiService(IHttpClientFactory clientFactory, IMemoryCache memoryCache, Settings settings)
{
_clientFactory = clientFactory;
_memoryCache = memoryCache;
_settings = settings;
string graphApiAccessTokenCacheEntry;
// Look for cache key.
if (!_memoryCache.TryGetValue(CacheKeys.GraphApiAccessToken, out graphApiAccessTokenCacheEntry))
{
// Key not in cache, so get data.
var adb2cTokenResponse = GetAccessTokenAsync().GetAwaiter().GetResult();
graphApiAccessTokenCacheEntry = adb2cTokenResponse.access_token;
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromSeconds(adb2cTokenResponse.expires_in));
// Save data in cache.
_memoryCache.Set(CacheKeys.GraphApiAccessToken, graphApiAccessTokenCacheEntry, cacheEntryOptions);
}
_accessToken = graphApiAccessTokenCacheEntry;
}
//TODO - Call this method and refresh cache when a new user is added
public async Task<List<Adb2cUser>> GetAllUsers(bool refreshCache = false)
{
List<Adb2cUser> adb2cUsers;
if (refreshCache)
{
_memoryCache.Remove(CacheKeys.Adb2cUsers);
}
// Look for cache key.
if (!_memoryCache.TryGetValue(CacheKeys.Adb2cUsers, out adb2cUsers))
{
// Key not in cache, so get data.
adb2cUsers = new List<Adb2cUser>();
var authProvider = new AuthenticationProvider(_accessToken);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var users = await graphClient.Users
.Request()
.GetAsync();
foreach (var user in users)
{
var adb2cUser = new Adb2cUser()
{
Id = Guid.Parse(user.Id),
GivenName = user.GivenName,
FamilyName = user.Surname,
};
adb2cUsers.Add(adb2cUser);
}
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
//Get new values every hour
.SetAbsoluteExpiration(TimeSpan.FromHours(1));
// Save data in cache.
_memoryCache.Set(CacheKeys.Adb2cUsers, adb2cUsers, cacheEntryOptions);
}
return adb2cUsers;
}
private async Task<Adb2cTokenResponse> GetAccessTokenAsync()
{
var client = _clientFactory.CreateClient();
var kvpList = new List<KeyValuePair<string, string>>();
kvpList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
kvpList.Add(new KeyValuePair<string, string>("client_id", _settings.AzureAdB2C.ClientId));
kvpList.Add(new KeyValuePair<string, string>("scope", "https://graph.microsoft.com/.default"));
kvpList.Add(new KeyValuePair<string, string>("client_secret", _settings.AzureAdB2C.ClientSecret));
#pragma warning disable SecurityIntelliSenseCS // MS Security rules violation
var req = new HttpRequestMessage(HttpMethod.Post, $"https://login.microsoftonline.com/{_settings.AzureAdB2C.Domain}/oauth2/v2.0/token")
{ Content = new FormUrlEncodedContent(kvpList) };
#pragma warning restore SecurityIntelliSenseCS // MS Security rules violation
using var httpResponse = await client.SendAsync(req);
var response = await httpResponse.Content.ReadAsStringAsync();
httpResponse.EnsureSuccessStatusCode();
var adb2cTokenResponse = JsonSerializer.Deserialize<Adb2cTokenResponse>(response);
return adb2cTokenResponse;
}
}
public class AuthenticationProvider : IAuthenticationProvider
{
private readonly string _accessToken;
public AuthenticationProvider(string accessToken)
{
_accessToken = accessToken;
}
public Task AuthenticateRequestAsync(HttpRequestMessage request)
{
request.Headers.Add("Authorization", $"Bearer {_accessToken}");
return Task.CompletedTask;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.