ささみ学習帳 - sasami's study book

ささみ学習帳

Microsoft365 や Power Platform について学んだこと・アイデアのメモ

Microsoft365 管理センターのサービス正常性のメール通知を翻訳してTeamsチャネルに投稿する Power Automate クラウドフロー (1/3) を作り直した

(2023/10/24) Defender for Office365 無環境でエラーとなった為、フロー解説→6-2.[データ操作]アレイのフィルター処理-MessageUrlを微修正しました。

 

以前作ったフローの問題点

Microsoft365 管理センターのサービス正常性のメール通知を翻訳してTeamsチャネルに投稿する Power Automate クラウドフロー (1/3)」として投稿したフローをその後運用していたのですが問題点がわかってきました。

  • サービス正常性通知メールのメール本文の変動が想定以上に大きくそれなりの頻度でエラーが発生する
  • メッセージが省略表示されないようにアダプティブカードで投稿していたが、新しいTeams(および新しいチャネルエクスペリエンス)ではアダプティブカードも省略表示されてしまう為、わざわざメール本文から項目を抽出しアダプティブカードにマッピングする意義が薄れてしまった(項目を抽出することがエラーの要因でもある)

ということで

  • サービス正常性通知メールの本文の変動でエラーが起きづらい構成にする
  • Microsoft365ライセンスのPower Automateで使える
  • 極力シンプルなフローにする
  • 2023年10月頃に通知メールに新たに追加された「Issue type」に対応する

の4点をテーマに全面的に作り直しました。

 

 

はじめに(流用です)

Microsoft365管理センターのサービス正常性には、標準機能として新しい問題が発生するとメール通知する機能があります。

私はこの通知メールの送信先に、チャネルのメールアドレスを設定しているのですが2つの問題点がありました。

  • 通知メールは翻訳されていない
  • チャネルにはメール全文が表示されない

翻訳はともかく、メール本文がほぼ表示されないのが致命的です。「元のメールをダウンロード」のリンクからemlファイルとしてメールをダウンロードすることはできますが、emlファイルを毎回開いていては使い勝手がいまいちです。

この辺りの問題をPower Automate クラウドフローを使って解消しました。

 

実行結果イメージ

こんな形でチャネルに投稿されます。

こんな感じのフィード通知も送ります。

 

フロー全体

 

フロー解説

1.[Office 365 Outlook] 新しいメールが届いたとき (V3) トリガー

サービス正常性のメール通知の fromアドレス "0365mc@microsoft.com" を指定しています。

ユーザーメールボックスで受信する場合は、こちらのアクションですが、共有メールボックスの場合は未確認ですが「新しいメールが共有メールボックスに届いたとき (V2)」トリガーで同様の動作が実現できるかと思います。

 

2.[変数]変数を初期化する-改行

改行文字の置換処理用に変数に定義しておきます。


3.[Content Conversion] Htmlからテキスト-Body

メール本文はHTMLで構成されているのでHtmlからテキストアクションでテキストに変換します。

  • コンテンツ
    • @{triggerOutputs()?['body/body']}

変換したメール本文テキストはこのようになります。

 

4.[コントロール]スコープ-Title抽出

4-1.[文字列操作] 部分文字列-Title

メール本文からメッセージのタイトル部分を取得します。

  • テキスト
    • @{body('Html_からテキスト-Body')}
  • 開始位置
    • 下の式A
  • 長さ
    • 下の式B

[式A]

add(indexof(body('Html_からテキスト-Body'), ']'), 1)

[式B]

add(
    indexof(body('Html_からテキスト-Body'), 'ID: '), 
    mul(
        add(
            indexof(body('Html_からテキスト-Body'), ']'), 1
        ), 
        -1
    )
)

この辺りのテキストを取得します。

 

4-2.[Translator V2] テキストの翻訳-Title

4-1.で取得した文字列を日本語に翻訳します。

  • ターゲット言語
    • 日本語
  • テキスト
    • @{body('部分文字列-Title')}

 

4-3.[データ操作] 作成-Title-Ja

タイトル文字列中に含まれる下記の文字を置換し、前後の空白を除去します。

  • 改行 →  ' '

trim(
    replace(body('テキストの翻訳-Title'), variables('改行'), ' ')
)

 

5.[コントロール]スコープ-ID抽出

5-1.[文字列操作]部分文字列-ID

メール本文からメッセージのID部分を取得します。

  • テキスト
    • @{body('Html_からテキスト-Body')}
  • 開始文字列
    • 下の式
  • 長さ
    • 8
add(
    indexof(body('Html_からテキスト-Body'), 'ID: '), 
    4
)

この辺りのテキストを取得します。

 

5-2.[データ操作]作成-ID

前後の空白と改行を除去します。IDに関しては発生しないはずですが念の為。

trim(replace(body('部分文字列-ID'), variables('改行'), ' '))

 

6.[コントロール]スコープ-URL抽出

6-1.[データ操作]作成-BodyArray0

split関数でメール本文のテキストをアレイに変換します。

split(
    body('Html_からテキスト-Body'), 
    variables('改行')
)

メール本文が1行ごとにアレイに変換されます。

 

6-2.[データ操作]アレイのフィルター処理-MessageUrl

6-1.で作成したアレイからサービス正常性のページへのリンクを抽出します。

  • 差出人
    • @outputs('作成-BodyArray0')
  • 条件
    • @{item()}
    • 次の値を含む
    • IncidentMail

サービス正常性のページへのリンクには必ず"IncidentMail"の文字が含まれるようですので、これを条件にURLを抽出しています。

6-3.[データ操作]作成-URL

6-2.で抽出したURLには前後に[]がありますのでこれを除去します。

replace(
    replace(
        first(body('アレイのフィルター処理-MessageUrl')),
        '[',
        ''
    ),
    ']',
    ''
)

 

7.[コントロール]スコープ-本文を整える

7-1.[文字列操作]部分文字列-ID以降

メール本文のIDとインシデントタイトルは件名に表示するので、IDより後ろのテキストを抽出します。

  • テキスト
    • @{body('Html_からテキスト-Body')}
  • 開始位置
    • 下の式
  • 長さ
    • 未指定
add(indexof(body('Html_からテキスト-Body'), 'ID:'), 12)

ここから後ろのテキストを取得しています。

メッセージに末尾にも不要なテキストはありますが、区切り位置を特定する文字列が変動する可能性があるのでそのままにしています。

 

7-2.[データ操作]作成-BodyArray

7-1.で抽出したテキストをsplit関数でメール本文のテキストをアレイに変換します。

split(
    body('部分文字列-ID以降'),
    variables('改行')
)

7-1.で抽出したテキストが1行ごとにアレイに変換されます。

 

7-2.[データ操作]アレイのフィルター処理-Body without URL

アレイからURLの要素を除去します。

  • 差出人
    • @outputs('作成-BodyArray')
  • 条件
    • @{item()}
    • 次のもので始まらない
    • [https://

 

7-3.[Translator V2]テキストの翻訳-Body

メッセージ本文を日本語に翻訳します。

  • ターゲット言語
    • 日本語
  • テキスト
    • 次の式
join(
    body('アレイのフィルター処理-Body_without_URL'),
    variables('改行')
)

この式で7-2.のアレイをテキストに戻し、そのテキストを日本語に翻訳します。

 

8.[Microsoft Teams]チャットまたはチャネルでメッセージを投稿する

チャネルにメッセージを投稿します。

  • 投稿者
    • ユーザー
  • 投稿先
    • チャネル
  • Team
    • 投稿するチーム
  • Channel
    • 投稿するチャネル
  • Message
    • <p><a href="@{outputs('作成-URL')}">【詳細】</a></p>
      <p>@{replace(
          body('テキストの翻訳-Body'),
          variables('改行'),
          '<BR>'
      )}</p>
  • Subject
    • @{outputs('作成-ID')}:@{outputs('作成-Title-Ja')}

 

9.[コントロール]スコープ-フロー実行者にフィード通知を投稿

9-1.[Office 365 Users]マイプロフィールの取得(V2)

 

9-2.[Microsoft Teams]フィード通知を投稿する

フロー実行者にフィード通知を送ります。

  • 投稿者
    • フローボット
  • 通知の種類
    • チーム
  • 受信者
    • @{outputs('マイ_プロフィールの取得_(V2)')?['body/mail']}
  • 通知テキスト
    • @{outputs('作成-ID')}:@{outputs('作成-Title-Ja')}
  • Team
    • 8で指定したチーム
  • Channel
    • 8で指定したチャネル
  • メッセージID
    • @{outputs('チャットまたはチャネルでメッセージを投稿する')?['body/id']}

 

このフローの残念ポイント - 日本語訳がやや過剰

本文を一度に日本語訳しているので日本語訳がやや過剰です。"Exchange Online" は"オンライン交換"と翻訳されてしまいます。Translatorコネクタの翻訳精度によるものですが、"Exchange Online"はBing翻訳でもGoogle翻訳でも同様の翻訳をしてしまうので妥協しているポイントです。

 

さいごに

ID,タイトル,URLの切り出しをやめて、翻訳もやめれば(通常メッセージなのでTeamsで翻訳できる)もっとシンプルにする事はできるのですが、自分の用途にはこれらがマストだったのでこの形に落ち着きました。

  • 件名にIDとタイトル入れたい
  • URLはリンクにしたい
  • 通知は日本語訳して目に止まるようにしたい

 

 

関連ページ

同じネタで何個もフローを作ってます。

 

⚫︎ Power Automate for Office365 ライセンスで使えるフロー

こちらが問題があり今回作り直しました。

sasami-axis.hatenablog.com

 

⚫︎OpenAI API を利用したフロー (要Power Automate Premium ライセンス)

sasami-axis.hatenablog.com

 

⚫︎Azure OpenAI Service を利用したフロー (要Power Automate Premium ライセンス)

sasami-axis.hatenablog.com