13
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-12-08

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 のチャットでできる反応(= いいね、ハート、笑い、びっくり、悲しい、怒り)のことです。

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
・クライアントシークレット

##保護されているAPIの使用についてMSから承認を得る

※この章は2020/10/22 に追記しました

「アプリケーションのアクセス許可」におけるチャネルメッセージの一覧を取得するAPIはテナント内のすべてのチームの情報にアクセスできるため、 **「保護されたAPI(Protected API)」**とされています。

保護されたAPIを使用する場合は、マイクロソフトにアプリIDとAPIの使用目的を伝えてAPI使用の承認を得る必要があります。承認を得る前にAPIにリクエストを投げるとエラーが返ってきます。

承認依頼の出し方は下記リンクのDocs の記事を参照してください。
Microsoft Teams の保護された API
image.png

承認がおりると下図のようなメールが送られてきます。
image.png

チームとチャネルの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

13
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?