Pratik Grafik: Ekip Mesajlaşmasıyla Çalışmak


Modüller Arasında Seçim Yapmak

Microsoft Teams PowerShell modülünün yeni bir sürümü genellikle PowerShell Galerisinden yüz binlerce indirme oluşturur. İndirme sayısı kullanımın bir göstergesi olmasa da modülü indirenlerin çoğunun bunu Teams'i yönetmek için kullandığını varsaymak mantıklıdır. Microsoft Graph PowerShell SDK'sı ayrıca Teams'le çalışmak için Get-MgTeam, Get-MgTeamChannel vb. gibi cmdlet'ler içerir; bunların çoğu Microsoft'ta yinelenen cmdlet'ler bulunur. Ekipler modülü. Tekrarlama göz önüne alındığında, yöneticilerin Teams işlemlerini otomatikleştirmek için hangi yolu izlemesi gerekir?

Cevap basit değil çünkü ne yapmaya çalıştığınıza bağlı. Hatırlanması gereken bazı noktalar şunlardır:

  • Her iki modülün de Microsoft Graph'a bağlantıları vardır. Microsoft Teams modülündeki cmdlet'lerin çoğu Graph API'lerini temel alır ve Microsoft Graph PowerShell SDK'sındaki tüm cmdlet'ler Graph API'lerinden türetilir.
  • Microsoft Teams modülü, Graph API'lerini temel almayan diğer cmdlet'leri içerir. Çoğu, orijinal olarak Skype Kurumsal bağlayıcısından gelen ilke yönetimi cmdlet'leridir.
  • Microsoft Graph PowerShell SDK'sı, diğer Microsoft 365 iş yükleri ve Entra ID ile etkileşim kurmak için cmdlet'ler içerir.
  • Microsoft Teams modülü, yönetim işlemlerini otomatikleştirmek için tasarlanmıştır. Genel yönetici veya Teams yöneticisi rolüne sahip bir hesap tarafından kullanıldığında cmdlet'ler bir kuruluştaki tüm ekipleri yönetebilir.
  • Microsoft Graph PowerShell SDK'sı, yeni sohbetlerin yayınlanması gibi kullanıcı içeriğiyle etkileşim kurabilen cmdlet'ler içerir. Farklı Teams verileriyle etkileşim kurmak için farklı izinler gerekir. Geliştiricilerin, verilere erişim söz konusu olduğunda devredilen izinler ile uygulama izinleri arasındaki farkı da hatırlamaları gerekir.

Çoğu durumda, genel otomasyon için Microsoft Teams modülünü kullanmak ve sohbetleri göndermek veya kaldırmak gibi kullanıcı verileriyle etkileşimde bulunmak gerektiğinde Microsoft Graph PowerShell SDK'yı tanıtmak daha kolaydır; burada yapmak istediğimiz de budur.

Bu makalenin geri kalanında Teams mesajlaşmasının temelleri ele alınmakta ve Microsoft Graph PowerShell SDK kullanılarak bire bir ve grup sohbetlerine ve kanal konuşmalarına nasıl mesaj gönderileceği açıklanmaktadır. Mesajların kanallardan kaldırılması süreci farklı bir makalede ele alınmaktadır.

İzinlerle İlgili Bir Not

Muhtemelen bildiğiniz gibi, Graph API istekleri için kullanılan izin modeli en az ayrıcalık esasına dayanmaktadır. Çoğu durumda, Grafik isteklerini kullanan uygulamaların zamanlanmış bir Azure Otomasyonu işi gibi arka plan işlemleri olarak çalışmasına izin vermek için uygulama izinleri mevcuttur.

Sohbetlere veya kanal konuşmalarına mesaj göndermek gibi Grafik istekleri için hiçbir uygulama izni mevcut değildir, bu nedenle devredilen izinlerin kullanılması gerekir. Uygulamanın, kanallara mesaj göndermek için ChannelMessage.Send iznine ve sohbete mesaj göndermek için Chat.Create iznine ihtiyacı vardır. İletileri almak için ek izinler (Chat.ReadWrite gibi) gereklidir.

Uygulama izinlerinin olmaması nedeniyle, oturum açan hesabın mesaj göndermek için bir sohbetin veya ekibin üyesi olması, kanal mesajlarını kaldırmak için ise bir ekip sahibi olması gerekir. Azure Otomasyonu tarafından yönetilen kimlikler kullanılamaz çünkü bu kimlikler bir ekibin veya sohbetin üyesi olamaz.

Genel geçici çözüm, ekip üyesi olan bir hizmet hesabı kullanarak Teams'de oturum açmak ve kanallara bu şekilde gönderi göndermektir. Geçmişte bunu, Azure Key Vault'ta depolanan kimlik bilgilerini kullanarak Submit-PnPTeamsChannelMessage cmdlet PnP modülünü kullanarak yapmıştım. Aynı teknik burada ele alınan cmdlet'lerde de çalışır.

Sohbet Verileri

Teams bire bir ve grup sohbetlerini destekler. İlk örnek, iki kiracı hesabı arasında yeni bir bire bir sohbet oluşturur. Microsoft belgeleri, sohbetlere nasıl mesaj gönderileceğine dair birkaç güzel örnek içerir. Ancak Teams'e gönderilecek JSON yükünü oluşturmak için kullanılan yöntemin aşırı karmaşık olduğunu ve programatik manipülasyona uygun olmadığını düşünüyorum.

Bu nedenle, yükü oluşturan dizileri ve karma tabloları tanımlamak ve açmak için farklı bir yaklaşım kullanıyorum. Planner görevlerini bir plana göndermek için parametreler oluşturmak için kullanılan yaklaşımın aynısıdır. İsterseniz dokümantasyon örneklerinde benimsenen yaklaşımı kullanın. İşe yarıyorlar ve iyi örnekler, ancak benim yöntemimin prodüksiyon senaryoları için daha iyi olduğunu düşünüyorum.

Bire Bir Sohbet Oluşturma ve Gönderim Yapma

İlk olarak, sohbet katılımcılarının hesap tanımlayıcılarını tutan bir diziyi ve sohbeti oluşturmak için kullanılan yükü (diğer bir deyişle istek gövdesini) tutan karma tablosunu tanımlarız. Kod ayrıca sohbeti bire bir olarak tanımlamak için bir parametre de ekler. Sohbet türünü tanımlamak için tam biçimi (onOnOne) kullanmanız gerekir.

[array]$MemberstoAdd = "eff4cd58-1bb8-4899-94de-795f656b4a18", "cad05ccf-a359-4ac7-89e0-1e33bf37579e"
$OneOnOneChatBody = @{}
$OneOnOneChatBody.Add("chattype", "oneOnOne")

Yükün geri kalan kısımları sohbet katılımcılarını tanımlar. Bu veriler iki hash tablosundan oluşan bir diziye iletilir. Her karma tablosu, bir sohbet katılımcısı hakkında bilgi içerir; bunlardan biri oturum açmış kullanıcı olmalıdır. Gördüğünüz gibi kod, sohbet katılımcısı olarak bir misafir hesabı eklemeye uygundur.

$Members = @()
ForEach ($Member in $MemberstoAdd) {
    $User = Get-MgUser -UserId $Member -Property id, displayName, userType, userprincipalName
    $MemberId = ("https://graph.microsoft.com/v1.0/users('{0}')" -f $Member)
    $MemberDetails = @{}
    [array]$MemberRole = "owner"
    If ($User.userType -eq "Guest") {
        [array]$MemberRole = "guest"
    }
    $MemberDetails.Add("roles", $MemberRole.trim())
    $MemberDetails.Add("@odata.type", "#microsoft.graph.aadUserConversationMember")
    $MemberDetails.Add("user@odata.bind", $MemberId.trim())
    $Members += $MemberDetails
}
$OneOnOneChatBody.Add("members", $Members)

Yükün tamamı şuna benzer:

$OneOnOneChatBody

Name                           Value
----                           -----
chattype                       oneOnOne
members                        {System.Collections.Hashtable, System.Collections.Hashtable}

Artık sohbet oluşturmak için New-MgChat cmdlet'ini çalıştırabiliriz. İki katılımcı için zaten bir sohbet mevcutsa Teams, bu sohbetin sohbet tanımlayıcısını döndürür. Aksi takdirde Teams yeni bir sohbet oluşturur ve 19:949d2f6c2b1f4f50b42714ddb2be4a36@thread.v2 gibi bir değere sahip olan tanımlayıcıyı döndürür.

$NewChat = New-MgChat -BodyParameter $OneOnOneChatBody
If ($NewChat) {
    Write-Host ("New chat {0} created" -f $NewChat.id)
} Else {
    Write-Host "Failed to create chat"
}

Sohbet tanımlayıcısını bilmek, sohbete mesaj göndermek için New-MgChatMessage cmdlet'ini çalıştırmamıza olanak tanır. Bu kod bazı HTML içeriği oluşturur ve bunu sohbete gönderir.

$Content = "<b><i>Using the Microsoft AuditLog Query Graph API (Preview)</b></i><p>"
$Content = $Content + "The unified audit log is the source of a lot of information about a Microsoft 365 tenant. The Search-UnifiedAuditLog cmdlet is available to search the audit log and now we have the AuditLog Graph API. This article explains how to use the new API to query and retrieve audit records from the log."
$Content = $Content + "<p>For more information, see <a href='https://practical365.com/audit-log-query-api/'>https://practical365.com/audit-log-query-api/</a>"

$ChatMessageBody = @{}
$ChatMessageBody.Add("contentType", "html")
$ChatMessageBody.Add("content", $Content) 
$ChatMessage = New-MgChatMessage -ChatId $NewChat.Id -Body $ChatMessageBody

Şekil 1 sohbete gönderilen mesajı göstermektedir.

Grup Sohbeti Oluşturma ve Sohbete Gönderme

Bir grup sohbetinin iki ila 250 katılımcısı vardır. Ayrıca bir konusu (başlığı) da olabilir. Yeni bir grup sohbetine çok sayıda katılımcının eklendiğini göstermek için bu kod, belirli bir görünen ad için af filtresini kullanan bir ekip bulur ve üyelik listesini bir dizi kullanıcı hesabı tanımlayıcısına çıkarır. Ayrıca yeni sohbeti oluşturmak için veriye ilişkin karma tablosunu oluşturur ve sohbet türünü ve konusunu doldurur:

$Members = @()
$Team = Get-MgTeam -Filter "displayName eq 'Information Quality and Accuracy'"
If ($Team) {
   [array]$TeamMembers = (Get-MgGroupMember -GroupId $Team.Id).Id 
}
# Create a new group chat
$GroupChatBody = @{}
$GroupChatBody.Add("chattype", "group")
$GroupChatBody.Add("topic", "Major Updates - Urgent News")

Bir sonraki adım, grup sohbetine eklenecek her üyeyi tanımlamak için bir dizi karma tablo oluşturur. Tıpkı bire bir sohbette olduğu gibi, grup sohbetindeki katılımcılardan birinin oturum açmış kullanıcı olması gerekir. Bu bir önizleme özelliği olduğundan kod, çok kiracılı bir kuruluştan senkronize edilen ekip üyelerinin hesaplarını hariç tutar. Son olarak New-MgChat cmdlet'i yeni sohbeti oluşturur.

ForEach ($Member in $TeamMembers) {
   $User = Get-MgUser -UserId $Member -Property id, displayName, userType, userprincipalName
   # Exclude MTO accounts
   If (($User.userprincipalName -notlike "*#EXT#*" -and $User.userType -eq "Member") -or $User.userType -eq "Guest") {
        Write-Host ("Processing member {0}" -f $User.DisplayName)
        $MemberId = ("https://graph.microsoft.com/v1.0/users('{0}')" -f $Member)
        $MemberDetails = @{}
        [array]$MemberRole = "owner"
        If ($User.userType -eq "Guest") {
            [array]$MemberRole = "guest"
        }
        $MemberDetails.Add("roles", $MemberRole.trim())
        $MemberDetails.Add("@odata.type", "#microsoft.graph.aadUserConversationMember")
        $MemberDetails.Add("user@odata.bind", $MemberId.trim())
        $Members += $MemberDetails
  }
}
# Add the membership information to the parameter body
$GroupChatBody.Add("members", $Members)
$NewGroupChat = New-MgChat -BodyParameter $GroupChatBody

Şekil 2'de yukarıdaki kod ile oluşturulan grup sohbetine üyelik gösterilmektedir.

Bire bir sohbete mesaj göndermek için kullanılan aynı New-MgChatMessage komutu, grup sohbetine de mesaj gönderecektir.

Çoklu Grup Sohbetleri

Teams bire bir sohbet mevcut olduğunda yeniden kullansa da aynı konulara sahip birden fazla grup sohbeti oluşturmak da mümkündür. Özelleştirilebilir sohbet fotoğrafı gibi Teams istemcileri de, kullanıcıların sohbet listesinde sohbetleri bulmasına yardımcı olmak için konuyu görüntüleme amacıyla kullanır. Sohbet tanımlayıcısı, belirli sohbetlere nasıl başvurulacağıdır. Bu, kodun mesaj gönderirken hangi sohbeti hedeflediği konusunda dikkatli olması gerektiği anlamına gelir. Örneğin, grup sohbetlerinin ayrıntılarını almak için Get-MgChat cmdlet'ini çalıştırırsanız şunun gibi bir şey görebilirsiniz:

$GroupChats = Get-MgChat -filter "ChatType eq 'group'"
$GroupChats | Format-Table Topic, Id

Topic                             Id
-----                             --
Major Updates - Urgent News       19:1741422a23464620a6e71f363db2d51a@thread.v2
Major Updates - Urgent News       19:949d2f6c2b1f4f50b52714ddb2be4a36@thread.v2
Major Updates - Urgent News       19:5f6deae375f84b3396a9648722ba62b8@thread.v2
Warnings                          19:b2db6ce5bfb348709dccd9b8f959dfae@thread.v2

Aynı konuya sahip sohbetleri birbirinden ayırmak için sohbet üyeleri (Get-MgChatMembers) veya son güncellemenin zaman damgası gibi diğer ayrıntıları kontrol etmeniz gerekir.

Bir Kanala Temel Notlar ve Yanıtlar Gönderme

Teams, kanal konuşmalarını (mesaj dizilerini) oluşturan mesajları temel notlar ve yanıtlar halinde düzenler. Bu kod, daha önce kullandığımız ekibin Genel kanalının tanımlayıcısını bulur ve yeni bir temel not (konuşma) olarak bir mesaj göndermek için New-MgTeamChannelMessage cmdlet'ini kullanır.

Tüm kanal konuşmalarında olması gerektiği gibi, temel notta kullanıcılara konuşmanın hangi konuyu kapsadığını bildiren bir konu bulunur. Kod aynı zamanda mesajı da işaretler (isteğe bağlı bir adım). Mesaj gönderimi başarılı olursa kod, Get-MgTeamChannelMessage cmdlet'i ile notun ayrıntılarını getirir ve mesajı kimin gönderdiğinin ve gönderim tarihinin ayrıntılarını bildirir.

[array]$TeamChannel = Get-MgTeamChannel -TeamId $Team.Id -Filter "displayName eq 'General'"
$ChatMessageBody = @{}
$ChatMessageBody.Add("contentType", "html")
$ChatMessageBody.Add("content", $Content)
$ChannelMessage = New-MgTeamChannelMessage -TeamId $Team.Id -ChannelId $TeamChannel.Id -Body $ChatMessageBody -Subject "Really Important News" -Importance "urgent"
$MessageContents = Get-MgTeamChannelMessage -TeamId $Team.Id -ChannelId $TeamChannel.Id -ChatMessageId $ChannelMessage.Id
If ($MessageContents) {
    Write-Host ("Channel message posted by {0} at {1}" -f $MessageContents.from.user.displayName, $MessageContents.createdDateTime)
}

Konuşmaya bir yanıt eklemek için New-MgTeamChannelMessageReply cmdlet'ini çalıştırın ve temel notun tanımlayıcısını iletin.

$ReplyMessageBody = @{}
$ReplyMessageBody.Add("contentType", "html")
$ReplyMessageBody.Add("content", "This is a reply...")
$ReplyMessage = New-MgTeamChannelMessageReply -TeamId $Team.Id -ChannelId $TeamChannel.Id -ChatMessageId $ChannelMessage.Id -Body $ReplyMessageBody
If ($ReplyMessage) {
    Write-Host ("Reply posted by {0} at {1}" -f $ReplyMessage.from.user.displayName, $ReplyMessage.createdDateTime) 
}

Şekil 3, temel notun gönderilmesinin sonucunu ve Genel kanala verilen yanıtı göstermektedir.

Daha Fazla Ekip Mesajlaşma Seçeneği

Bu örneklerin, Microsoft Graph PowerShell SDK'sındaki Teams mesajlaşma cmdlet'lerinin nasıl çalıştığına dair bazı bilgiler sunacağını umuyoruz. Mesajlara eklentiler veya sözlerin eklenmesi gibi başka olasılıklar da mevcuttur. Microsoft belgeleri gerekli parametreleri keşfetmenize yardımcı olacaktır, belki de gelecekteki bir makalede bunlara değineceğim.

İlgili makaleler