Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Google's Batch Mode #118

Open
astorm opened this issue Sep 13, 2024 · 1 comment
Open

Support for Google's Batch Mode #118

astorm opened this issue Sep 13, 2024 · 1 comment

Comments

@astorm
Copy link

astorm commented Sep 13, 2024

I ran into something that's either a bug or a missing feature (depending on your point of view). Would it be possible to add support for Google's batch requests (https://developers.google.com/gmail/api/guides/batch) to the built-in google classes (Keyring_Service_GoogleMail, etc.)

The problem I ran into was, I was trying to use Google's batch mode with code that looked something like this (pseudo code)

$body = '--batch_science
Content-Type: application/http
Content-ID: <item1>

GET /gmail/v1/users/me/messages/191e7beb2878c863

--batch_science
Content-Type: application/http
Content-ID: <item2>

GET /gmail/v1/users/me/messages/191e7beb2878c863

--batch_science--';
$args = [
    'method'=>'POST',
    'headers'=>[
        'Content-Type'=>'multipart/mixed; boundary=batch_science',
    ],
    'body'=>$body,
];

// $token is a the token object return by 
// Keyring::get_token_store()->get_tokens( array( 'service' => 'google-mail' ) )
$data = $token->service->request(
    'https://www.googleapis.com/batch/gmail/v1',
    $args
);	

The issue I ran into is the request method would return a null value, but there wouldn't be an error otherwise. It seemed as though the HTTP request was succeeding. After digging into the issue a bit, I believe the culprit is this bit of code in the base OAuth class.

#File: wp-content/plugins/keyring/includes/services/core/oauth2.php
/**
 * OAuth2 implementations generally use JSON. You can still override this
 * per service if you like, but by default we'll assume JSON.
 */
function parse_response( $response ) {
    return json_decode( $response );
}

The base OAuth2 class appears to assume the response will be a JSON formatted string. However, in the base of Google's batch API, the response is a multipart message. The json_decode function fails to parse this, returning NULL.

I realize there's workarounds -- implement my own service class that extends Keyring_Service_GoogleMail and include a multipart aware parse_response method, or add a filter/listener for the http_response filter and parse the response myself -- however it feels like this is something these classes should be able to handle themselves, or at minimum come back with an error that indicated the response could not be parsed.

@astorm
Copy link
Author

astorm commented Sep 17, 2024

Just some additional datapoint -- as much for the Google searches as anything.

A colleague (hat tip @rowasc) pointed out that the oAuth2 request method has two undocumented params -- full_response and raw_response that allow us to make requests without the automatic attempt as a json_decode, and are suitable workarounds.

https://github.com/beaulebens/keyring/blob/trunk/includes/services/core/oauth2.php#L208

That said -- it still seems like the Google service classes could/should be aware of the multipart Content-Type and do something smarter than return an empty error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant