phpazuremicrosoft-graph-apimicrosoft-graph-sdks

Microsoft Graph API PHP ODataError line 36 with no exception message when trying to use filter


I have installed and executed the basic example for MS Graph API through the PHP SDK. The examples contain a class named GraphHelper, which has a method getInbox:

public static function getInbox(): Models\MessageCollectionResponse {
        $configuration = new MessagesRequestBuilderGetRequestConfiguration();
        $configuration->queryParameters = new MessagesRequestBuilderGetQueryParameters();
        // Only request specific properties
        $configuration->queryParameters->select = ['from','isRead','receivedDateTime','subject'];

        $configuration->queryParameters->filter = "(from/emailAddress/address) eq 'MiriamG@M365x214355.onmicrosoft.com'";

        // Sort by received time, newest first
        $configuration->queryParameters->orderby = ['receivedDateTime DESC'];
        // Get at most 25 results
        $configuration->queryParameters->top = 25;
        return GraphHelper::$userClient->me()
            ->mailFolders()
            ->byMailFolderId('inbox')
            ->messages()
            ->get($configuration)->wait();
    }

If I omit the line $configuration->queryParameters->filter = "(from/emailAddress/address) eq 'MiriamG@M365x214355.onmicrosoft.com'";, I get the 25 latest messages from my inbox. When I apply filter, no matter what filter I put, I get the following:

Error getting user's inbox: 

Microsoft\Graph\Generated\Models\ODataErrors\ODataError in /home/alexios/research/automation/finances/automation-finances-import/vendor/microsoft/microsoft-graph/src/Generated/Models/ODataErrors/ODataError.php:36
Stack trace:
#0 /home/alexios/research/automation/finances/automation-finances-import/vendor/microsoft/kiota-serialization-json/src/JsonParseNode.php(117): Microsoft\Graph\Generated\Models\ODataErrors\ODataError::createFromDiscriminatorValue()
#1 /home/alexios/research/automation/finances/automation-finances-import/vendor/microsoft/kiota-http-guzzle/src/GuzzleRequestAdapter.php(678): Microsoft\Kiota\Serialization\Json\JsonParseNode->getObjectValue()
#2 /home/alexios/research/automation/finances/automation-finances-import/vendor/microsoft/kiota-http-guzzle/src/GuzzleRequestAdapter.php(160): Microsoft\Kiota\Http\GuzzleRequestAdapter->throwFailedResponse()
#3 /home/alexios/research/automation/finances/automation-finances-import/vendor/php-http/promise/src/FulfilledPromise.php(39): Microsoft\Kiota\Http\GuzzleRequestAdapter->Microsoft\Kiota\Http\{closure}()
#4 /home/alexios/research/automation/finances/automation-finances-import/vendor/microsoft/kiota-http-guzzle/src/GuzzleRequestAdapter.php(145): Http\Promise\FulfilledPromise->then()
#5 /home/alexios/research/automation/finances/automation-finances-import/vendor/microsoft/microsoft-graph/src/Generated/Users/Item/MailFolders/Item/Messages/MessagesRequestBuilder.php(73): Microsoft\Kiota\Http\GuzzleRequestAdapter->sendAsync()
#6 /home/alexios/research/automation/finances/automation-finances-import/src/Microsoft/GraphHelper.php(80): Microsoft\Graph\Generated\Users\Item\MailFolders\Item\Messages\MessagesRequestBuilder->get()
#7 /home/alexios/research/automation/finances/automation-finances-import/bin/import.php(25): AlexiosTsiaparas\AutomationFinancesImport\Microsoft\GraphHelper::getInbox()
#8 /home/alexios/research/automation/finances/automation-finances-import/bin/import.php(85): listInbox()
#9 {main}

So, no error description whatsoever.

I got the filtering from https://learn.microsoft.com/en-us/graph/use-the-api#query-parameters, and checked out the Graph Explorer https://developer.microsoft.com/en-us/graph/graph-explorer.

The get my mails from an address example has the filter I am interested in:

https://graph.microsoft.com/v1.0/me/messages?$filter=%28from%2FemailAddress%2Faddress%29+eq+%27MiriamG%40M365x214355.onmicrosoft.com%27

I tried url encoding the filter, and not, the error remains the same.

Update

I tried to bypass the SDK, except for the access token, so I did the following:

$accessToken = GraphHelper::getUserToken();
// echo "Token: $token\n";

$params = [
    'select' => ['from','isRead','receivedDateTime','subject'],
    'orderby' => ['receivedDateTime DESC'],
    'top' => 3,
    'filter' => "(from/emailAddress/address) eq 'test@test.com'"
];

$ch = curl_init();
$url = 'https://graph.microsoft.com/v1.0/me/messages?'.http_build_query($params);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer " . $accessToken));
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);

echo "HTTP status: $httpcode\nError:\n";
print_r($err);
echo "\nOutput\n------\n";
echo $output;

Everything works and I manage to get a response back with expected results!


Solution

  • I believe you are facing the issue described in the doc when using $filter and $orderby in the same query

    • Properties that appear in $orderby must also appear in $filter.
    • Properties that appear in $orderby are in the same order as in $filter.
    • Properties that are present in $orderby appear in $filter before any properties that aren't.

    Because you are ordering messages by receivedDateTime, you need to specify the property also in $filter query before any other properties

    $configuration->queryParameters->filter = "receivedDateTime ge 2000-01-01T00:00:00Z AND (from/emailAddress/address) eq 'MiriamG@M365x214355.onmicrosoft.com'";
    

    Code

    public static function getInbox(): Models\MessageCollectionResponse {
        $configuration = new MessagesRequestBuilderGetRequestConfiguration();
        $configuration->queryParameters = new MessagesRequestBuilderGetQueryParameters();
        // Only request specific properties
        $configuration->queryParameters->select = ['from','isRead','receivedDateTime','subject'];
    
        $configuration->queryParameters->filter = "receivedDateTime ge 2000-01-01T00:00:00Z AND (from/emailAddress/address) eq 'MiriamG@M365x214355.onmicrosoft.com'";
    
        // Sort by received time, newest first
        $configuration->queryParameters->orderby = ['receivedDateTime DESC'];
        // Get at most 25 results
        $configuration->queryParameters->top = 25;
        return GraphHelper::$userClient->me()
            ->mailFolders()
            ->byMailFolderId('inbox')
            ->messages()
            ->get($configuration)->wait();
    }