コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Power Automateの「チャットでメッセージに応答があったとき」トリガーを利用して"Thanks Point"を集計する


スポンサードリンク

はじめに

最近 Power Automate のトリガーとして「チャットでメッセージに応答があったとき」という Teams のトリガーが追加されました。

こちらのトリガーは指定したグループチャット、もしくはチャネルで特定のリアクションが行われたときに反応するトリガーとなっています。

現在ドキュメントは英語のみが提供されています。

learn.microsoft.com

今回はこちらのトリガーの簡単な紹介と、こんなことに使えそう!というものを紹介したいと思います。

チャットでメッセージに応答があったとき

こちらのトリガーは先ほども紹介しましたが、指定したグループチャット、もしくはチャネルで誰かがメッセージに特定のリアクションが行われたときに反応するトリガーとなっています。

パラメーター

追跡する絵文字

トリガーされるリアクションを選択します。
必須パラメーターです。

Teams でメッセージにリアクションするときと同じような感じでリアクションを選択することが可能です。

組織内で設定したカスタム絵文字も選択可能...なのですが、私がブログ作成時ではうまいことプレビューを取得することができなくなっていました...
どうして...

トリガー頻度

すべてのリアクションに対してトリガーするのか最初に行われたリアクションにのみトリガーを行うのかを選択します。
必須パラメーターです。

トリガー対象のユーザー

このフローをトリガーできるのが、自分だけなのか、もしくは全員がトリガーできるのかを選択します。
必須パラメーターです。

特定のユーザーやグループだけ~みたいなことはパラメーターだけではできないです。
リアクションを行ったユーザーの userId は取得できるので、「トリガーの条件」で頑張れば絞ることはできます。

メッセージの種類

グループチャットのリアクションに対してトリガーするのか、チャネルのリアクションに対してトリガーするのかを選択します。
必須パラメーターです。

会話 ID or チャネル

「メッセージの種類」っで「グループチャット」を選択した際は「会話 ID」を、「メッセージの種類」で「チャネル」を選択した際は「チャネル」をそれぞれ指定する必要があります。
それぞれ複数のグループチャット/チャネルを指定することが可能です。
必須パラメーターです。

上記のスクショからわかる通り、「グループチャット」は「会話 ID Item」を選択することができますが、「チャネル」の場合は「チャネル Item」を選択できず、自身でチャネル ID を入力する必要があります。

ただしこれは初回入力時だけですので、一度フローを保存して再度編集を行うことで GUI 上で選択することが可能になります。
なのでチャネルを指定する場合は一度適当な値を入力し、保存してから再度開きなおすといいかもですね。

チーム

「メッセージの種類」で「チャネル」を選択した際に選択します。
どのチームをトリガーの対象にするかを選択します。

必須になってはいないものの設定が必要な項目ですね。

出力

こちらのトリガーは以下のような出力結果を返します。

{
    "headers": {
        "Host": "prod-03.japaneast.logic.azure.com",
        "Max-Forwards": "10",
        "Request-Id": "|132dc9729b7855fcbc90c477594e28b1.72a75d7bd4624201.",
        "traceparent": "00-132dc9729b7855fcbc90c477594e28b1-72a75d7bd4624201-00",
        "X-ARR-LOG-ID": "196a6730-be13-441f-8812-5666aec20c0c",
        "CLIENT-IP": "52.112.125.90:22673",
        "DISGUISED-HOST": "prod-03.japaneast.logic.azure.com",
        "X-SITE-DEPLOYMENT-ID": "flowfe-prod-kw-rp00-app-01__937c",
        "WAS-DEFAULT-HOSTNAME": "flowfe-prod-kw-rp00-app-01.flow-prod-kw-rp00-ase-01.p.azurewebsites.net",
        "X-Forwarded-Proto": "https",
        "X-AppService-Proto": "https",
        "X-ARR-SSL": "2048|256|CN=Microsoft Azure RSA TLS Issuing CA 04, O=Microsoft Corporation, C=US|CN=japaneast.logic.azure.com, O=Microsoft Corporation, L=Redmond, S=WA, C=US",
        "X-Forwarded-TlsVersion": "1.3",
        "X-Forwarded-For": "52.112.125.90:22673",
        "X-Original-URL": "/workflows/b9dabd4a8d2044c1ad9142e75912af0c/triggers/...",
        "X-WAWS-Unencoded-URL": "/workflows/b9dabd4a8d2044c1ad9142e75912af0c/triggers/...",
        "Content-Length": "610",
        "Content-Type": "application/json; charset=utf-8"
    },
    "body": {
        "messageReaction": "powerautomate",
        "reactionDateTime": "2025-07-30T08:44:59.96+00:00",
        "userId": "e1816e20-9788-43ef-a7f7-a415a67884d7",
        "messageId": "1738824753188",
        "messageLink": "https://teams.microsoft.com/l/message/19%3Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%40thread.tacv2/1738824753188?groupId=xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx&tenantId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&createdTime=1738824753188&parentMessageId=1738824753188",
        "threadType": "channel",
        "teamId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
        "channelId": "19:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@thread.tacv2"
    }
}

動的なコンテンツとして選択可能な項目は以下です。

どういうときトリガーする?

トリガーに設定したリアクションがチャネル or グループチャットで行われた場合にトリガーされますが、以下のようなシナリオの際にトリガーされます。

  • メッセージにリアクションした場合
  • メッセージの返信にリアクションした場合
  • リアクションを取り消して再度リアクションした場合

最後のトリガーシナリオが少し厄介なのではないかな。と思っています。

おおよそのシナリオの場合、1メッセージに対して1人のユーザーのリアクションは1として処理したい場合がほとんどだと思いますので、なんらかの対策が必要になってくると思います。
例) リアクションを付けたり消したりしたからといって複数処理は行いたくない。

例えばこんな使い方ができる!

コミュニティ貢献ポイントの記録

たとえば、社内コミュニティの会話の場として Teams を利用している場合などで、他者に対して役に立つ情報を提供したり、質問に回答したりなど、なんらかの貢献を行った人を可視化したい場合の方法の1つとして、このトリガーを活用することができます。

特定のユーザーがコミュニティ内のユーザーからどれだけ頼られていて、どんな貢献を行っているのか?というのを可視化する仕組みづくりですね。

構成

仕組みとしてはざっくり以下のようになっています。

Dataverse を利用していますが、SharePoint List でも問題ないです。

後述しますが、Teams のチャネルでのメッセージは通常(単一)のメッセージと返信の2種類があります。
このことに気を付けてフローを構成しないといけないです。

Dataverse

Dataverse テーブルとしては以下2つのテーブルを作成しています。

リレーションシップは以下のように設定してます。

Message テーブルはリアクションが行われたメッセージを格納しています。
Reaction User テーブルには対象のメッセージにリアクションを付けた人一覧を格納しています。

Power Automate

フローの構成としてこんな感じです。

「チャットでメッセージに応答があったとき」トリガーでは誰がメッセージを投稿したのか?がわからないので、まずは投稿されたメッセージの詳細を取得する必要があります。

しかし、標準アクションの「メッセージの詳細を取得する」では通常のメッセージと返信、両方のタイプを取得することはできません。

したがって Graph API を実行して両方のタイプのメッセージを取得できるようにします。

実行する API はこちらです。

learn.microsoft.com

通常のメッセージを取得したい場合は /messages/{message-id} なのに対し、返信を取得したい場合は /messages/{message-id}/replies/{reply-id} となります。

したがって、以下のように URI を組み立てます。

URI

https://graph.microsoft.com/v1.0/teams/@{triggerOutputs()?['body/teamId']}/channels/@{triggerOutputs()?['body/channelId']}/messages/@{if(
  empty(triggerOutputs()?['body/replyToId']),
  triggerOutputs()?['body/messageId'],
  concat(
    triggerOutputs()?['body/replyToId'],
    concat(
      '/replies/', 
      triggerOutputs()?['body/messageId']
    )
  )
)}?$expand=replies

続いて、 Message テーブルにデータを追加する処理を行います。
ここの追加はまだテーブルに対象の "Message ID" が含まれてなければ新規作成を、あればなにもしない。という処理が必要です。

ただ後続の処理でこのテーブルのレコード情報を用いて処理をする必要があるため条件分岐を追加して処理を作成してしまうと、データの取り扱いがちょっとめんどくさいです。

なので「行をアップサートする」アクションを利用します。

learn.microsoft.com

アップサートアクションは、既存のレコードを更新する場合は既存レコードの一意識別子(GUID)を、新規作成する場合は既存テーブルに存在しない GUID を指定する必要があります。

したがってまずは既存テーブルに "Message ID" が含まれているかどうかを「行を一覧にする」アクションで判断します。

行のフィルター

cr115_messageid eq '@{body('Microsoft_Graph_HTTP_要求を送信する')?['id']}'

その結果を持ってアップサート処理を行います。

行ID

@{if(
    empty(outputs('行を一覧にする_-_対象メッセージの処理')?['body/value']?[0]?['cr115_thankspointmessageid']),
    guid(),
    outputs('行を一覧にする_-_対象メッセージの処理')?['body/value']?[0]?['cr115_thankspointmessageid']
)}

新規作成である場合は guid() 関数で GUID の生成を行っています。
厳密にいうと、既存テーブルに存在しない GUID() の生成が必要ではあるものの、 GUID が被ることはまずないと思いますので、無視しています。

ちなみにアップサートの更新処理は、更新する値が同じなのであればレコードの更新は行われません(修正日は変わらない)

最後にリアクションを行った人の登録処理ですね。
これは先ほどとほぼ同じ処理で実行が可能です。

まず既にそのユーザーが過去にリアクション済みか?を確認するには「Message ID と User ID が同じ組み合わせが存在しないこと」の確認が必要です。

ここで気を付ける必要があるのはこのテーブルの "Message ID" は検索値(リレーション)であるということですね。

検索値や選択肢の場合、「[論理名]value」形式で列を指定する必要があります。

行のフィルター

_cr115_messageid_value eq '@{outputs('行をアップサートする_-_対象メッセージの処理')?['body/cr115_thankspointmessageid']}' and cr115_reactionuserid eq '@{triggerOutputs()?['body/userId']}'

あとは同じくアップサート処理を実施して完了ですね。

これでデータ自体の準備は完了しましたので適宜可視化などを行ってください。

ポイント集めてどうするの?

コミュニティ管理者目線

コミュニティ管理者としてこのデータの活用は単純ですね。

コミュニティ内で貢献度が高いユーザーの特定や、みんながポジティブな興味関心を持っている投稿を特定することができます。

この情報をもとに、そのユーザーに社内イベントでの登壇依頼や、投稿をもとに新たなコンテンツ作成などができると思います。

コミュニティ参加者目線

こちらはコミュニティ管理グループ、もしくは経営層によるなんらかの支援が必要になっては来ますが、以下のような施策に活用することができます。

  • ポイントを社内マネーとして利用できるようにして、書籍購入補助やオフィスグリコとの交換などができるようにする
  • ポイントをゲーミフィケーションに活用して、デジタルコンテンツの交換やキャラクターのレベルアップなどが行えるようにする

上記のような施策を実施することで、コミュニティでの貢献対してコミュニティメンバーになんらかのベネフィットを明確に提示できるようになりますので、所謂やりがい搾取とならないようなコミュニティ運営を行うことができるようになります。

やっぱり頑張ってる人にはそれなりのリターンを与えてあげたいですしね。

おわりに

Teams のリアクションを活用できる面白いトリガーが追加されていたので、紹介も兼てブログにまとめてみました。

このトリガーで微妙に痒いところに手が届かないのがリアクションを取り消されたときはトリガーできない点ですね。
私が紹介したような施策に繋げるとすると、場合によっては予算が必要になってくるので厳密な管理が必要になってくる可能性があると思います。   現状そこまで厳密にしたければ定期的に棚卸を行うようなフローを作成して実行しないけないですかね。  

ただ取り消しを行うとすると、間違えて特定のリアクションつけちゃった~とかだと思いますが、それそこまで厳密に管理する??というのはちょっと協議した方が良いんじゃないかな?と思います。  

活用事例の技術的な詳細の部分はだいぶ雑に描いちゃったところがあるのでまた別でブログにしようかな?と思っています。(多分。Maybe.)


スポンサードリンク