- はじめに
- いいね一覧を取ろうと思ったきっかけ
- 最終的な完成イメージ
- 途中成果物の完成イメージ
- 必要な事前準備
- 指定したチャネルのいいね一覧を取得するPowerShellソースコード
- 最終的な完成イメージ(再掲)
はじめに
この投稿はOffice365 Advent Calendar 2019 に投稿した内容です。
adventar.org
いいね一覧を取ろうと思ったきっかけ
以下の記事を読んだことが「やってみよう」と思い立ったきっかけです。
コードを書かなくてもPower Automate で情報取得が実現できるのはとても便利です。
blog.intracker.net
この方法を "情報取得ツール"に応用したいと考えました。
「◯◯テナントの情報を取得して」
と依頼されたときに
「(゚◇゚)ゞ 了解。ちゃちゃっと取得します。ツール実行、ぽちっと」
こんな風にひとつのファイルとして完結したツールを実行することでアウトプットが手に入ることが理想です。
今回は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から承認を得る
「アプリケーションのアクセス許可」におけるチャネルメッセージの一覧を取得するAPIはテナント内のすべてのチームの情報にアクセスできるため、 「保護されたAPI(Protected API)」とされています。
保護されたAPIを使用する場合は、マイクロソフトにアプリIDとAPIの使用目的を伝えてAPI使用の承認を得る必要があります。承認を得る前にAPIにリクエストを投げるとエラーが返ってきます。
承認依頼の出し方は下記リンクのDocs の記事を参照してください。
docs.microsoft.com
承認がおりると下図のようなメールが送られてきます。
指定したチャネルのいいね一覧を取得するPowerShellソースコード
ソースコード
下記5つはメモに控えたものに置き換えてください
・【テナントID】
・【クライアントID】
・【クライアントシークレット】
・【チームID】
・【チャネルID】
指定したチャネルのいいね一覧をPowerShellで取得する
#トークンを取得 $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メソッドに渡した返り値で判定できます。
・チャネル名
・スレッドかそれとも返信か
最終的な完成イメージ(再掲)
以上です。