17

REST インターフェイス経由で GMAIL API を使用してメールを読むデスクトップ アプリケーションがあります。ドメイン設定を使用してメールをダウンロードできるようにサービス アカウントを使用したいのですが、ユーザーの操作は null です。Gmail サービス インスタンスを正常に作成できますが、メール リストの取得などの Gmail API メソッドにアクセスしようとすると、例外が発生します。

Google.Apis.Auth.OAuth2.Responses.TokenResponseException: エラー:"access_denied"、説明:"要求されたクライアントは承認されていません。"

開発者コンソールですべての設定を完了し、gapps ドメインにスコープを追加しました。

Gmail API はサービス アカウントをサポートしていますか? 同じ設定とサービス アカウントを使用して、ドライブ サービスと API を使用して Google ドライブ内のすべてのファイルのリストを取得できます。

4

6 に答える 6

16

サービス アカウントから Gmail にアクセスするには、次の C# コードを使用します

String serviceAccountEmail =
    "999999999-9nqenknknknpmdvif7onn2kvusnqct2c@developer.gserviceaccount.com";

var certificate = new X509Certificate2(
    AppDomain.CurrentDomain.BaseDirectory +
        "certs//fe433c710f4980a8cc3dda83e54cf7c3bb242a46-privatekey.p12",
    "notasecret",
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);

string userEmail = "user@domainhere.com.au";

ServiceAccountCredential credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer(serviceAccountEmail)
    {
        User = userEmail,
        Scopes = new[] { "https://mail.google.com/" }
    }.FromCertificate(certificate)
);

if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{   
    GmailService gs = new GmailService(
        new Google.Apis.Services.BaseClientService.Initializer()
        {
            ApplicationName = "iLink",
            HttpClientInitializer = credential
        }
    );

    UsersResource.MessagesResource.GetRequest gr =
        gs.Users.Messages.Get(userEmail, msgId);
    gr.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Raw;
    Message m = gr.Execute();

    if (gr.Format == UsersResource.MessagesResource.GetRequest.FormatEnum.Raw)
    {
        byte[] decodedByte = FromBase64ForUrlString(m.Raw);
        string base64Encoded = Convert.ToString(decodedByte);
        MailMessage msg = new MailMessage();
        msg.LoadMessage(decodedByte);
    }
}
于 2014-07-17T05:04:19.290 に答える
3

「メールを読みたい」場合は、新しい Gmail API が必要です (「バイナリで失われた」と指摘された古い管理者設定 API ではありません)。はい、oauth2 と新しい Gmail API を使用してこれを行うことができます。Cpanel で開発者をホワイトリストに登録し、リクエストに署名できるキーを作成する必要があります。セットアップには少し時間がかかります: https://developers.google.com /accounts/docs/OAuth2ServiceAccount#formingclaimset

于 2014-07-16T15:51:38.100 に答える
2

はい、できます...委任設定を確認してください...

https://developers.google.com/admin-sdk/directory/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account

編集: Eric DeFriez が共有したリンクを使用します。

于 2014-07-16T13:05:12.207 に答える
1

新しい Gmail API を使用して、user@YOUR_DOMAIN.COM のメール/ラベル/スレッドなどにアクセスできます。

https://developers.google.com/gmail/api/

なりすましを使用したサービス アカウント経由(サービス アカウントは、ドメインの特定のユーザーであるかのように API にアクセスしています)。

詳細はこちら: https://developers.google.com/identity/protocols/OAuth2ServiceAccount

Dartlang の関連コードは次のとおりです。

import 'package:googleapis_auth/auth_io.dart' as auth;
import 'package:googleapis/gmail/v1.dart' as gmail;
import 'package:http/http.dart' as http;

 ///credentials created with service_account here  https://console.developers.google.com/apis/credentials/?project=YOUR_PROJECT_ID 
final String creds = r'''
{
  "private_key_id": "FILL_private_key_id",
  "private_key": "FILL_private_key",
  "client_email": "FILL_service_account_email",
  "client_id": "FILL_client_id",
  "type": "service_account"
}''';


Future<http.Client> createImpersonatedClient(String impersonatedUserEmail, List scopes) async {
  var impersonatedCredentials = new auth.ServiceAccountCredentials.fromJson(creds,impersonatedUser: impersonatedUserEmail);
  return auth.clientViaServiceAccount(impersonatedCredentials  , scopes);
}



getUserEmails(String userEmail) async { //userEmail from YOUR_DOMAIN.COM
  var client = await  createImpersonatedClient(userEmail, [gmail.GmailApi.MailGoogleComScope]);
  var gmailApi = new gmail.GmailApi(client);
  return gmailApi.users.messages.list(userEmail, maxResults: 5);
}
于 2015-10-28T15:31:37.057 に答える