LoginSignup
3
1

OutlookのGraph APIを用いて、自分がメンションされたメールを一覧化する【Power Automate】

Last updated at Posted at 2024-05-28

OutlookTeams、その他でメンション、絶え間ない通知に、おぼれかけている毎日。
Power Automateでは

という便利なトリガーも存在するため、こちらでメンションをストックすることもできそうです。

しかしながら、メンションがつく度に、何かしらのツールにデータがストックされるのも少し邪魔・・・。
どちらかというと決まったタイミングで、自分が必要な分だけ集めたい・・・

ということから、Outlookのメールに焦点を宛て、自分がメンションされたメールを一覧化する方法を模索してみました。

メンションされた通知を一覧化する

前述した通り、Teams、Outlookそれぞれメンションされた投稿やメッセージを受信する都度、発火するトリガーは、前述のとおり、すでに存在します。

しかしそういったものも、習慣化しない限りは、everyday no look life のはじまりです。

理想は、リマインド。何か漏れているものがあれば、対応したい、それくらいの我儘があったりします。
Pushされるのではなく、Pull型で決まった条件付きの情報を収集したい、というやつです。

自分が調査したところ、メンションされた投稿やメッセージを一覧化するというアクションは見当たりません。

2024.05.28時点

そこで、Graph APIを使って、まずはOutlookのメールだけでもなんとかできないか、挑戦してみます。

Graph API mentionsPreview リソース

今回の課題は、mentionsPreviewを使って対処ができそうです。

またbetaバージョンのAPIとのこと。

/betaバージョンのAPIであり、変更される可能性があります。

第1セグメント: /me/users/<userId>、第2セグメント:messagesmailFolderseventscalendarcalendarsoutlookinferenceClassificationの範囲内であることから、Office 365 Outlookコネクタで対応できそうです。

Office 365 OutlookコネクタのHTTP 要求を送信するアクションで、Graph APIを使ってみましょう。

image.png

Method : Get

url
https://graph.microsoft.com/beta/me/messages?$filter=mentionsPreview/isMentioned+eq+true

これだけで、自分がメンションされたメールを一覧化することができます。

実際に使ってみると、Outlookの通知、下記の部分が取得できました。

image.png

Office 365 Outlookコネクタのアクションであるため、プレミアム コネクタなしで使えます。
個人情報も入っているので、戻り値は例で紹介します。

body
{
  "@odata.context": "https://graph.microsoft.com/beta/$metadata#users('XXXXXX')/messages",  // ODataコンテキストURL
  "value": [
    {
      "@odata.etag": "W/\"CQAAABYAAADkSCYyPiA9RbDtjRLFGs9eAAHXd8D+\"",  // エンティティタグ
      "id": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Yy05MzM5LTJmZGQ3OWViZDcxNQBGAAAAAADfGay5QuF-RaPDhnhQhBiwBwDkSCYyPiA9RbDtjRLFGs9eAAAAAAEMAADkSCYyPiA9RbDtjRLFGs9eAAHYoEnHAAA=",  // メッセージID
      "createdDateTime": "2024-05-26T13:48:43Z",  // メッセージの作成日時
      "lastModifiedDateTime": "2024-05-26T15:29:40Z",  // メッセージの最終変更日時
      "changeKey": "CQAAABYAAADkSCYyPiA9RbDtjRLFGs9eAAHXd8D+",  // 変更キー
      "categories": [],  // メッセージのカテゴリ
      "receivedDateTime": "2024-05-26T13:48:43Z",  // メッセージの受信日時
      "sentDateTime": "2024-05-26T13:48:40Z",  // メッセージの送信日時
      "hasAttachments": false,  // 添付ファイルがあるかどうか
      "internetMessageId": "<OS3PR01MB9979FE7B27B56435AF10D47DA8F02@OS3PR01MB9979.jpnprd01.prod.outlook.com>",  // インターネットメッセージID
      "subject": "Re: 出戻り ガツオ さん",  // メールの件名
      "bodyPreview": "@出戻り ガツオ",  // メール本文のプレビュー
      "importance": "normal",  // メッセージの重要度
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Yy05MzM5LTJmZGQ3OWViZDcxNQAuAAAAAADfGay5QuF-RaPDhnhQhBiwAQDkSCYyPiA9RbDtjRLFGs9eAAAAAAEMAAA=",  // 親フォルダID
      "conversationId": "A------------------------------AAAA=",  // メールの会話ID
      "conversationIndex": "AQHaq3wohqJq/KBeUEupH6IVjmfdJLGrIiZr",  // メールの会話インデックス
      "isDeliveryReceiptRequested": false,  // 配信確認の要求
      "isReadReceiptRequested": false,  // 読了確認の要求
      "isRead": true,  // メッセージが既読かどうか
      "isDraft": false,  // メッセージがドラフトかどうか
      "webLink": "",  // メッセージをウェブで開くためのURL
      "inferenceClassification": "focused",  // メッセージの分類
      "unsubscribeData": [],  // 購読解除リンク
      "unsubscribeEnabled": false,  // 購読解除が有効かどうか
      "body": {
        "contentType": "html",  // メッセージ本文の形式
        "content": "htmlテキスト"  // メッセージ本文の内容
      },
      "sender": {
        "emailAddress": {
          "name": "大久保 絵梨",  // 送信者の名前
          "address": "okubo_eri@onmicrosoft.com"  // 送信者のメールアドレス
        }
      },
      "from": {
        "emailAddress": {
          "name": "大久保 絵梨",  // メッセージの送信元の名前
          "address": "okubo_eri@onmicrosoft.com"  // メッセージの送信元のメールアドレス
        }
      },
      "toRecipients": [
        {
          "emailAddress": {
            "name": "出戻り ガツオ",  // 宛先の名前
            "address": "hogehoge@onmicrosoft.com"  // 宛先のメールアドレス
          }
        }
      ],
      "ccRecipients": [],  // CCの受信者情報
      "bccRecipients": [],  // BCCの受信者情報
      "replyTo": [],  // 返信先アドレス情報
      "mentionsPreview": {
        "isMentioned": true  // メンションされているかどうか
      },
      "flag": {
        "flagStatus": "notFlagged"  // フラグの状態
      }
    }
  ]
}

メールのidhtmlを含めて、様々な値を取得することができます。
isReadCategoryを使うことによって、抽出も可能。

プロパティの詳細は下記を参考にしてください。

抽出例:アーカイブされたメッセージ以外を対象にする

私の場合、もう見ないメッセージは、Backspaceでアーカイブします。
しかし、アーカイブの場合、例文の中のプロパティでは判断できません。

parentFolderIdは、親フォルダIDであり、この手法で変更される値ではないためです。
発想を変えてみます。
メッセージを抽出する対象を受信トレイに絞り、メンションされたメッセージを取得します。

このためには、

  1. メールボックスのIDを取得
  2. メールボックスのIDを含めてGraph APIを実行

上記の二段構えで対処します。

1. メールフォルダー(mailFolders)のIDを取得

こちらもGraph APIを使い、メールフォルダー コレクションを取得します。

image.png

Method : Get

URI
https://graph.microsoft.com/v1.0/me/mailFolders

上記により、メールフォルダー コレクションを取得できます。

戻り値
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('hogehogehogehogehoge')/mailFolders",
  "value": [
    {
      "id": "AAMkADBiYTQzZ----------------DtjRLFGs9eAAABb7e4AAA=",
      "displayName": "アーカイブ",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Yy05MzM5LTJm----------------AEIAAA=",
      "childFolderCount": 2,
      "unreadItemCount": 0,
      "totalItemCount": 31,
      "sizeInBytes": 6978775,
      "isHidden": false
    },
    {
      "id": "AAMkADBiYTQz----------------bDtjRLFGs9eAAAAAAEPAAA=",
      "displayName": "下書き",
      "parentFolderId": "AAMk----------------DtjRLFGs9eAAAAAAEIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 13432,
      "isHidden": false
    },
    {
      "id": "AAMkADBiYTQzZDYzLW----------------",
      "displayName": "会話の履歴",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtND----------------tjRLFGs9eAAAAAAEIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 0,
      "isHidden": false
    },
    {
      "id": "AAMkADBiY----------------=",
      "displayName": "削除済みアイテム",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI----------------jRLFGs9eAAAAAAEIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 1583000204,
      "isHidden": false
    },
    {
      "id": "----------------=",
      "displayName": "受信トレイ",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNvDtjRLFGs9eAAAAAAEIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 62280,
      "isHidden": false
    },
    {
      "id": "AAMkADBiYTQzZDYzLW----------------FGs9eAAAAAAELAAA=",
      "displayName": "送信トレイ",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Yy05MzM5----------------EIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 0,
      "isHidden": false
    },
    {
      "id": "AAMkADBiYTQzZ----------------bDtjRLFGs9eAAAAAAEJAAA=",
      "displayName": "送信済みアイテム",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Y----------------LFGs9eAAAAAAEIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 741258,
      "isHidden": false
    },
    {
      "id": "A----------------uF-RaPDhnhQhBiwAQDkSCYyPiA9RbDtjRLFGs9eAAFqodNcAAA=",
      "displayName": "同期の失敗",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Yy05MzM5LTJmZGQ3OWV----------------F-RaPDhnhQhBiwAQDkSCYyPiA9RbDtjRLFGs9eAAAAAAEIAAA=",
      "childFolderCount": 3,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 0,
      "isHidden": false
    },
    {
      "id": "AAMkADBiYTQzZDYzLWQ----------------fGay5QuF-RaPDhnhQhBiwAQDkSCYyPiA9RbDtjRLFGs9eAAAAAAEUAAA=",
      "displayName": "迷惑メール",
      "parentFolderId": "AAMkADBiYTQzZDYzLWQ4NzMtNDI4Yy05MzM5LTJmZGQ3OWViZDc-----------------RaPDhnhQhBiwAQDkSCYyPiA9RbDtjRLFGs9eAAAAAAEIAAA=",
      "childFolderCount": 0,
      "unreadItemCount": 0,
      "totalItemCount": 0,
      "sizeInBytes": 0,
      "isHidden": false
    }
  ]
}

単純なJSON 配列入力ですね。
JSON の解析アクションで、Schemaを定義しましょう。

image.png

Content
@{body('HTTP_要求を送信します_mailFolders')}
Schema mailFolders
{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "value": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "displayName": {
                        "type": "string"
                    },
                    "parentFolderId": {
                        "type": "string"
                    },
                    "childFolderCount": {
                        "type": "integer"
                    },
                    "unreadItemCount": {
                        "type": "integer"
                    },
                    "totalItemCount": {
                        "type": "integer"
                    },
                    "sizeInBytes": {
                        "type": "integer"
                    },
                    "isHidden": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "id",
                    "displayName",
                    "parentFolderId",
                    "childFolderCount",
                    "unreadItemCount",
                    "totalItemCount",
                    "sizeInBytes",
                    "isHidden"
                ]
            }
        }
    }
}

アレイのフィルター処理を使って、メンションされたメールを判別するフォルダーの設定、
つまり受信トレイIDを取得します。

image.png

displayName受信トレイのものがそのままマッチしますね。

2. 改めてメンションされたメールを一覧化

image.png

Method : Get

URI
https://graph.microsoft.com/beta/me/mailFolders/@{body('アレイのフィルター処理')[0]?['id']}/messages?$filter=mentionsPreview/isMentioned+eq+true

アレイのフィルター処理の戻り値は配列であるため、[0]で抽出した値を特定します。
mailFoldersの後にIDを追加することで、受信トレイのメールのみ取得できました。

さらにアレイのフィルター処理で、receivedDateTimegetPastTime関数で比較することで、直近1日以内のメッセージに絞ることができます。

getPastTime(1, 'Day')

あとは選択で必要項目のみ抽出して、HTMLテーブルに変えて、Teamsリマインドなど追加すれば、リマインダーが出来上がりますね。

※イメージ

image.png

通知まみれ

それにしても通知まみれの環境になりました。
Always ピコピコブーブーです。

そんな状況にならないよう、環境整理からスタートすべきですかね。
お互い明日も頑張りましょう!

3
1
3

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
3
1