使用应用商店服务访问分析数据

使用 Microsoft Store 分析 API,针对已注册到你的或组织的 Windows 合作伙伴中心帐户的应用以编程方式检索分析数据。 此 API 使你可以针对应用和加载项(也称为应用内产品或 IAP)购置、错误、应用评分和评价检索数据。 此 API 使用 Azure Active Directory (Azure AD) 验证来自应用或服务的调用。

以下步骤介绍端到端过程:

  1. 确保已完成所有先决条件
  2. 在 Microsoft Store 分析 API 中调用某个方法之前,请先获取 Azure AD 访问令牌。 获取访问令牌后,可以在 60 分钟的令牌有效期内,使用该令牌调用 Microsoft Store 分析 API。 该令牌到期后,可以重新生成一个。
  3. 调用 Microsoft Store 分析 API

步骤 1:完成使用 Microsoft Store 分析 API 的先决条件

在开始编写调用 Microsoft Store 分析 API 的代码之前,确保已完成以下先决条件。

  • 你(或你的组织)必须有一个 Azure AD 目录,并且必须对该目录拥有全局管理员权限。 如果你已使用 Microsoft 365 或 Microsoft 的其他业务服务,表示你已经具有 Azure AD 目录。 否则,你可以免费在合作伙伴中心中创建新的 Azure AD

  • 你必须将 Azure AD 应用程序与你的合作伙伴中心帐户相关联、检索应用程序的租户 ID 和客户端 ID 并生成密钥。 Azure AD 应用程序是指你想要从中调用 Microsoft Store 分析 API 的应用或服务。 需要使用该租户 ID、客户端 ID 和密钥来获取要传递给 API 的 Azure AD 访问令牌。

    注意

    你只需执行一次此任务。 获取租户 ID、客户端 ID 和密钥后,每当需要创建新的 Azure AD 访问令牌时,都可以重复使用它们。

若要将 Azure AD 应用程序与你的合作伙伴中心帐户相关联并检索所需值:

  1. 在合作伙伴中心,将组织的合作伙伴中心帐户与组织的 Azure AD 目录相关联

  2. 然后,从合作伙伴中心的帐户设置部分的用户页面添加 Azure AD 应用程序,这里的应用程序表示应用或服务并且将用于访问合作伙伴中心帐户的分析数据。 确保为此应用程序分配“管理者”角色。 如果你的 Azure AD 目录中尚不包含该应用程序,可以在合作伙伴中心创建新的 Azure AD 应用程序

  3. 返回到“用户”页,单击 Azure AD 应用程序的名称转到“应用程序设置”,然后复制“租户 ID”和“客户端 ID”值。

  4. 单击“添加新密钥”。 在下一个屏幕上,复制“密钥”值。 离开此页后,不再可以访问此信息。 有关详细信息,请参阅管理 Azure AD 应用程序的密钥

步骤 2:获取 Azure AD 访问令牌

在 Microsoft Store 分析 API 中调用任何方法之前,首先必须获取将传递给该 API 中每个方法的 Authorization 标头的 Azure AD 访问令牌。 获取访问令牌后,你有 60 分钟的时间来使用它,60 分钟后它将过期。 该令牌到期后,可以对它进行刷新,以便可以在之后调用该 API 时继续使用。

若要获取访问令牌,请按照 使用客户端凭据的服务到服务调用 中的说明将 HTTP POST 发送到 https://login.microsoftonline.com/<tenant_id>/oauth2/token 终结点。 示例请求如下所示。

POST https://login.microsoftonline.com/<tenant_id>/oauth2/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8

grant_type=client_credentials
&client_id=<your_client_id>
&client_secret=<your_client_secret>
&resource=https://manage.devcenter.microsoft.com

对于 POST URI 中的 tenant_id 值以及 client_idclient_secret 参数,请指定在上一部分中从合作伙伴中心中为应用程序检索的租户 ID、客户端 ID 和密钥。 对于 resource 参数,必须指定 https://manage.devcenter.microsoft.com

在你的访问令牌到期后,你可按照此处的说明刷新令牌。

> [!NOTE]
> ResourceType='Graph.windows.net' will be deprecated after September 2023. Please migrate to ResourceType ='Graph.microsoft.com'

步骤 3:调用 Microsoft Store 分析 API

获取 Azure AD 访问令牌后,可以随时调用 Microsoft Store 分析 API。 你必须将访问令牌传递到每个方法的 Authorization 标头。

UWP 应用和游戏的方法

以下方法可用于应用、游戏购置和附加购置:

适用于 UWP 应用的方法

在合作伙伴中心,UWP 应用可以使用以下分析方法。

场景 方法
购置、转换、安装和使用
应用错误
洞察力
评分和评价
应用内广告和广告活动

适用于桌面应用程序的方法

属于 Windows 桌面应用程序计划的开发人员帐户可以使用以下分析方法。

场景 方法
安装次数
应用程序错误
洞察力

适用于 Xbox Live 服务的方法

使用 Xbox Live 服务的游戏开发人员帐户可以使用以下其他方法。 适用于 Xbox 的 Microsoft Store 分析 API 不再可用。 gaming/xbox-live/get-started/join-dev-program/join-dev-program_nav

场景 方法
常规分析

适用于硬件和驱动程序的方法

属于 Windows 硬件仪表板程序的开发人员帐户可以访问一组额外的方法来检索硬件和驱动程序的分析数据。 有关详细信息,请参阅硬件仪表板 API

代码示例

以下代码示例演示如何获取 Azure AD 访问令牌以及如何从 C# 控制台应用调用 Microsoft Store 分析 API。 若要使用此代码示例,请将 tenantIdclientIdclientSecretappID 变量分配给你的方案的相应值。 此示例需要 Newtonsoft 中的 Json.NET 程序包,以便反序列化 Microsoft Store 分析 API 返回的 JSON 数据。

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace TestAnalyticsAPI
{
    class Program
    {
        static void Main(string[] args)
        {
            string tenantId = "<your tenant ID>";
            string clientId = "<your client ID>";
            string clientSecret = "<your secret>";

            string scope = "https://manage.devcenter.microsoft.com";

            // Retrieve an Azure AD access token
            string accessToken = GetClientCredentialAccessToken(
                    tenantId,
                    clientId,
                    clientSecret,
                    scope).Result;

            // This is your app's Store ID. This ID is available on
            // the App identity page of the Dev Center dashboard.
            string appID = "<your app's Store ID>";

            DateTime startDate = DateTime.Parse("08-01-2015");
            DateTime endDate = DateTime.Parse("11-01-2015");
            int pageSize = 1000;
            int startPageIndex = 0;

            // Call the Windows Store analytics API
            CallAnalyticsAPI(accessToken, appID, startDate, endDate, pageSize, startPageIndex);

            Console.Read();
        }

        private static void CallAnalyticsAPI(string accessToken, string appID, DateTime startDate, DateTime endDate, int top, int skip)
        {
            string requestURI;

            // Get app acquisitions
            requestURI = string.Format(
                "https://manage.devcenter.microsoft.com/v1.0/my/analytics/appacquisitions?applicationId={0}&startDate={1}&endDate={2}&top={3}&skip={4}",
                appID, startDate, endDate, top, skip);

            //// Get add-on acquisitions
            //requestURI = string.Format(
            //    "https://manage.devcenter.microsoft.com/v1.0/my/analytics/inappacquisitions?applicationId={0}&startDate={1}&endDate={2}&top={3}&skip={4}",
            //    appID, startDate, endDate, top, skip);

            //// Get app failures
            //requestURI = string.Format(
            //    "https://manage.devcenter.microsoft.com/v1.0/my/analytics/failurehits?applicationId={0}&startDate={1}&endDate={2}&top={3}&skip={4}",
            //    appID, startDate, endDate, top, skip);

            //// Get app ratings
            //requestURI = string.Format(
            //    "https://manage.devcenter.microsoft.com/v1.0/my/analytics/ratings?applicationId={0}&startDate={1}&endDate={2}top={3}&skip={4}",
            //    appID, startDate, endDate, top, skip);

            //// Get app reviews
            //requestURI = string.Format(
            //    "https://manage.devcenter.microsoft.com/v1.0/my/analytics/reviews?applicationId={0}&startDate={1}&endDate={2}&top={3}&skip={4}",
            //    appID, startDate, endDate, top, skip);

            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, requestURI);
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

            WebRequestHandler handler = new WebRequestHandler();
            HttpClient httpClient = new HttpClient(handler);

            HttpResponseMessage response = httpClient.SendAsync(requestMessage).Result;

            Console.WriteLine(response);
            Console.WriteLine(response.Content.ReadAsStringAsync().Result);

            response.Dispose();
        }

        public static async Task<string> GetClientCredentialAccessToken(string tenantId, string clientId, string clientSecret, string scope)
        {
            string tokenEndpointFormat = "https://login.microsoftonline.com/{0}/oauth2/token";
            string tokenEndpoint = string.Format(tokenEndpointFormat, tenantId);

            dynamic result;
            using (HttpClient client = new HttpClient())
            {
                string tokenUrl = tokenEndpoint;
                using (
                    HttpRequestMessage request = new HttpRequestMessage(
                        HttpMethod.Post,
                        tokenUrl))
                {
                    string content =
                        string.Format(
                            "grant_type=client_credentials&client_id={0}&client_secret={1}&resource={2}",
                            clientId,
                            clientSecret,
                            scope);

                    request.Content = new StringContent(content, Encoding.UTF8, "application/x-www-form-urlencoded");

                    using (HttpResponseMessage response = await client.SendAsync(request))
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();
                        result = JsonConvert.DeserializeObject(responseContent);
                    }
                }
            }

            return result.access_token;
        }
    }
}

错误响应

Microsoft Store 分析 API 在 JSON 对象中返回含有错误代码和消息的错误响应。 以下示例演示了由无效参数引起的错误响应。

{
    "code":"BadRequest",
    "data":[],
    "details":[],
    "innererror":{
        "code":"InvalidQueryParameters",
        "data":[
            "top parameter cannot be more than 10000"
        ],
        "details":[],
        "message":"One or More Query Parameters has invalid values.",
        "source":"AnalyticsAPI"
    },
    "message":"The calling client sent a bad request to the service.",
    "source":"AnalyticsAPI"
}