カスタム API の作成と使用

Dataverse で独自の API を作成するカスタム API を使用します。 1 つ以上の操作をカスタム API に統合して、自分や他の開発者がコード内で、または Power Automate から呼び出せるようにすることができます。 Microsoft Dataverse コネクタにより、Power Automate のアクションを呼び出すことができます。

カスタム API をビジネス イベントとして使用して、Microsoft Dataverse コネクタの新しい種類のトリガー イベントを公開するなどの新しい統合機能を作成できるようにすることができます。 詳細情報: Microsoft Dataverse ビジネス イベント

カスタム API は、カスタム プロセス アクションの代替手段です。 カスタム プロセス アクションは、カスタム メッセージを含めるためのコード不要の方法を提供しますが、開発者にはいくつかの制限があります。 カスタム API は、開発者がコードでその他のオプションを使用してロジックを定義するための機能を提供します。 カスタム プロセス アクションとカスタム API の完全な比較については、カスタム プロセス アクションとカスタム API の比較 を参照してください。

カスタム API の作成

カスタム API には、プラグインで実装されたロジックが含まれる場合があります。 Microsoft Dataverse ビジネス イベント を使用して、プラグインなしでカスタム API を作成して、他のサブスクライバーが応答するイベントに関するデータを渡すことができます。

ただし、その他の場合は、カスタム API とプラグインと組み合わせて、Dataverse に委任して計算し、結果を返す操作を定義します。

カスタム API の作成には、いくつかの方法があります。

メソッド リンク ベネフィット
プラグイン登録ツール プラグインの開発に使用されるツールと統合された使いやすい GUI ツール。
Power Apps フォームを使用してデータを入力します。 個別のツールをインストールする必要はありません。カスタム API の各部分に個別のレコードを作成する必要があります。
コードを使用 データ モデルを理解した後、Postman や Insomnia などの API クライアントを使用して、カスタム API をすばやく作成することができます。 または、独自のエクスペリエンスを構築して、カスタム API を作成することもできます。
ソリューション ファイルを使用 アプリケーション ライフサイクル管理 (ALM) ツールを使用すると、ソース コード リポジトリに含まれているソリューションで XML ファイルを使用してカスタム API 定義を作成または変更できます。 カスタム API は、ソース コードから生成されたソリューションをインポートするときに作成されます。

注意

カスタム API のデータはテーブルに格納されていますが、これらのテーブルに対するモデル駆動型アプリの作成はサポートしていません。

これらは、カスタム API を操作するために、コミュニティが作成とサポートを行うツールの一部です。

コミュニティによって作成されたツールは、Microsoft によってサポートされていません。 コミュニティ ツールに関する質問や問題は、ツールの公開元にお問い合わせください。

カスタム API のカスタマイズ

カスタム API および関連するリクエスト パラメーターやレスポンス プロパティを作成する際には、これらの API 定義が既定でカスタマイズ可能であることを理解することが重要です。 カスタマイズ可能なため、アンマネージド ソリューションでこれらの項目を反復して変更することができます。

重要

ソリューションを出荷またはデプロイする際には、マネージドソリューションを使用し、これらのコンポーネントの Is Customizable マネージド プロパティを常に false に設定しておくことを推奨します。 これにより、マネージド ソリューションを使用するユーザーが、ソリューションのこれらのコンポーネントを変更または削除できないように設定できます。 このような変更は、カスタム API の元の定義に向けて記述されたコードを壊す可能性があります。

Is Customizable を false に設定する

Power Apps のソリューションから Is Customizable 管理プロパティを設定することができます。

Is Customizable 管理プロパティを設定する

このプロパティは、各カスタム API、リクエスト・パラメータ、および応答プロパティに対して個別に設定する必要があります。

詳細情報 管理プロパティ

追加要求パラメーターと応答プロパティを追加する

これらのコンポーネントの Is Customizable 管理プロパティを false に設定した場合でも、新しい要求パラメーターや応答プロパティをカスタム API に追加することができます。 ただし、これら要求パラメーターは必須ではありません。 カスタム API でカスタム処理ステップを許可することを選択した場合、カスタム API で作成されたメッセージに対して登録された他のプラグインは、それらを使用することができます。 カスタム要求パラメーターはオプションのみであるため、カスタム API のメイン操作に提供するプラグインには無視され、カスタム要求パラメーターの使用やカスタム応答プロパティの設定について責任を負いません。

カスタム API テーブル/エンティティ

カスタム API を作成するときに使用するテーブルと列の値に関する情報については、CustomAPI テーブル を参照してください。

カスタム処理手順の種類を選択する

次の表に、使用する必要があるカスタム API の カスタム処理手順の種類 (AllowedCustomProcessingStepType) について説明します。

回答内容 使用する場合
なし CustomAPI.PluginTypeId を使用してこのカスタム API に設定されたプラグインが、この操作の実行時に発生する唯一のロジックである場合。
他の開発者が、他のロジックをトリガーしたり、この操作の動作を変更したり、操作をキャンセルしたりできるようなステップをこれ以上登録できないようにします。
カスタム API がカスタマイズすべきでない機能を提供する場合に、このオプションを使用します。
非同期のみ 他の開発者がこの操作の発生時を検出できるようにしたいが、操作のキャンセルや操作の動作のカスタマイズをできないようにしたい場合。
他の開発者は非同期手順を登録して、この操作が発生したことを検出し、完了後に応答することができます。
これは、ビジネス イベント パターンを使用している場合に推奨されるオプションです。 ビジネス イベントは Power Automate のトリガーを作成し、このイベントが発生した際に使用できます。 詳細情報: Microsoft Dataverse ビジネス イベント
同期と非同期 他の開発者が操作の動作を変更できるようにし、ビジネス ロジックで指示されている場合はそれをキャンセルできるようにする場合。
操作が成功した場合、他の開発者もこのイベントを検出し、非同期で実行するロジックを追加することができます。
ほとんどの Dataverse メッセージは、このように拡張機能を有効にします。 メッセージがカスタマイズ可能なビジネス プロセスを表す場合にこのオプションを使用します。

バインディングの種類の選択

バインディングは、操作を特定のテーブルに関連付ける OData の概念です。 次の表に、使用する必要があるカスタム API の バインディングの種類 (BindingType) について説明します。

回答内容 使用する場合
Global 操作が特定のテーブルに適用されない場合。
Entity 操作が特定のテーブルの単一レコードをパラメーターとして受け入れる場合。
EntityCollection 操作が変更を適用するとき、または特定のテーブルのコレクションを返す場合。

Entity または EntityCollection を選択すると、Web API の使用時に関数やアクションの完全修飾名を使用する必要があります。 完全修飾名は、Microsoft.Dynamics.CRM.<UniqueName of the custom API> です。

Entity を選択した場合、種類が EntityReferenceTarget という名前の要求パラメーターが自動的に作成されます。 作成する必要はありません。 この値は、このメッセージに登録されているすべてのプラグインに渡されます。

EntityCollection を選択した場合、エンティティ コレクションを表すパラメーターまたは応答プロパティは含まれません。 このバインドを設定すると、Web API の使用時にエンティティセットに追加された操作が呼び出されるという要件が追加されます。

注意

これらのバインドの種類は、カスタム API を作成するときに使用できますが、エンティティまたはエンティティ コレクションにバインドする必要はありません。 すべてのカスタム API を Global として作成し、バインドされた関数またはアクションと同じ機能を実現するために必要な要求パラメーターまたは応答プロパティを追加します。

詳細情報:

関数を作成する場合

カスタム API の Is Function プロパティは、カスタム API が 関数 または アクション になるかどうかを制御します。 OData では、関数は変更を加えずにデータを返す HTTP GET 要求を使用して呼び出される操作です。 GET 要求を使用し、関数を呼び出すときにすべてのパラメーターが URL のパラメーターとして渡されます。

ブラウザのみを使用して GET リクエストをテストする方が簡単ですが、送信できる URL の長さには 32KB (32,768 文字) の制限があります。 カスタム API には多くの複雑な要求パラメーターがあり、URL の長さが長くなりすぎる可能性がある場合は、POST 要求を使用する本文内のすべてのパラメーター データを渡す、同じ操作を実行するアクションを作成することができます。

注意

  • 関数はデータを返します。 カスタム API を有効にするには、少なくとも 1 つの応答プロパティを含める必要があります。
    • 応答プロパティを含まない関数は、Web API $metadata サービス ドキュメント内に表示されません。
    • 無効な関数を使用しようとすると、このような 404 Not found エラーが発生します。
      {"error":{"code":"0x8006088a","message":"Resource not found for the segment 'your_function_name'."}}
  • ワークフローで有効オプションが選択されている場合、関数は許可されません。 ワークフローでカスタム API を使用するを参照してください
  • 現在、Microsoft Dataverse コネクタはアクションの実行のみを有効にします。 Power Automate を使用して操作を実行する必要がある場合、カスタム API をアクションとして作成する必要があります。

詳細情報: Web API 関数を使用

カスタム API を非公開にする場合

既定では、作成するカスタム API は、他の開発者が検出して使用できるようになります。 カスタム API の公開元として、作成するパブリック API を維持する義務があります。 API を削除したり、他の消費者に破損をもたらすような変更を適用したりしないでください。

他の開発者がカスタム API を使用するのをサポートしない場合、カスタム API を含む管理ソリューションを送付する前に、カスタム API の Is Private (IsPrivate) プロパティを true に設定する必要があります。

Is Private プロパティは、カスタム API が $metadata サービス ドキュメント内に表示されないようにブロックし、Dataverse コード生成ツールがカスタム API のメッセージを使用するためのクラスを作成するのを防止します。

このプロパティを設定することで、他の開発者がそのメッセージを知っていて、使用するための要求を作成できる場合、使用することができないという意味ではありません。 Is Private プロパティの設定は、他の開発者によるメッセージの使用をサポートしていないことを示す方法です。

カスタム API を削除したり、破壊的変更を加えたりする必要がないことが確実になるまで、カスタム API を非公開にしておくことができます。

開発環境において Is Private 設定を false にしておき、$metadata サービス ドキュメントの出力を確認したり、独自に使用するクラスを生成したりすることができます。 ただし、カスタム API を管理ソリューションで送付する前に、Is Private を true に設定する必要があります。

詳細情報:

特権でカスタム API を保護する

カスタム API の Execute Privilege Name (ExecutePrivilegeName) プロパティを要求する特権の名前に設定します。 現在、マイクロソフト以外の開発者が新しい権限を作成する方法はサポートされていませんが、既存の権限を使用できます。 詳細: Q: カスタム API に新しい権限を作成できますか?

プラグインを使用して、カスタム API にロジックを含める

カスタム API のプラグインの種類 (PluginTypeId) を設定しないでメイン操作を指定する場合でも、カスタム API を呼び出すことができます。

カスタム API をビジネス イベントとして使用しているため、プラグインにロジックを含めないことを選択できます。 詳細情報: Microsoft Dataverse ビジネス イベント

テスト手順としてプラグインを追加したくない場合もあります。 プラグインがなければ、設定するコードもないため、出力パラメータの値はその型の既定の値を返します。 それ以外の場合は、カスタム API 用プラグインを記述する を参照してください

注意

メイン操作ロジックに指定されたプラグインに構成データを渡すことはできません。 これには回避策があります

ワークフローでカスタム API を使用する

カスタム API をワークフロー アクションとして呼び出すことを有効にする必要がある場合、カスタム API のワークフローで有効 (WorkflowSdkStepEnabled) を true に設定します。 ただし、このオプションを選択すると、ワークフロー デザイナーでカスタム API を呼び出すことができるように、次の制限が課せられます:

  • カスタム API を関数にすることはできません。 関数である は false である必要があります。

  • カスタム API は、ワークフローがサポートするリクエスト パラメータまたはレスポンス プロパティ タイプのみを持つことができます。

    • Boolean
    • 日時
    • Decimal
    • EntityReference
      • EntityReference は、カスタム API がエンティティにバインドされている場合にのみ使用できます。
    • 浮動
    • 整数
    • お金
    • Picklist
    • 文字列
    • GUID

    次の要求パラメーターまたは応答プロパティの種類は使用できません。

    • エンティティ
    • EntityCollection
    • StringArray

カスタム API の呼び出し

カスタム API は、他の操作と同じように Web API または .NET 用 Dataverse SDK を介して呼び出すことができる新しいメッセージを作成します。

Web API からのカスタム API の呼び出し

テスト中に、Postman や Insomnia などの API クライアントを使用して API を呼び出すことができます。 Dataverse Web API を含む Insomnia を使用するで説明されている手順に従って、必要なアクセス トークンの生成する Insomnia 環境を設定します。 次に、API がアクションである場合は、Web API のアクションを使用するで説明されている手順を適用します。 関数の場合は、Web API 関数を使用する の手順を使用します。

次の例を参照してください。

バインドされていないアクション

このアクションの名前は、myapi_CustomUnboundAPI です。 InputParameter という名前の単一文字列要求パラメーターがあります。

POST [Organization URI]/api/data/v9.1/myapi_CustomUnboundAPI
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

{
  "InputParameter": "Value"
}

テーブルにバインドされた関数

myapi_CustomBoundAPI という名前の関数は、アカウント テーブルにバインドされています。

GET [Organization URI]/api/v9.1/accounts(ed5d4e42-850c-45b7-8b38-2677545107cc)/Microsoft.Dynamics.CRM.myapi_CustomBoundAPI()
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

テーブル コレクションにバインドされた関数

myapi_CustomEntityCollectionBoundAPI という名前の関数は、アカウント テーブル コレクションにバインドされています。

GET [Organization URI]/api/v9.1/accounts/Microsoft.Dynamics.CRM.myapi_CustomEntityCollectionBoundAPI()
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json; charset=utf-8

詳細情報:

.NET 用 SDK からのカスタム API の呼び出し

早期バインド済みまたは遅延バインド済みのコードのいずれかを使用して、カスタム API を呼び出すことができます。 pac modelbuilder ビルド ツールを使用して、カスタム API の要求パラメーターと応答プロパティを公開するためのヘルパー要求クラスと応答クラスを生成します。 .NET 用 SDK のアーリーバウンド クラスの生成については、こちらをご覧ください

遅延バインディング コードや、非公開に設定したカスタム API の場合は、カスタム API の固有名で OrganizationRequest を作成し、要求プロパティの固有名と一致する名前のパラメーターを追加します。

エンティティ バインド済みのカスタム API には、API 上で呼び出すレコードの EntityReference を設定する必要がある、Target という名前の暗黙的なリクエスト プロパティがあります。

返された応答のパラメーターから応答プロパティにアクセスできます。

この例では myapi_EscalateCase という名前のカスタム API が、Priority という名前の他のオプション セット値要求パラメーターと共に、Target パラメーターとしてレコードを受け入れるようにインシデント テーブルにバインドされます。 AssignedTo という名前の EntityReference 応答プロパティがあります。

var req = new OrganizationRequest("myapi_EscalateCase")
{
  ["Target"] = new EntityReference("incident", guid),
  ["Priority"] = new OptionSetValue(1)
};

var resp = svc.Execute(req);

var newOwner = (EntityReference) resp["AssignedTo"];

詳細: メッセージを .NET 用 SDK と共に使用する

カスタム API をバックグラウンド操作として呼び出す

バックグラウンド操作を使用して実行されるロジックは、カスタム API として定義する必要があります。 詳細: バックグラウンド操作 (プレビュー)

カスタム API で使用するプラグインを記述する

カスタム API のメイン操作を実装するプラグインを記述することは、プラグイン登録ツールを使用して特定のステップを設定しないことと、プラグインに渡す構成データを指定できない ことを除けば、他のプラグインを記述することと変わりません。

次の情報を知っておく必要があります:

  • メッセージの名前
  • 要求パラメーターと応答プロパティの名前と種類。

要求パラメータの値は、InputParameters に含まれます。

OutputParameters の応答パラメーターで使用する値を設定する必要があります。

以下のコードは、StringParameter の文字を逆にして結果を StringProperty として返す簡単なプラグインです。

using System;
using System.Linq;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;

namespace CustomAPIExamples
{
    public class Sample_CustomAPIExample : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the tracing service
            ITracingService tracingService =
            (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.  
            IPluginExecutionContext context = (IPluginExecutionContext)
                serviceProvider.GetService(typeof(IPluginExecutionContext));

            if (context.MessageName.Equals("sample_CustomAPIExample") && context.Stage.Equals(30)) {

                try
                {
                    string input = (string)context.InputParameters["StringParameter"];
                    
                    if (!string.IsNullOrEmpty(input)) {
                        //Simply reversing the characters of the string
                        context.OutputParameters["StringProperty"] = new string(input.Reverse().ToArray());
                    }
                }
                catch (Exception ex)
                {
                    tracingService.Trace("Sample_CustomAPIExample: {0}", ex.ToString());
                    throw new InvalidPluginExecutionException("An error occurred in Sample_CustomAPIExample.", ex);
                }
            }
            else
            {
                tracingService.Trace("Sample_CustomAPIExample plug-in is not associated with the expected message or is not registered for the main operation.");
            }
        }
    }
}

プラグインの作成の詳細については、チュートリアル : プラグインを作成して登録するを参照してください。 アセンブリの登録は必要ですが、手順の登録は必要ありません。 詳細情報: プラグインを使用して、カスタム API にロジックを含めるを参照してください

サンプル: IsSystemAdmin カスタム API の例を参照してください

アセンブリの登録後は、必ずアセンブリと任意のタイプをソリューションに追加してください。

ローカライズされたラベルの値

カスタム API には、ローカライズ可能なラベルがいくつかあります。 ラベルの値をローカライズするには、次で説明している手順に従う必要があります : モデル駆動型アプリに向けたローカライズされたテキストを翻訳するラベルや表示文字列の翻訳

このプロセスには、基本言語の値を含むファイルをエクスポートし、有効になっている各言語に列を含めます。 その後、Excel で値を編集できます。 翻訳をインポートするプロセスを完了すると、ラベルがソリューションに含まれます。

次の例は、Excel ワークシートを編集して、英語の値に日本語翻訳を追加する方法を示しています。

ラベルがどのようにローカライズされているかを示します。

ヒント

ソリューション ファイルを編集して、カスタム API を作成する場合は、ローカライズされたラベルを直接提供できます。 詳細: ソリューションでローカライズされたラベルを提供する

ローカライズされた値の設定

上記の手動プロセスを使用するのではなく、コードでローカライズされたラベルを設定したい場合は、Web API のいずれかを使用した SetLocLabels メッセージSetLocLabels アクション または .NET 用 SDK SetLocLabelsRequest を使用できます。

次の例は、WebAPI を使用して、カスタム API の displayname プロパティのローカライズされたラベルを設定する方法を示しています。

要求:

POST [Organization URI]/api/data/v9.1/SetLocLabels HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
Content-Type: application/json

{
    "EntityMoniker": {
        "@odata.type": "Microsoft.Dynamics.CRM.customapi",
        "customapiid": "86bcd12e-2f30-eb11-a813-000d3a122b89"
    },
    "AttributeName": "displayname",
    "Labels": [
        {
            "Label": "例え",
            "LanguageCode": 1041
        },
        {
            "Label": "Beispiel",
            "LanguageCode": 1031
        },
        {
            "Label": "ejemplo",
            "LanguageCode": 1034
        }
    ]
}

応答:

HTTP/1.1 204 No Content

ローカライズされた値の取得

ローカライズされたラベルを取得するには、Web API RetrieveLocLabels 関数 または SDK for .NET RetrieveLocLabelsRequest クラス のいずれかを使用して RetrieveLocLabels メッセージを使用します。

次の例は、RetrieveLocLabels 関数を使用して、カスタム API の displayname プロパティのラベルを 88602189-183d-4584-ba4b-8b60f0f5b89fcustomapiid で取得する方法を示しています

要求:

GET [Organization URI]/api/data/v9.1/RetrieveLocLabels(EntityMoniker=@p1,AttributeName=@p2,IncludeUnpublished=@p3)?
@p1={'@odata.id':'customapis(88602189-183d-4584-ba4b-8b60f0f5b89f)'}&
@p2='displayname'&
@p3=false HTTP/1.1

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

{
    "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#Microsoft.Dynamics.CRM.RetrieveLocLabelsResponse",
    "Label": {
        "LocalizedLabels": [
            {
                "Label": "Custom API Example",
                "LanguageCode": 1033,
                "IsManaged": null,
                "MetadataId": null,
                "HasChanged": null
            },
            {
                "Label": "カスタムAPIの例",
                "LanguageCode": 1041,
                "IsManaged": null,
                "MetadataId": null,
                "HasChanged": null
            }
        ],
        "UserLocalizedLabel": {
            "Label": "Custom API Example",
            "LanguageCode": 1033,
            "IsManaged": null,
            "MetadataId": null,
            "HasChanged": null
        }
    }
}

よく寄せられる質問 (FAQ)

以下のような質問があります:

Q: カスタム API に新しい権限を作成できますか?

A: カスタム API には 実行する権限名 (ExecutePrivilegeName) プロパティがありますが、現在、この API 専用の新しい権限を作成する方法はサポートされていません。 この機能は、将来のリリースで計画されています。 それまでの間、2 つのオプションがあります:

  • 既存の Privilege.Name 値を使用できます。
  • カスタム エンティティを作成し、そのエンティティ用に作成された権限の 1 つを使用できます。 たとえば、new_myaction という名前のエンティティを作成すると、CRUD 操作の権限が生成されます。 例: prvCreatenew_myaction。 カスタム API を含むソリューションと共に、このカスタム エンティティを含める必要があります。

Q: カスタム API レコードをアクティブ化または非アクティブ化できますか?

A: できません。 これらのレコードには、ほとんどの Microsoft Dataverse テーブルに見られる共通の 状態ステータス の列があります。 これらの列の値を設定しても、カスタム API の可用性、リクエスト パラメーター、レスポンス プロパティには影響しません。

Q: 非公開メッセージが Web API $Metadata Service ドキュメントに含まれていない場合、どうすれば使用できますか?

A: 非公開メッセージは、Web API CSDL $Metadata ドキュメント で通知されているかどうかに関係なく機能します。 ソリューションを開発している間、IsPrivate 値を false に設定したままにしておくことができます。 この方法により、$metadata の一覧を参照し、このデータに依存するコード生成ツールを使用できます。 ただし、他のユーザーが使用できるようにソリューションを送る前に、CustomAPI.IsPrivate の値を true に設定する必要があります。 後で、メッセージを使用する他のアプリケーションをサポートする場合、CustomAPI.IsPrivate の値を false に変更できます。

詳細情報:

カスタム API に関する既知の問題

カスタム API が一般提供されていますが、まだ関連する機能で変更が予定されています。

デバッグにプロファイラーを使用できません

プラグイン登録ツールとプラグイン プロファイラー ソリューションを使用してデバッグするには、特定のプラグイン ステップを選択できる必要があります。 プラグイン用のメイン ステージの実装は、現在プラグイン登録ツールでは利用できません。

回避策: カスタム API 用に作成したメッセージの PostOperation ステージにプラグイン タイプを登録します。

プライベート メッセージはプラグインでは使用できません

カスタム API をプライベートとして定義した場合、そのメッセージをプラグインで使用することはできません。 詳細丈夫: 非公開メッセージ

カスタム API メイン操作プラグインにセキュリティで保護された構成とセキュリティで保護されていない構成を設定することはできません

カスタム API のメイン操作プラグインに セキュリティで保護された構成やセキュリティで保護されていない構成 を渡すことはできません。

回避策: プラグインをカスタム API に関連付けるのではなく、プラグイン登録ツール (PRT) を使用して PostOperation ステージにプラグインを登録します。 こうすることで、通常行うように PostOperation プラグイン ステップで構成データを指定 できます。

この回避策を使用するには、カスタム API の作成時に 同期と非同期 カスタム処理手順の種類 を有効にするようにカスタム API を構成する必要があります。 これを作成した後は変更できません。

次のステップ

プラグイン登録ツールを使用してカスタム API を作成する

参照

カスタム API の作成と使用
コードを使用したカスタム API を作成する
ソリューション ファイルを使用したカスタム API の作成
独自のメッセージを作成する
カスタム API テーブル

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。