cybercitizen443
cybercitizen443

Reputation: 43

Filter email via headers information in M365 using Microsoft Graph API

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.

Upvotes: 2

Views: 1329

Answers (2)

BoKDamgaard
BoKDamgaard

Reputation: 398

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

Upvotes: 2

user2250152
user2250152

Reputation: 20635

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

Upvotes: 0

Related Questions