1

I am trying to locate emails in mailboxes that contain certain email header information. Utilizing the Microsoft Graph Explorer I am able to extract all 'internetMessageHeaders' for emails: https://graph.microsoft.com/v1.0/me/mailfolders('Inbox')/messages?$select=internetMessageHeaders

Which results in:

{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('xxxxxxx-ef44-425b-b7a5-xxxxxxxxxx')/mailFolders('Inbox')/messages(internetMessageHeaders)",
    "value": [
        {
            "@odata.etag": "W/\"xxxxxxxxxxxZXLAAASEk7/\"",
            "id": "kSlaEZXLAAASFWUWAAA="
        },
        {
            "@odata.etag": "W/\"EZXLAAAKjXG0\"",
            "id": "AKj3OcAAA=",
            "internetMessageHeaders": [
                {
                    "name": "Received",
                    "value": "from x.x.prod.outlook.com (x:x:x:x::x) by x.x.prod.outlook.com with HTTPS; Tue, 23 Nov 2021 22:13:31 +0000"
                },
                {
                    "name": "Received",
                    "value": "from x.x.prod.outlook.com (x:x:x:x::x) by x.x.prod.outlook.com (x:x:x:x::x) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id x; Tue, 23 Nov 2021 22:13:28 +0000"
                },
                {
                    "name": "Received",
                    "value": "from x.x.prod.protection.outlook.com (x:x:x:x::x) by x.outlook.office365.com (x:x:x:x::x) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id x via Frontend Transport; Tue, 23 Nov 2021 22:13:27 +0000"
                },
                {
                    "name": "Received",
                    "value": "from x (x.x.x.x) by x.mail.protection.outlook.com (x.x.x.x) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id x via Frontend Transport; Tue, 23 Nov 2021 22:13:26 +0000"
                },
                {
                    "name": "Authentication-Results",
                    "value": "spf=pass (sender IP is x.x.x.x) smtp.mailfrom=senderdomain.com; dkim=pass (signature was verified) header.d=senderdomain.com;dmarc=pass action=none header.from=senderdomain.com;compauth=pass reason=100"
                },
                {
                    "name": "Received-SPF",
                    "value": "Pass (protection.outlook.com: domain of senderdomain.com designates x.x.x.x as permitted sender) receiver=protection.outlook.com; client-ip=x.x.x.x; helo=senderdomain.com;"
                },
                {
                    "name": "Date",
                    "value": "Tue, 23 Nov 2021 22:13:24 +0000"
                },
                {
                    "name": "DKIM-Signature",
                    "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=senderdomain.com;s=senderdomain; t=1637705605;bh=xxxxxxx;h=Date:To:From:Reply-To:Subject:From;b=[redacted]="
                },
                {
                    "name": "Subject",
                    "value": "Test #3"
                },....

With the JSON results available, is it possible to use the $filter operation to search any of the value fields for specific conditions?

For example:

  1. how would I search/filter the Received-SPF field for a Pass or Fail condition?
  2. how would I search/filter any of the Received fields for a specific string?
  3. how would I combine #1 and #2 with an AND logic in a single filter?

I have looked at the Advanced Query references, yet I am not able to find any reference on how to filter for values inside the internetMessageHeaders JSON structure.

Any thoughts or pointers on how to search the header information fields would be much appreciated.

The end-goal is to only return emails where the $filter criteria on the email header fields is met.

2 Answers2

2

You could filter on filter singleValueExtendedProperties of type 0x007D which returns all internetmessageheaders as one object:

"singleValueExtendedProperties": [
  {
    "id": "String 0x7d",
    "value": "{headerName}: {headerValue}; {headerName}: {headerValue}; ....."
  }
]

If you want to use this filter:

$filter=internetMessageHeaders/any(r:r/name eq 'Received-SPF')

use this instead

$filter=singleValueExtendedProperties/any(r:r/id eq 'String 0x007D' and contains(r/value,'Received-SPF'))

If you want to avoid parsing that one long string of headers, you can add

$select=internetMessageHeaders

and you get them as one long array of key/value objects

BoKDamgaard
  • 378
  • 1
  • 19
0

The property InternetMessageHeaders does not support filtering.

You can try this request

GET https://graph.microsoft.com/v1.0/me/mailfolders('Inbox')/messages?$select=internetMessageHeaders&$filter=internetMessageHeaders/any(r:r/name eq 'Received-SPF')

But it will return ErrorInvalidProperty

user2250152
  • 14,658
  • 4
  • 33
  • 57
  • 1
    Yes, the response will like `{ "error":{ "code": "ErrorInvalidProperty", "message": "The property 'internetMessageHeaders' does not support filtering." } }` – Tiny Wang Dec 01 '21 at 09:11
  • So there is no way to filter/search internetMessageHeaders during an API call? – cybercitizen443 Dec 02 '21 at 00:15
  • What about the $expand option? [Get singleValueLegacyExtendedProperty](https://learn.microsoft.com/en-us/graph/api/singlevaluelegacyextendedproperty-get?view=graph-rest-1.0&tabs=http) Is it possible to use that to search the JSON returned? I simply can't figure out how the $expand option is suppose to be applied. – cybercitizen443 Dec 02 '21 at 00:28