2020/10/22 に以下の章を追記しました
・保護されているAPIの使用についてMSから承認を得る
#はじめに
この投稿は
Office365 Advent Calendar 2019
の投稿です。
#いいね一覧を取ろうと思ったきっかけ
以下の記事を読んだことが「やってみよう」と思い立ったきっかけです。
コードを書かなくてもPower Automate で情報取得が実現できるのはとても便利です。
Microsoft Teamsの特定チャネルのいいねをした人ランキングを作成しよう!その1~Azure ADにアプリを登録する~
この方法を "情報取得ツール"に応用したいと考えました。
「◯◯テナントの情報を取得して」
と依頼されたときに
「(゚◇゚)ゞ 了解。ちゃちゃっと取得します。ツール実行、ぽちっと」
こんな風にひとつのファイルとして完結したツールを実行することでアウトプットが手に入ることが理想です。
今回はGraph API を使うため、事前準備としてAzureADへのアプリ登録だけGUIで行います。
CSV形式にしたのはアウトプットの一例です。
データベースに登録するなり、Power BI のデータセットとして登録するなり、目的応じてアレンジができます。
#最終的な完成イメージ
チャネルの会話内に投稿されたリアクションをCSVに一覧出力します。
CSV の1行が1回のリアクションを表します。
リアクションとは、Teams のチャットでできる反応(= いいね、ハート、笑い、びっくり、悲しい、怒り)のことです。
取得する情報は以下の通りです。
・リアクションの種類(= いいね、ハート、笑い、びっくり、悲しい、怒り)
・リアクションをした日時
・誰がリアクションをしたか(表示名とUPN)
・誰に対してリアクションをしたか(表示名とUPN)
・チャネル名
・スレッドかそれとも返信か
・リアクション対象の投稿内容
・投稿ID
・返信先のID
#途中成果物の完成イメージ
PowerShell のソースコード全文を記載すると長くなってしまうので、「指定した特定のチャネルからリアクションを取得する」処理の部分にフォーカスします。
取得する情報は以下の通りです。
・リアクションの種類(= いいね、ハート、笑い、びっくり、悲しい、怒り)
・リアクションをした日時
・誰がリアクションをしたか(ユーザーID)
・誰に対してリアクションをしたか(ユーザーID)
・チャネル名
・スレッドかそれとも返信か
・リアクション対象の投稿内容
・投稿ID
・返信先のID
チャネル内の本文を取得するAPIからユーザー名を直接取得することはできません。
ここでとれるのはユーザーIDです。
取得したIDをユーザー情報を取得するAPI に渡すことでユーザー名やUPN、メールアドレスを取得します。後述します。
#必要な事前準備
##AzureADにアプリを登録
Microsoft Graph API を使うために AzureADにアプリを登録します。
登録方法については下記の記事を参照してください。
Microsoft Teamsの特定チャネルのいいねをした人ランキングを作成しよう!その1~Azure ADにアプリを登録する~
AzureADアプリをPowerShellで使用するためのIDを入手する
登録したAzureADアプリの下記情報をメモに控えます
・テナントID
・クライアントID
・クライアントシークレット
##保護されているAPIの使用についてMSから承認を得る
※この章は2020/10/22 に追記しました
「アプリケーションのアクセス許可」におけるチャネルメッセージの一覧を取得するAPIはテナント内のすべてのチームの情報にアクセスできるため、 **「保護されたAPI(Protected API)」**とされています。
保護されたAPIを使用する場合は、マイクロソフトにアプリIDとAPIの使用目的を伝えてAPI使用の承認を得る必要があります。承認を得る前にAPIにリクエストを投げるとエラーが返ってきます。
承認依頼の出し方は下記リンクのDocs の記事を参照してください。
Microsoft Teams の保護された API
チームとチャネルのIDを入手する
いいね一覧を取得したいチャネルの下記情報をメモに控えます
・チームID
・チャネルID
取得方法は以下の参照ください。
Microsoft Teamsの特定チャネルのいいねをした人ランキングを作成しよう!その2~GraphAPIで出力を確認しよう~
#指定したチャネルのいいね一覧を取得するPowerShellソースコード
##ソースコード
下記5つはメモに控えたものに置き換えてください
・【テナントID】
・【クライアントID】
・【クライアントシークレット】
・【チームID】
・【チャネルID】
#トークンを取得
$url = "https://login.microsoftonline.com/【テナントID】/oauth2/token"
$body = @{
"grant_type" = 'client_credentials'
"resource" = 'https://graph.microsoft.com'
"client_id" = '【クライアントID】'
"client_secret" = '【クライアントシークレット】'
}
$contentType = "application/x-www-form-urlencoded"
$oauth = Invoke-RestMethod -uri $url -Method post -Body $body -ContentType $contentType
#チャネル内のスレッドをすべて取得
$url = "https://graph.microsoft.com/beta/teams/【チームID】/channels/【チャネルID】/messages/" -f $channel.id
$headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}
$contentType = "application/json"
$responseFromAPI = Invoke-RestMethod -uri $url -Method Get -header $headerParams -ContentType $contentType
$messagesWithOutReply = @()
$messagesWithOutReply += $responseFromAPI.value
$messagesWithReply = @()
$messagesWithReply += $responseFromAPI.value
#返信をすべて取得
foreach($m in $messagesWithOutReply)
{
$url = "https://graph.microsoft.com/beta/teams/0ad9e708-d8ef-4f9f-9188-6b2f875c0cf0/channels/19:aba0636cec624f7e8fa720cf10f8ec4c@thread.skype/messages/{0}/replies" -f $m.id
$headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}
$ContentType = "application/json"
$responseFromAPI = Invoke-RestMethod -uri $url -Method Get -header $headerParams -ContentType $ContentType
$messagesWithReply += $responseFromAPI.value
}
#いいねをCSVに出力
foreach($message in $messagesWithReply)
{
if($message.reactions.Count -eq 0)
{
continue
}
$reactions = @()
$reactions += $message.reactions
foreach($reaction in $reactions)
{
$obj = New-Object PSObject | Select "ReactionType","CreatedDateTime","From","To","Content","ID","ReplyToID"
#リアクションの種類
$obj.ReactionType = $reaction.reactionType
#リアクションをした日時
$obj.CreatedDateTime = $reaction.createdDateTime
#誰がリアクションをしたか
$obj.From = $reaction.user.user.id
#誰に対してリアクションをしたか
$obj.To = $message.from.user.id
#リアクション対象の投稿内容
$obj.Content = $message.body.content
#投稿ID
##スレッドでも返信でも投稿IDを持っている
$obj.ID = $message.id
#返信先のID
##この値が空白値の場合は返信ではなくスレッド
$obj.ReplyToId = $message.replyToId
$obj | Export-Csv -Path ".\output.csv" -Encoding UTF8 -NoTypeInformation -Append
}#foreach($reaction in $reactions)
}#foreach($message in $messagesWithReply)
##これを改良して
チームIDをAPIに渡してチャネル一覧をPowerShellの処理内で取得するようにします
https://graph.microsoft.com/beta/teams/【チームID】/channels
ユーザーIDをAPIに渡してユーザー名とUPNをPowerShellの処理内で取得するようにします
https://graph.microsoft.com/v1.0/users/【ユーザーID】
加えて、下記2つも出力対象にします。
後者は「返信先のID」をIsNullOrEmptyメソッドに渡した返り値で判定できます。
・チャネル名
・スレッドかそれとも返信か