- はじめに
- Teams の新しいチャネルエクスペリエンスでは情報ペインが既定でOnに
- 【重要】非公開のAPIを利用しており一切のサポートはありません
- 事前準備
- Power Automate クラウドフローを作成する
- Power Apps for Teamsでアプリを作成する
- 動作イメージ
- 今後改善したい事
- さいごに
- 参考にしたページ
はじめに
Teams チャネルのメッセージのピン留め機能使っていますか?チャットの場合は画面上部に固定表示される非常に分かりやすい機能ですが、チャネルの場合はピン留めされたメッセージを確認する為には情報ペインを開くひと手間が必要でその存在を知らない方も少なくないのではと思います。
今回は以前作成したPower Automateフローを応用してチャネルのタブとしてピン留めメッセージを表示するPower Appsアプリを作ってみました。
以前の記事はこちらです。
Teams の新しいチャネルエクスペリエンスでは情報ペインが既定でOnに
Teams のチャネルが2023年7月下旬から展開予定の新しいチャネルエクスペリエンスでは、情報ペインが既定で表示されるように変わるようです。情報ペインが表示されていればピン留めメッセージへのアクセスも容易になります。このアプリは必要なくなってしましましたが記録として残しておきます。
【重要】非公開のAPIを利用しており一切のサポートはありません
このアプリのPowerAutomateフローでは文書化されていない Teams ネイティブな? API を使用しています。本来使われる想定がない形で機能を使用していますのである日突然使えなくなってしまう可能性もあります。マイクロソフト社のサポート対象外の使い方になりますので、運用環境では使用しない方が良いかと思います。
事前準備
今回のアプリはPowerApps for Teamsで作成しました。
アプリはチームに作成します。今回作成するチームにアプリを作成したことが無い場合は、下記の操作を行い環境を作成します。
Teams のウィンドウ左側のアプリバーからPower Appsにアクセスします。
「今すぐ始める」をクリック
アプリを配置するチームを選択し「作成」します。
初めてアプリをチームに作成する場合はしばらく待ちます。
Power Automate クラウドフローを作成する
ピン留めメッセージの情報を取得するフローを作成します。
PowerAutomateにアクセスし、右上の環境をクリックしアプリを作成するチーム名の環境を選択してからフローを作成します。
PowerApps内からフローを作成する事もできますが、こちらの方がおすすめです。
「listPinnedMessagesOnChannel_V3」フロー全体
フロー解説
1.PowerAppsから2つのパラメーターを渡しますので、既定で追加されているPowerAppsトリガーを削除し、PowerApps(V2)トリガーを追加します。
- generalChannelId
- 一般チャネルのId
- targetChannelId
- ピン留めの情報を取得するチャネルId
2.SharePointコネクタ-「SharePointにHTTP要求を送信します」アクションでピン留め情報を取得します。
このような形で取得できるはずです。
3.HTTP要求の結果をjson解析する際のスキーマ定義はこちらです。
{ "type": "object", "properties": { "messages": { "type": "array", "items": { "type": "object", "properties": { "messageType": { "type": "string" }, "content": { "type": "string" }, "clientMessageId": { "type": "string" }, "imDisplayName": { "type": "string" }, "properties": { "type": "object", "properties": { "importance": { "type": "string" }, "languageStamp": { "type": "string" }, "pinned": { "type": "string" }, "edittime": { "type": "integer" }, "ams_references": { "type": [ "array", "null" ] } } }, "id": { "type": "string" }, "type": { "type": "string" }, "composeTime": { "type": "string" }, "originalArrivalTime": { "type": "string" }, "containerId": { "type": "string" }, "parentMessageId": { "type": "string" }, "from": { "type": "string" }, "sequenceId": { "type": "integer" }, "version": { "type": "integer" }, "threadType": { "type": [ "string", "null" ] }, "isEscalationToNewPerson": { "type": "boolean" }, "contentType": { "type": [ "string", "null" ] }, "fromTenantId": { "type": [ "string", "null" ] }, "amsReferences": { "type": [ "array", "null" ] } }, "required": [ "messageType", "content", "clientMessageId", "imDisplayName", "properties", "id", "type", "composeTime", "originalArrivalTime", "containerId", "parentMessageId", "from", "sequenceId", "version", "threadType", "isEscalationToNewPerson" ] } } } }
4.PowerAppsで扱いやすいように データ操作-選択アクションで、必要な項目のみを選択します。
アイテム名 | 説明 |
---|---|
imDIsplayName | メッセージ投稿者表示名 |
content | メッセージ本文 |
subject | メッセージ件名 |
title | メッセージアナウンスタイトル |
webUrl |
メッセージリンクURL https://teams.microsoft.com/l/message/@{triggerBody()['text_2']}/@{item()?['id']}?parentMessageId=@{item()?['parentMessageId']} |
originalArrivalTime |
メッセージ投稿日時 convertFromUtc( item()?['originalArrivalTime'], 'Tokyo Standard Time', 'yyyy/MM/dd HH:mm:ss' ) |
from | メッセージ投稿者ユーザーId |
pinned | ピン留めしたユーザーIdとピン留めした日時のjson |
5.選択アクションの出力をPowerAppsに返します。
[ { "imDisplayName": "アライ クマ", "content": "<div>\r\n<div itemprop=\"copy-paste-block\">\n\r\n<ol style=\"font-size:16px\">\r\n\n\t\r\n<li>こんにちは!お昼ご飯は何を食べましたか?</li>\n</ol>\r\n\n</div>\n</div>", "subject": null, "title": null, "webUrl": "https://teams.microsoft.com/l/message/19:216740c0e6ca410a9d195953f8c37bba@thread.tacv2/1684497743914?parentMessageId=1684497743914", "originalArrivalTime": "2023/05/19 21:02:23", "from": "8:orgid:554f5e22-01b6-4a45-94bf-83044398ea99", "pinned": "{\"creatorId\":\"8:orgid:448060bd-fe71-424f-b70b-3456084c7ffd\",\"pinnedTime\":1684752709594}" },
【中略】
{ "imDisplayName": "ジャイアント パンダ", "content": "<p>猫を吸います!!!</p>", "subject": null, "title": null, "webUrl": "https://teams.microsoft.com/l/message/19:216740c0e6ca410a9d195953f8c37bba@thread.tacv2/1689250255589?parentMessageId=1684498142076", "originalArrivalTime": "2023/07/13 21:10:55", "from": "8:orgid:5e41bcfc-97b9-40ec-9f2c-8bef94b140d7", "pinned": "{\"creatorId\":\"8:orgid:479e2162-2151-4005-88c4-2029412d46b2\",\"pinnedTime\":1689291239743}" } ]
以上でフローの作成は完了です。
Power Apps for Teamsでアプリを作成する
アプリを作成する
Teams のウィンドウ左側のアプリバーからPower Appsにアクセスします。
ビルド→指定したチーム→新規→アプリ
データ接続の作成
「Microsoft Teams」を追加
「データの追加」→「データソースの選択」で検索欄で「Teams」と検索すると表示される「Microsoft Teams」コネクタを選択します。
「Office 365 ユーザー」を追加
同様に「Office 365 ユーザー」も追加します。
PowerAutomate フローを追加
フローの追加から上の手順で作成した「listPinnedMessagesOnChannel_V3」を追加します。
画面の構成
下図のような形で画面を構成します。
Screen1
OnVisible
Screen1が表示されたときに下記を実行するよう構成します。
OnVisibleをクリックし入力バーに下記のコードを入力します。
UpdateContext({ channelId:Teams.ThisChannel.Id, channelIdGeneral:Teams.ThisTeam.Id }); ClearCollect(colJson, listPinnedMessagesOnChannel_V3a.Run(channelIdGeneral,channelId) );
ClearCollect(colMessages, ForAll( Table(ParseJSON(First(colJson).json)),{ imDIsplayName: Text(ThisRecord.Value.imDisplayName), context: PlainText(Text(ThisRecord.Value.content)), subject: Text(ThisRecord.Value.subject), title: Text(ThisRecord.Value.title), webUrl: Text(ThisRecord.Value.webUrl), teamsUrl: Text(ThisRecord.Value.teamsUrl), originalArrivalTime: Text(ThisRecord.Value.originalArrivalTime),
from: Text(ThisRecord.Value.from),
pinnedTime: Text(ParseJSON(Text(ThisRecord.Value.pinned)).pinnedTime)
} ) );
- Teams統合オブジェクトから必要な情報を取得
Teams統合オブジェクトからチームId, 一般チャネルのチャネルId, ピン留めを取得するチャネルIdを取得します。 - 取得した値をPowerAutomate フローに引き渡して実行
Power Automateフローを実行し返されたJSONをコレクションcolJSONに格納します。 - JSONをパースしてコレクションに格納
colJSONの値をParseJSON関数でパースしてコレクションcolMessagesに格納します。この時、pinnedの値はJSONになっていますので、さらにparseJSON関数でパースしてpinnedTimeのみ取り出しています。
※Teams統合オブジェクトを参照しているとPowerApps for Teams内でアプリをプレビュー実行した場合には値を取得できません。その為上記のようにコレクションの中を確認することができません。上記はTeams統合オブジェクトを使用しないプロトタイプ版アプリで取得した際のコレクションです。
IconRefresh
OnSelect
Screen1 OnVisibleと同じ処理をコピペします。
LabelPinnedCount
Text
Itemsを選択し入力バーに下記のコードを入力します。
ピン留めメッセージの件数を表示します
CountRows(colMessages) & " 件のピン留めメッセージ"
Gallery1
Items
Itemsを選択し入力バーに下記のコードを入力します。colMessages を ピン留め日付の降順でソートしてます。
SortByColumns(colMessages,"pinnedTime",SortOrder.Descending)
OnSelect
OnSelectを選択し入力バーに下記のコードを入力します。
Launch( If(Param("hostClientType") = "desktop", Substitute(ThisItem.webUrl,"https://","msteams://"), ThisItem.webUrl ) )
Launch関数でURLを開きます。Param("hostClientType")で、現在実行中のクライアントタイプが取得できます(desktop, Web iOS, Android ...) Teamsデスクトップアプリで起動している場合のみ「msteams://teams.micro...」を起動し、その他では「http://teams.microsoft...」を起動します。こうする事で、Teamsデスクトップアプリ内でダイレクトにメッセージを開くことができます。
Subtitle1
Text
Itemsを選択し入力バーに下記のコードを入力します。
メッセージ投稿者とメッセージ投稿日時を表示します
ThisItem.imDIsplayName & " " & ThisItem.originalArrivalTime
Title1
Text
Textを選択し入力バーに下記のコードを入力します。
アナウンスタイトル, 件名, 本文を表示します
ThisItem.title & " " & ThisItem.subject & " " & ThisItem.content
ImageProfile
Image
Imageを選択し入力バーに下記のコードを入力します。
If(Len(ThisItem.from)>0, Office365ユーザー.UserPhotoV2( Substitute( ThisItem.from, "8:orgid:", "" ) ), "" )
PowerAutomateフローが返したfrom(ユーザーid)でユーザーのプロファイル画像を取得しています。fromの値の"8:orgid:"は、Office365ユーザー.UserPhotoV2のパラメーターには不要な為取り除いています。
"8:orgid:35975ed9-608b-408a-a362-19c1f3e1e844"
RadiusTopLeft, RadiusTopRight, RadiusBottomLeft, RadiusBottomRight
4つの値を24と設定することで、ユーザープロファイル画像を丸く表示します。
※Height ,Widhともに48で設定しています。
その他の位置調整やデザインなどはお好みで調整してください。
以上で完了です。
動作イメージ
実際に動作させた場合のイメージはこちらの動画のようなイメージになります。
これで一旦区切り。 pic.twitter.com/oGf8XDpwET
— Sasami (ささみ) (@sasami_axis) 2023年7月17日
今後改善したい事
- PowerAutomateを使わずにAPIをよぶ
- できるかな?
- ピン留めの解除
- ピンの画像クリックでピン止め解除を行う動作をしたい
- APIでの実現手段は確認できているので実装する見込みはあります。
- レスポンシブ対応
- 今回雰囲気でコンテナを使ってみましたがレスポンシブではありません。
さいごに
"ピン留めメッセージがもっとアクセスしやすかった便利じゃないかな?"のアイデアだけで突っ走って作ってみました。アイデア先行でアプリとしてはまだまだ作り込みが必要なレベルかと思います。
今回Teams統合オブジェクトを使用して現在のチャネルのIdと一般チャネルのIdを取得しています。Teams統合オブジェクトはアプリのプレビューでは値が取得できません。まずはじめはTeams統合オブジェクトを使わずにチーム・チャネルを指定する機能をつけてテストを行うと捗りました。
参考にしたページ
色々な有用な情報を公開していただいている皆さんに感謝です。
PowerAppsでのJSONのパースについて
Teams統合オブジェクトについて
hostClientTypeの値について