1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

どんなものも注意深く観察していると一定の規則性を感じることができます。先日Microsoft 365 メッセージ センターコネクタを試す - Part.1 設定のブログにて、「メモ欄」に情報が集約されてしまい、解析する必要があると記載しましたが、私なりの対処法を検討しましたので、書いていこうと思います。

見出し: 文章で一定の構造化がされている

観察していくと

  • Message ID
  • Published date
  • Last updated date
  • Category
  • Tags
  • Relevance

image.png

上記の例のように[見出し: 内容]と表現されます。
複数行テキストの情報は上記に該当しませんが少なくとも

  • Updated Month Day, Year
  • [When this will happen:]
  • [How this will affect your organization:]
  • [What you need to do to prepare:]

と情報が連なっています。

Microsoft 365 管理センターで見る

  • メッセージの件名
  • サービス
  • 最終更新
  • 対応期限
  • 関連性
  • 組織の状態
  • タグ

上記のような情報がパースして拾えそうな気配がします。

image.png

また複数例を見ていくと、「Last updated date」の見出しがある場合とない場合で分かれるなど、動的な項目の変動が見られます。

  • 一定の項目は固定的に抽出できる
  • 動的な項目の変動に対処

上記で情報をパースし、アダプティブカードで通知するシナリオを検討したいと思います。

文章の規則性

文章を観察すると、ほぼ「見出し: 内容」で構成されると同時に、今回抽出するテキストは、基本的に一行内に収まる情報です。

つまり改行するまでがパースの対象になります。
この点のものは「正規表現」を使いことが相場ですが、データ操作でトライしていきましょう。

フローの流れ

  1. 変数を初期化 - 配列(取得するキー項目の一覧)
  2. 変数を初期化 - オブジェクト(値を取得するための箱)
  3. 選択(Select) - キーバリューで値を抽出
  4. アレイのフィルター処理 - nullを除外して項目の増減に対処
  5. For each
    1. 作成 - オブジェクトを一時的に格納
    2. 変数を設定 - addProperty 関数でプロパティを追加

変数を初期化 - 配列(取得するキー項目の一覧)

呼び出したいキー項目を下記の通り列挙しておきましょう。
条件分岐で利用するためです。

[
  "Message ID",
  "Published date",
  "Last updated date",
  "Category",
  "Tags",
  "Relevance"
]

ハードコーディングがナンセンス、という意見は一旦その通りです、と言っておきます

やはり便利な選択

選択(Select)を用いて、改行コードごとに文章を分割split 関数、(1)で設定したキー項目を含むcontains 関数要素のみ、キーバリューを明示的に収集します。

  • From - split(outputs('タスクの詳細を取得する')?['body/description'], decodeUriComponent('%0D%0A'))
  • Map
{
  "key": @{if(contains(variables('Columns'),split(item(),': ')?[0]),split(item(),': ')?[0],null)},
  "value": @{if(contains(variables('Columns'),split(item(),': ')?[0]),split(item(),': ')?[1],null)}
}
  1. 改行コードで文字列を分割
    1. 改行コードはdecodeUriComponent('%0D%0A'))が該当
  2. オブジェクト型でkeyvalueを拾いたい配列に含まれる場合のみ追加する方法

image.png

やはり登場するのは選択です。
万能選手過ぎて驚きますね!

アレイのフィルター処理nullを除外

選択(Select)を用いた際に、(1)の配列に含まれないキーを全てnullと設定しています。こちらによって配列からnullを除外するフィルターを設定します。

image.png

  • From - body('選択')
  • Filter Query - @not(equals(item()?['value'],null))

あとは繰り返し処理

あとは繰り返しでaddProperty 関数による属性の追加です。

変数の設定の中で対象の変数を呼び出すことはできないため、一度作成で格納してからaddProperty 関数を適用しています。

Do until
addProperty(body('JSON_Array')?[variables('j')],'Index',iterationIndexes('Do_until'))

image.png

JSONになったらこっちのもの!

あとはお手の物です。
SharePoint Listsに格納するなり、Teamsでアダプティブカードに追加するなりできます。

文字列といえども目を凝らせば規則性があるもの。
観察👀大切ですね!

アダプティブカード編

最終系はコチラ!

image.png

{
    "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.4",
    "body": [
        {
            "type": "Container",
            "items": [
                {
                    "type": "FactSet",
                    "facts": @{body('FactSet')
                    }
                },
                {
                    "type": "TextBlock",
                    "text": "@{outputs('タスクの詳細を取得する')?['body/description']}",
                    "wrap": true
                }
            ]
        }
    ],
    "actions": @{body('actions')
    }
}

FactSetactionsは配列なので、アレイのフィルター処理から整形したほうが速いですね💦
並列分岐で追加しました。

FactSet

image.png

  • From - body('アレイのフィルター処理')
Map
{
 "title": @{item()?['key']},
 "value": @{item()?['value']}
}

actions
参照リソースのURLです

  • From - outputs('タスクの詳細を取得する')?['body/references']
Map
{
 "type": "Action.OpenUrl",
 "title": "Item", // title適当なので変えてください
 "url": @{item()?['resourceLink']}
}
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?