AzureFunctionsでGoogle Workspaceのレポートデータを取得する

こんにちは、ATL Systems 鍋島です。
今回は、Azure Functionsで Google Workspaceのレポートデータを取得する手順について説明していきます。

ちなみに、Consoleアプリで実行する場合は、こちらのドキュメントを公式参考にしてください。
OAuth 認証を使ったサンプルコードがあります。
[Google Workspace Admin SDK > .Net >.NET quickstart](https://developers.google.com/admin-sdk/reports/v1/quickstart/dotnet)


:::note warn
Reports APIをAzure Functionsなどサーバーで利用する場合、OAuthによる認証を利用できません。今回は検証のため、その代わりにサービスアカウントを使っています。
:::

:::note warn
サービス アカウント キーは、不正使用されるとセキュリティ上のリスクになる可能性があります。サービス アカウント キーをダウンロードするのではなく、代わりに Workload Identity 連携を使用することをおすすめします。 
:::

Workload Identityについては以下のドキュメントを参照してください。

* [Workload Identity 連携](https://cloud.google.com/iam/docs/workload-identity-federation?_ga=2.257603343.-541300376.1628569272)
* [Google Cloud でサービス アカウントを認証する最適な方法の詳細](https://cloud.google.com/blog/products/identity-security/how-to-authenticate-service-accounts-to-help-keep-applications-secure?_ga=2.95189528.-541300376.1628569272)



# Google Consoleでプロジェクトを追加
まずはサービスアカウントを作る前にプロジェクトを作成します。

Google Consoleにログインします。
[https://console.cloud.google.com/](https://console.cloud.google.com/)

次に、Google Cloud Platformで新しいプロジェクトを追加します。
ここではプロジェクト名を *AzureFunctionProject* とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/67325912-9bff-966c-595c-b38f15f2b022.png)

プロジェクトを作成したら、作成したプロジェクトに切り替えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/419f538d-5e38-d39e-9125-40841b40df90.png)

# Admin SDK APIの有効化
次に利用するAPIを有効化します。ここでは **Admin SDK API**を有効化していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/280c10b6-8be0-4c70-4e72-f7ec9c8b98cd.png)

Admin SDK API を検索して、**有効にする** ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/49c2d1b8-b084-1e70-857d-3b95c6505e59.png)

# Google Consoleでサービスアカウントの追加

次に、**認証情報を作成**ボタンをクリックして、認証情報追加していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/f95e0cb7-801d-b80a-89d9-a50d46e2d6d2.png)
使用するAPIは**Admin SDK API**を選択し、アクセスするデータの種類は **アプリケーションデータ**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/94aaac92-6077-818a-6a6b-e3d7cd278a84.png)
ロールは**オーナー**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/44db6529-664d-d5ec-e5c2-d45e9e045be4.png)
最後に**完了**をクリックして、認証情報の追加を完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/5cbf34ae-833c-4e07-bb54-c5e0732f31c5.png)

サービスアカウントが作成されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/6b4154a0-bbef-daec-6bc8-ba06aa72dbf9.png)

次にReports APIを利用するために、サービスアカウントの設定を変更て、
**Google Workspace ドメイン全体の委任を有効にする** にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/748ed41c-d924-247d-2903-8012449ac235.png)

チェックを入れると
**ドメイン全体の委任を変更するには、OAuth 同意画面でプロダクト名を構成する必要があります。** 
と表示されるので、プロダクト名を入力して、**保存** ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/8cee6ff9-b339-5d67-f7c2-a97b9281a6bd.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/0bd2c06f-2670-654a-3df3-4d2965d40f16.png)

# Google AdminでクライアントIDの追加

Google Admin で APIの制御 にアクセスします。

Google Admin > セキュリティ > APIの制御 にアクセスします。
 [https://admin.google.com/ac/owl/domainwidedelegation?hl=ja](https://admin.google.com/ac/owl/domainwidedelegation?hl=ja)

次に[新しく追加] ボタンをクリックして、新しいクライアントIDを追加します。ここで登録するクライアントIDは Google Cloud Consoleで追加したサービスアカウントのクライアントIDです。

以下のドキュメントを参考にOAUTHスコープも追加します。
[https://developers.google.com/admin-sdk/reports/v1/guides/authorizing](https://developers.google.com/admin-sdk/reports/v1/guides/authorizing)

| 範囲	     | 意味       |
|:-----------|:----------|
|https://www.googleapis.com/auth/admin.reports.audit.readonly|アクティビティレポートを取得するときの読み取り専用アクセス。|
|https://www.googleapis.com/auth/admin.reports.usage.readonly|使用状況レポートを取得するときの読み取り専用アクセス。|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/7e5b2321-dd53-5cc6-e4c9-e91030a9b675.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/53627e47-529a-fa7e-d506-fa723055ee9a.png)

# サービスアカウントで秘密鍵の作成

Google Cloud Platformに戻り、**サービスアカウント**メニューから作成したサービスアカウントを表示して、**キー**タブを表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/a6eedac9-9325-4d13-764b-836243e13057.png)

JSONを選択して、**作成**ボタンをクリックして、秘密鍵ファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/d2bb4d73-2021-17d1-cf08-fba7986d6b27.png)

秘密鍵入りのJSONファイルが端末へ保存されると、以下のメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/e47947af-29c9-5d75-f4f4-25c343bc9cc9.png)

# AzureFunctions のプロジェクトの作成

Visual Studio 2019を起動し、新しいプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/2bd3d50e-6b4d-81c4-2bd9-b5698eebf0bf.png)

スケジュールされた間隔で実行される、Time trigger を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/b5c91a93-d95f-b49b-9043-42dd4490c976.png)

ちなみに実行間隔を5分から1分に変更するには 5 を 1に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/e0c3bdef-a474-6d64-ea03-278839b74c66.png)

パッケージマネージャーコンソールで必要なパッケージ **Google.Apis.Admin.Reports.reports_v1**を追加します。

```PowerShell
PM> Install-Package Google.Apis.Admin.Reports.reports_v1
```

秘密鍵ファイルを追加します。

サービスアカウントで作成した秘密鍵ファイルをプロジェクトに追加します。
その際、ファイルのプロパティで**出力ディレクトリにコピー**を常にコピーするに変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/737b1f67-9dcf-249d-b7ad-a88cd8500f24.png)


最後に、Azure Functionsのコードを変更します。
Functions1.csを開いて、以下のコードを貼り付けます。
コード中の以下のワークスペース名や定数については各自の環境に合わせて変更してください。

|項目 | 値|
|:--------|:------|
|Google Workspaceの管理者ユーザ | foo@exmaple.com |
|秘密鍵のファイル名| azurefunctionproject-123456789.json|

```C#
using Google.Apis.Admin.Reports.reports_v1;
using Google.Apis.Admin.Reports.reports_v1.Data;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using static Google.Apis.Admin.Reports.reports_v1.ActivitiesResource.ListRequest;

namespace GoogleWorkspaceReportsFunctionApp
{
    public static class Function1
    {
        static string[] Scopes = { ReportsService.Scope.AdminReportsAuditReadonly, ReportsService.Scope.AdminReportsUsageReadonly };
        static string ApplicationName = "Reports API .NET Quickstart";
        static string User = "foo@example.com";
        static string JsonPath = "azurefunctionproject-123456789.json";
        [FunctionName("Function1")]
        public static void RunAsync([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
            

            //以下のドキュメントが参考になった。
            //CreateWithUserで特定のユーザとしてクレデンシャルを作成すると401にならない。
            //https://github.com/googleapis/google-api-dotnet-client/issues/1629
            var credential = GoogleCredential.FromFile(JsonPath).CreateScoped(Scopes).CreateWithUser(User);

            // Create Reports API service.
            var service = new ReportsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });

            // Define parameters of request.
            ActivitiesResource.ListRequest request = service.Activities.List("all", ApplicationNameEnum.Login);
            request.MaxResults = 10;
            // List activities.
            IList<Activity> activities = request.Execute().Items;
            Console.WriteLine("Logins:");
            if (activities != null && activities.Count > 0)
            {
                foreach (var activityItem in activities)
                {
                    Console.WriteLine("{0}: {1} {2}", activityItem.Id.Time,
                        activityItem.Actor.Email,
                        activityItem.Events.First<Activity.EventsData>().Name);
                }
            }
            else
            {
                Console.WriteLine("No logins found.");
            }
            Console.Read();
        }
    }
}

```
# エミュレーターの実行
最後にエミュレータを実行して試します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/5cf036dc-0ee8-d1eb-f010-0cceecf2d367.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760066/72302505-c56e-8279-db13-83cdc0f2a87e.png)

うまくいきましたね！

#まとめ
Azure Functionsのエミュレータで Google Workspaceのレポートデータを取得できました。