Help us understand the problem. What is going on with this article?

PowerShell を使ってMicrosoft Teams のいいね一覧をCSV形式で出力する

はじめに

この投稿は
Office365 Advent Calendar 2019

の投稿です。

いいね一覧を取ろうと思ったきっかけ

以下の記事を読んだことが「やってみよう」と思い立ったきっかけです。
コードを書かなくてもPower Automate で情報取得が実現できるのはとても便利です。

Microsoft Teamsの特定チャネルのいいねをした人ランキングを作成しよう!その1~Azure ADにアプリを登録する~

この方法を "情報取得ツール"に応用したいと考えました。

「◯◯テナントの情報を取得して」

と依頼されたときに

「(゚◇゚)ゞ 了解。ちゃちゃっと取得します。ツール実行、ぽちっと」

こんな風にひとつのファイルとして完結したツールを実行することでアウトプットが手に入ることが理想です。
今回はGraph API を使うため、事前準備としてAzureADへのアプリ登録だけGUIで行います。

CSV形式にしたのはアウトプットの一例です。
データベースに登録するなり、Power BI のデータセットとして登録するなり、目的応じてアレンジができます。

最終的な完成イメージ

チャネルの会話内に投稿されたリアクションをCSVに一覧出力します。
CSV の1行が1回のリアクションを表します。

リアクションとは、Teams のチャットでできる反応(= いいね、ハート、笑い、びっくり、悲しい、怒り)のことです。

image.png
取得する情報は以下の通りです。
・リアクションの種類(= いいね、ハート、笑い、びっくり、悲しい、怒り)
・リアクションをした日時
・誰がリアクションをしたか(表示名とUPN)
・誰に対してリアクションをしたか(表示名とUPN)
・チャネル名
・スレッドかそれとも返信か
・リアクション対象の投稿内容
・投稿ID
・返信先のID

途中成果物の完成イメージ

PowerShell のソースコード全文を記載すると長くなってしまうので、「指定した特定のチャネルからリアクションを取得する」処理の部分にフォーカスします。

image.png

取得する情報は以下の通りです。
・リアクションの種類(= いいね、ハート、笑い、びっくり、悲しい、怒り)
・リアクションをした日時
・誰がリアクションをしたか(ユーザーID
・誰に対してリアクションをしたか(ユーザーID
・チャネル名
・スレッドかそれとも返信か
・リアクション対象の投稿内容
・投稿ID
・返信先のID

チャネル内の本文を取得するAPIからユーザー名を直接取得することはできません。
ここでとれるのはユーザーIDです。

取得したIDをユーザー情報を取得するAPI に渡すことでユーザー名やUPN、メールアドレスを取得します。後述します。

必要な事前準備

AzureADにアプリを登録

Microsoft Graph API を使うために AzureADにアプリを登録します。
登録方法については下記の記事を参照してください。

Microsoft Teamsの特定チャネルのいいねをした人ランキングを作成しよう!その1~Azure ADにアプリを登録する~

必要なアクセス許可は以下の通りです。
image.png

AzureADアプリをPowerShellで使用するためのIDを入手する

登録したAzureADアプリの下記情報をメモに控えます
・テナントID
・クライアントID
・クライアントシークレット

チームとチャネルのIDを入手する

いいね一覧を取得したいチャネルの下記情報をメモに控えます
・チームID
・チャネルID

取得方法は以下の参照ください。

Microsoft Teamsの特定チャネルのいいねをした人ランキングを作成しよう!その2~GraphAPIで出力を確認しよう~

指定したチャネルのいいね一覧を取得する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)

取得したCSVのイメージ(再掲)

image.png

これを改良して

チーム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メソッドに渡した返り値で判定できます。
・チャネル名
・スレッドかそれとも返信か

最終的な完成イメージ(再掲)

以上です。
image.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした