I'm developing a notification bot for my organization in Microsoft Teams, using ASP.NET Core, Graph SDK (from Microsoft.Identity.Web.MicrosoftGraphBeta). I'm having hard times to develop a simple notification system to specific users in my tenant. Those users are identified by email address. I already implemented the proactive installation of the app for users and teams, by doing:
The controller that receives a message to send in MS Teams to a specific user
[HttpPost]
[Route("notify-approver")]
public async Task<List<string>> NotifyApprover([FromBody] ApproverMessage approverMessage)
{
var approvers = await _graphServiceClient.Users.Request().Filter($"mail eq '{approverMessage.Email}'").GetAsync();
var targetApprover = approvers.CurrentPage.ToList().FirstOrDefault();
var appInstallation= await _graphServiceClient.InstallIfNotAlreadyForUser(targetApprover.Id, _configuration.GetTeamsAppId());
// PER IL MOMENTO SEMBRA BUG
var chatId = await _graphServiceClient.GetChatThreadId(targetApprover.Id, appInstallation.Id)
}
The installation works fine and returns a UserScopeTeamsAppInstallation. This is the function I built for proactive installing:
public static async Task<UserScopeTeamsAppInstallation> InstallIfNotAlreadyForUser(this IGraphServiceClient graphServiceClient, string userId, string teamsAppId)
{
var appsCollectionPage = await graphServiceClient.Users[userId].Teamwork.InstalledApps.Request().Expand("teamsAppDefinition")
.GetAsync();
var appInstallation = appsCollectionPage.CurrentPage.ToList()
.Find(a => a.TeamsAppDefinition.TeamsAppId.Equals(teamsAppId));
if (appInstallation != null) return appInstallation;
var userScopeTeamsAppInstallation = new UserScopeTeamsAppInstallation()
{
AdditionalData = new Dictionary<string, object>
{
{"teamsApp@odata.bind", $"https://graph.microsoft.com/beta/appCatalogs/teamsApps/{teamsAppId}"}
}
};
var freshInstallation = await graphServiceClient.Users[userId].Teamwork.InstalledApps.Request().AddAsync(userScopeTeamsAppInstallation);
return freshInstallation;
}
Until now it's ok, but the bad part is in the trial to send proactively a message; as suggested in the documentation I proceed to get this chatId that should be useful. The funny part is that if I use Graph Client v1.0 I get an internal server error while retrieving this chat object below, then I switched to Beta client and it... kinda works.
public static async Task<string> GetChatThreadId(this IGraphServiceClient graphServiceClient, string userId, string teamsAppIdInstallation)
{
// forse ci vuole AppInstallationId anziché il semplice teamsAppId della app
//var chat = await graphServiceClient.Users[userId].Teamwork.InstalledApps[teamsAppIdInstallation].Chat.Request().GetAsync();
/*
* Perché dá internal server error?? Possibile bug della API di graph
* perché viceversa da graph explorer funziona e restituisce l'id della chat
*
* Per adesso sono costretto a salvarmi in un database tutte le conversation references.
*/
var chat = graphServiceClient.Users[userId].Teamwork.InstalledApps[teamsAppIdInstallation].Chat.Request().GetAsync();
return chat.Id.ToString();
//return "CIAONE";
}
From now on I getting more and more confused by the amount of scattered information.
What I saw is that usually the thing should be:
How am I supposed to do such a "simple" thing like sending a simple message to a person while it looks so much confusing?
A simple solution I found was to save the ConversationReference object in the OnTeamsMembersAddedAsync callback when the Bot is installed for a user by serializing it in json and saving into a Sqlite database. For retrieving it i deserialize it and use