マイルストーン サンプル アプリで作業項目の状態が更新されたときにチームに通知を送信する
Microsoft Teams のマイルストーン サンプル アプリでは、すべてのマイルストーンにおけるプロジェクトの作業項目の進行状況を追跡することができます。 このアプリでは作業項目の更新や保持が可能ですが、現時点では作業項目の更新をチームに通知する標準的なプロセスは用意されていません。
この記事では、Power Automate フローを作成して、作業項目の状態が変化したときに (アプリがインストールされている) チームに通知のアダプティブ カードを送信する方法を学習します。
このビデオでは、マイルストーン サンプル アプリで作業項目の状態が更新されたときにチームへの通知を設定する方法について説明しています:
前提条件
この演習を完了するには、選択した Microsoft 365 サブスクリプションの一部として利用できる Teams にログインする機能と、Teams 用マイルストーン Power Apps テンプレートをインストールしておく必要があります。 このアプリは https://aka.ms/TeamsInspection からインストールできます。
マイルストーン アプリにログインする
左側にある Power Apps アイコンを選択し、ビルド タブに移動します。
左側のアプリ メニューで、マイルストーン アプリがインストールされているチームを選択します。
インストールされているアプリ を選択し、マイルストーンを選択して開きます。 マイルストーン アプリが開きます。
Power Automate フローを呼び出す条件を追加する
左側のペインのツリー ビューで、プロジェクト 画面を選択します。
画面上で Alt キーを押しながら開きたいプロジェクトを 1 つ選択します。 作業項目の追加/編集画面が開きます。
完了 ボタンを選択します。
完了ボタンの OnSelect プロパティを選択します。
完了 ボタンを選択した後、バックグラウンドで実行される他の更新に加えて、作業項目の状態が更新されたときにチームに通知のアダプティブ カードを送信するフローがトリガーされるようにします。 この変更を加えるには、OnSelect 式の先頭に以下を追加します。
If( locEditWorkItem, //adding code to call a flow when status changes If( locSelectedWorkItem.'Work Item Status'.'Project Work Item Status' \<\> cmbAddWorkItemStatus.Selected.'Project Work Item Status', true //your flow call will come here );完了 ボタンの OnSelect プロパティからコード全体をコピーし、テキスト エディターに貼り付けておきます。
上部リボンの 設定 の横にある ... (省略記号) を選択し、Power Automate を選択します。
データ ポップアップが開き、新しいフローの作成 オプションが表示されます。
新しいフローの作成 ボタンを選択します。 ブラウザー ウィンドウが開き、新しい Power Automate フロー画面が表示されます。
フローの名前を「作業指示書の状態が変化したときに通知のアダプティブ カードを送信する」に更新します。
トリガーのリストから、Power Apps をトリガーするオプションを選択します。 新しいフローが作成され、画面に Power Apps のステップが読み込まれます。
Power Automate フローを作成する
前のセクションのステップを実行した後、+新規 ステップ ボタンを選択します。
アクション ID で行を取得する を選択し、テーブル名として プロジェクト作業項目 を選択します。
行 ID の下で動的コンテンツを開き、Power Apps で質問する オプションを選択します。
ステップの名前を「作業項目の取得レコード」に変更します。
+新規 ステップ ボタンをもう一度選択します。アクション ID で行を取得する を選択し、テーブル名として 作業項目の状態 を選択します。
行 ID の下で動的コンテンツを開き、作業項目の状態 (値) を選択します。
ステップの名前を「作業項目の状態を取得レコード」に変更します。
+新規 ステップを選択してステップをもう 1 つ追加します。
変数の初期化アクションを追加します。
ステップの名前を変更して変数を初期化 - カード タイトル
名前 - 「varCardTitle」
種類 - 「文字列」
値 = 作業項目の状態を更新 {次に、ステップ 3 で追加した作業項目の動的コンテンツ名を選択する}
+新規 ステップを選択してステップをもう 1 つ追加します。
変数の初期化アクションを追加します。
- ステップの名前を変数の初期化 - リンクの確認に変更
- 名前-「varReviewWorkItemLink」
- 種類 - 「文字列」
- 値 - 空白にする - は後で追加されます。
注意
新しいステップを追加すると、フロー チェッカーに警告が表示される場合があります。 フローが Power Apps アプリから呼び出されるため、この警告が予期されます。また、Power Apps アプリから呼び出されたフローに新しいステップを追加すると、アプリとの接続を切断する場合があります。 演習の後半で、この警告を修正するためにフローへの接続を置き換えます。
作業項目のリンクを確認 アクションには、アプリへのリンクを使用します。 このリンクを見つけるには、マイルストーン アプリがインストールされているチームを開き、アプリがインストールされているタブのリンクをコピーします。 タブへのリンクをコピーするには、タブを開いてから右上隅にある ..。 (省略記号) を選択します。
URL は、次の例のようになります。
https://teams.microsoft.com/l/entity/GUID/_djb2_msteams_prefix_956529380?context=%7B%22subEntityId%22%3Anull%2C%22channelId%22%3A%2219%3AGUID%40thread.tacv2%22%7D&groupId=GUID&tenantId=GUID続行するには、URL のうち、context= に続く部分をコピーし、https://www.urldecoder.org/ などの URL デコーダーを使って URL をデコードします。
デコードしたテキストをコピーし、Power Automate フローに戻ります。
変数の初期化に戻る - 作業項目リンク ste のレビュー。
[値] フィールドを、前にコピーしたデコード URL テキストに設定します。
作成 アクションを含む新しいステップを追加し、入力 フィールドに次のスニペットを貼り付けます。
replace(replace(replace(variables('varReviewWorkItemLink'),'{','%7B'),'"','%22'),'}','%7D')+新しいステップ を選択してステップをもう 1 つ追加します。
チャットやチャネルにアダプティブ カードを投稿する (プレビュー) アクションを選択します。
投稿者 - ユーザー
投稿先 - チャネル
チーム - {アプリがインストールされているチーム}
チャネル - 全般
アダプティブ カード - 次の JSON コードを貼り付けます。
注意
次の JSON コードには、前のフロー ステップの値への動的な参照が含まれています。 これらは自動的に正しい参照に解決されるはずですが、解決しない場合は、正しい参照で手動で更新してください。 例えば、@{outputs('Get_Work_Item_Status_record')?['body/msft_name']} は [作業項目ステータスの取得] ステップの名前列を参照します。
{ "type": "AdaptiveCard", "body": [ { "type": "TextBlock", "size": "large", "weight": "Bolder", "text": "Status Update for @{outputs('Get_Work_Item_record')?['body/msft_name']}", "wrap": true }, { "type": "TextBlock", "text": "Status for Work Item '@{outputs('Get_Work_Item_record')?['body/msft_name']}' has been updated to @{outputs('Get_Work_Item_Status_record')?['body/msft_name']}", "wrap": true } ], "actions": [ { "type": "Action.OpenUrl", "title": "View @{variables('varCardTitle')}", //Update the part of the following URL before "context=" with the URL copied in step 12. "url": "[https://teams.microsoft.com/l/entity/040880f4-0c68-4c38-8821-d5efd2b6ddbe/_djb2_msteams_prefix_956529380?context=@{outputs('Compose](https://teams.microsoft.com/l/entity/040880f4-0c68-4c38-8821-d5efd2b6ddbe/_djb2_msteams_prefix_956529380?context=@%7boutputs('Compose)')}" } ], "$schema": "<http://adaptivecards.io/schemas/adaptive-card.json>", "version": "1.2" }
フローを保存します。
Power Appsからフローをトリガーする
フローを保存したら、Teams に戻り、Power Apps でアプリを開きます。
ツリー ビューで 作業項目の追加/編集 画面を選択します。
更新 をクリックします。
OnSelect プロパティを更新してフローがトリガーされるようにします。
先ほどコピーしておいた式を OnSelect プロパティに貼り付けます。
上部に追加された最初の If 条件で、「true」をフロー トリガーのトリガーに使用される実行関数で置き換えます。 以下の例をご覧ください。
If( locEditWorkItem, //adding code to call a flow when status changes If( locSelectedWorkItem.'Work Item Status'.'Project Work Item Status' \<\> cmbAddWorkItemStatus.Selected.'Project Work Item Status', SendAdaptivecardnotificationwhenthestatusoftheworkorderchanges.Run(locSelectedWorkItem.'Project Work item') //your flow call will come here ); //end code
読み込み画面を更新する
ツリー ビューで、読み込み画面 を選択します。
読み込み画面を展開し、その下にある conLoading_HiddenHelper を展開します。
タイマー tmrLoadingDelay を選択し、OnTimerEnd プロパティを選択します。
アダプティブ カードのリンクを介してアプリを開いたときに、更新された作業項目レコードが直接開くようにしたいので、作業項目 ID がアプリに渡されているかどうかを確認する方法が必要になります。
読み込みページの式を更新して作業項目番号を含める必要があるため、OnTimerEnd プロパティを次のように更新します。
If( gblAppLoaded,// && !IsBlankOrError(gblAppStyles), If( !IsBlank(Param("subEntityId")), //check if the parameter is blank or not If( //if the parameter is not blank, check if the user is on a mobile device or desktop/web and then populate the relevant variables and collections to make deep linking work (!IsBlank(Param("hostClientType")) && (Param("hostClientType") = "android" Or Param("hostClientType") = "ios")) || (IsBlank(Param("hostClientType")) && (Acceleration.X > 0 || Acceleration.Y > 0 || Acceleration.Z > 0)) Or tglAdmin_Mobile.Value, //project cover colors ClearCollect( colMobileProjectCoverColors, { Color: "#F4B9B9", Theme: "default", Base: "Color1" }, { Color: "#94BFFF", Theme: "default", Base: "Color2" }, { Color: "#E6F0FF", Theme: "default", Base: "Color3" }, { Color: "#5AC6CC", Theme: "default", Base: "Color4" }, { Color: "#C5E9EA", Theme: "default", Base: "Color5" }, { Color: "#F0F9FA", Theme: "default", Base: "Color6" }, { Color: "#EE6F99", Theme: "default", Base: "Color7" }, { Color: "#F495BF", Theme: "default", Base: "Color8" }, { Color: "#F4D2DC", Theme: "default", Base: "Color9" }, { Color: "#CEF0CD", Theme: "default", Base: "Color10" }, { Color: "#BDBDE6", Theme: "default", Base: "Color11" }, { Color: "#E2E2F6", Theme: "default", Base: "Color12" }, { Color: "#F4F4FC", Theme: "default", Base: "Color13" }, { Color: "#FBF6D9", Theme: "default", Base: "Color14" }, { Color: "#791818", Theme: "dark", Base: "Color1" }, { Color: "#053385", Theme: "dark", Base: "Color2" }, { Color: "#6264A7", Theme: "dark", Base: "Color3" }, { Color: "#002F31", Theme: "dark", Base: "Color4" }, { Color: "#025C5F", Theme: "dark", Base: "Color5" }, { Color: "#03787C", Theme: "dark", Base: "Color6" }, { Color: "#461525", Theme: "dark", Base: "Color7" }, { Color: "#CC3D6D", Theme: "dark", Base: "Color8" }, { Color: "#EA5788", Theme: "dark", Base: "Color9" }, { Color: "#043615", Theme: "dark", Base: "Color10" }, { Color: "#33344A", Theme: "dark", Base: "Color11" }, { Color: "#6264A7", Theme: "dark", Base: "Color12" }, { Color: "#464775", Theme: "dark", Base: "Color13" }, { Color: "#FFAA44", Theme: "dark", Base: "Color14" } ); //local table of character widths, used for auto width labels ClearCollect( colMobileCharsWidth, staticCharWidths ); //stock project cover images ClearCollect( colMobileStockImages, {appStockImage: Blank()}, {appStockImage: ProjectCover_Future}, {appStockImage: ProjectCover_Work}, {appStockImage: ProjectCover_Shapes}, {appStockImage: ProjectCover_Design}, {appStockImage: ProjectCover_Flow}, {appStockImage: ProjectCover_Abstract}, {appStockImage: ProjectCover_Mountain}, {appStockImage: ProjectCover_Vision}, {appStockImage: ProjectCover_DarkShapes}, {appStockImage: ProjectCover_Morning}, {appStockImage: ProjectCover_Sublime}, {appStockImage: ProjectCover_Tech}, {appStockImage: ProjectCover_Neon}, {appStockImage: ProjectCover_City} ); Set( gblMobileProject, LookUp( 'Project Work Items', 'Project Work item' = GUID(Param("subEntityId")) ).Project ); ClearCollect( colMobileWorkItems, Filter( 'Project Work Items', Project.Project = gblMobileProject.Project ) ); UpdateContext( { locMobileCompletionStatus: First( Sort( 'Project Work Item Statuses', Sequence, Ascending ) ) } ); Clear(colMobileWorkItemStatuses); ForAll( Sort( Filter( 'Project Work Item Statuses', 'Project Work Item Status' <> locMobileCompletionStatus.'Project Work Item Status' ), Sequence, Ascending ), Collect( colMobileWorkItemStatuses, { Name: ThisRecord.Name, Color: ThisRecord.Color, 'Color Dark': ThisRecord.'Color Dark', 'Project Work Item Status': ThisRecord.'Project Work Item Status', Sequence: ThisRecord.Sequence } ) ); Collect( colMobileWorkItemStatuses, { Name: locMobileCompletionStatus.Name, Color: locMobileCompletionStatus.Color, 'Color Dark': locMobileCompletionStatus.'Color Dark', 'Project Work Item Status': locMobileCompletionStatus.'Project Work Item Status', Sequence: locMobileCompletionStatus.Sequence } ); Navigate( 'Mobile Work Item Details Screen', ScreenTransition.None, { locMobileSelectedWorkItem: LookUp( 'Project Work Items', 'Project Work item' = GUID(Param("subEntityId")) ), locMobileShowWorkItemDetail: true, locMobileShowSearchWorkItem: false, locMobileNavToDetailFromAbout: true } ), Set( gblProject, LookUp( 'Project Work Items', 'Project Work item' = GUID(Param("subEntityId")) ).Project ); UpdateContext( { locCompletionStatus: First( Sort( 'Project Work Item Statuses', Sequence, Ascending ) ) } ); Clear(colWorkItemStatuses); ForAll( Sort( Filter( 'Project Work Item Statuses', 'Project Work Item Status' <> locCompletionStatus.'Project Work Item Status' ), Sequence, Ascending ), Collect( colWorkItemStatuses, { Name: ThisRecord.Name, Color: ThisRecord.Color, 'Color Dark': ThisRecord.'Color Dark', 'Project Work Item Status': ThisRecord.'Project Work Item Status', Sequence: ThisRecord.Sequence } ) ); Collect( colWorkItemStatuses, { Name: locCompletionStatus.Name, Color: locCompletionStatus.Color, 'Color Dark': locCompletionStatus.'Color Dark', 'Project Work Item Status': locCompletionStatus.'Project Work Item Status', Sequence: locCompletionStatus.Sequence } ); Navigate( 'Add/Edit Work Item', ScreenTransition.None, { locEditWorkItem: true, locSelectedWorkItem: LookUp( 'Project Work Items', 'Project Work item' = GUID(Param("subEntityId")) ), locAddProject: false, locExpandProjectList: true, locProjectSortOrder: true, locSortWorkItemBy: "eta", locShowSearchWorkItem: false, locAddWorkItem: false, locProjectStatusSelection: "Milestone status", locWorkItemSortOrder: true } ) ), If( //if the parameter is blank, check if the user is on a mobile device or desktop/web and redirect the user accordingly (!IsBlank(Param("hostClientType")) && (Param("hostClientType") = "android" Or Param("hostClientType") = "ios")) || (IsBlank(Param("hostClientType")) && Acceleration.X > 0) Or tglAdmin_Mobile.Value, Navigate( 'Mobile Projects Screen', ScreenTransition.None ), Navigate( 'Projects Screen', ScreenTransition.None, { locShowFirstRun: gblFirstRun, locShowPowerAppsPrompt: gblRecordUserSettings.'Display Splash (Power Apps)' = 'Display Splash (Power Apps) (Project User Settings)'.Yes } ) ) ) )
マイルストーン アプリを公開する
マイルストーン アプリの変更がすべて完了しました。 これで、右上の [チームに公開] ボタンを選択してアプリを公開できます。
Power Automate フローのテスト
Teams に移動し、マイルストーン アプリを開きます。
既存の作業項目を開き、状態を別の値に更新します。
アプリがインストールされているTeamsチャネルで通知のアダプティブ カードが受信されます。
関連項目
- マイルストーン サンプル アプリの広範な配布アプリをデプロイする
- マイルストーン サンプル アプリをカスタマイズする
- マイルストーン サンプル アプリのアーキテクチャを理解する
- サンプル アプリをカスタマイズする
- サンプル アプリ FAQ
- Microsoft Teams ストアからのサンプル アプリを使用する
注意
ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)
この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。
フィードバック
フィードバックの送信と表示