Marketplace アプリの機能の 1 つは、IMAP 経由でユーザーの Gmail アカウントにアクセスすることを利用しています。次のように、google-api-java-client および google-oauth-java-client ライブラリと、java-gmail-imap プロジェクトのこの例に似たコードを使用しています。
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_ID)
.setServiceAccountScopes(Arrays.asList(GMAIL_SCOPE))
.setServiceAccountPrivateKey(PRIVATE_KEY)
.setServiceAccountUser(emailAddress)
.build();
credential.refreshToken();
次に、 https://code.google.com/p/google-mail-oauth2-toolsの例に基づいたコードを使用して、IMAP 接続を確立します。
IMAPStore imapStore = OAuth2Authenticator.connectToImap("imap.googlemail.com",
993, emailAddress, credential.getAccessToken(), false);
ほとんどの場合、これは正しく機能しているように見えますが、少数ではあるがかなりの数のリクエストで、Google への呼び出しがrefreshToken()
HTTP 500 エラーで失敗し、通常は JSON が返される HTML レスポンスが返されることが確認されています。
<p class="large"><b>500.</b> <ins>That's an error.</ins></p>
<p class="large">The server could not process your request.
<ins>That's all we know.</ins></p>
Google のデベロッパー アドボケイトから、更新トークンはサービス アカウントではサポートされていないため、この例のようなアプローチを使用する必要があるとのアドバイスを受けました。
ただし、thenへの呼び出しがないと、資格情報オブジェクトにデータが取り込まれず、呼び出し時にrefreshToken
accessToken
NullPointerException
OAuth2Authenticator.connectToImap
ソースからは、サービス アカウントを処理するためにオーバーライドされてGoogleCredential
いるように見えexecuteRefreshToken()
ました。つまり、更新を実行する代わりに、単に新しいトークンを要求し、次にこのコードのビットでCredential
アクセス トークンの入力を処理します。
TokenResponse tokenResponse = executeRefreshToken();
if (tokenResponse != null) {
setFromTokenResponse(tokenResponse); ....
refreshToken()
断続的な 500 エラーを回避するために呼び出しを再試行ループに入れる必要があるかどうか、またはこのシナリオで推奨されるアプローチに従うためにコードに他の変更を加える必要があるかどうかはわかりませんでした。
誰でもアドバイスできますか?