Cómo funciona

Introducción

La API de inscripción automática ayuda a los revendedores de dispositivos a automatizar su integración. Las herramientas de ventas de tu organización pueden incorporar la inscripción automática, lo que aumenta la productividad de tus usuarios y clientes. Usa la API para ayudar a tus usuarios a lograr lo siguiente:

  • Asignar los dispositivos comprados a la cuenta de inscripción automática de un cliente
  • Crear la cuenta de inscripción automática de tu cliente
  • Conecta el teléfono de tu organización y los metadatos de pedidos a los dispositivos.
  • Crear informes sobre los dispositivos asignados a tus clientes

En este documento, se presenta la API y se explican los patrones. Si quieres explora la API por tu cuenta, prueba una guía de inicio rápido para Java .NET o Python.

Conceptos de la API

Los clientes y los dispositivos son los recursos principales que usas en la API. Para crear clientes, llama a create. Puedes crear dispositivos a través de los métodos de la API de reclamación (ver a continuación) Tu organización también puede crear clientes y dispositivos con el portal de inscripción automática.

Relación entre el dispositivo y los recursos del cliente

Cliente
Empresas a las que tu organización les vende dispositivos. Los clientes tienen un name y un ID. Usa a un cliente cuando quieras reclamar o encontrar sus dispositivos. Para obtener más información, consulta Customer.
Dispositivo
Un dispositivo Android o ChromeOS compatible con la inscripción sin intervención que tu organización le vende a un cliente. Los dispositivos tienen IDs de hardware, metadatos y datos reclamos. Los dispositivos son fundamentales para la API, por lo que los usas en casi todos los métodos. Para obtener más información, consulta Device.
DeviceIdentifier
Encapsula los IDs de hardware, como IMEI o MEID, para identificar un dispositivo dispositivo. Usa un DeviceIdentifier para orientar el dispositivo. que deseas encontrar, actualizar o reclamar. Para obtener más información, consulta Identificadores.
DeviceMetadata
Almacena pares clave-valor de metadatos para el dispositivo. Usa DeviceMetadata para almacenar los metadatos de tu organización. Para Para obtener más información, lee Metadatos del dispositivo.

Para enumerar todos los métodos y recursos de la API que puede usar tu app, consulta la Referencia de la API.

Crea clientes

En el caso de los dispositivos Android, el revendedor es responsable de crear el cliente en nombre de su cliente. El cliente usará esta cuenta para acceder al portal de inscripción automática y configurar la configuración de aprovisionamiento de sus dispositivos. Esto no es necesario para los dispositivos ChromeOS, que ya tienen una cuenta de Google Workspace que usarán para configurar su configuración de aprovisionamiento.

Puedes llamar al método de la API create para crear cuentas de clientes para la inscripción automática. Dado que los clientes ven la nombre de la empresa en su portal de inscripción automática, el usuario de tu app confirma que sea correcta. No puedes editar el nombre de un cliente después de crearlo.

Para ser el propietario, debes incluir al menos una dirección de correo electrónico corporativa asociada a una Cuenta de Google. No puedes usar cuentas de Gmail personales con el API de gcloud. Si el cliente necesita ayuda para asociar la cuenta, envíale las instrucciones de Cómo asociar una Cuenta de Google.

Después de crear un cliente llamando a la API, este administra la infraestructura de sus empleados acceso al portal, no puedes editar las contraseñas los usuarios que usan la API. El fragmento a continuación, se muestra cómo crear un cliente:

Java

// Provide the customer data as a Company type.
// The API requires a name and owners.
Company customer = new Company();
customer.setCompanyName("XYZ Corp");
customer.setOwnerEmails(Arrays.asList("liz@example.com", "darcy@example.com"));
customer.setAdminEmails(Collections.singletonList("jane@example.com"));

// Use our reseller ID for the parent resource name.
String parentResource = String.format("partners/%d", PARTNER_ID);

// Call the API to create the customer using the values in the company object.
CreateCustomerRequest body = new CreateCustomerRequest();
body.setCustomer(customer);
Company response = service.partners().customers().create(parentResource, body).execute();

.NET

// Provide the customer data as a Company type.
// The API requires a name and owners.
var customer = new Company
{
    CompanyName = "XYZ Corp",
    OwnerEmails = new String[] { "liz@example.com", "darcy@example.com" },
    AdminEmails = new String[] { "jane@example.com" }
};

// Use our reseller ID for the parent resource name.
var parentResource = String.Format("partners/{0}", PartnerId);

// Call the API to create the customer using the values in the company object.
var body = new CreateCustomerRequest
{
    Customer = customer
};
var request = service.Partners.Customers.Create(body, parentResource);
var response = request.Execute();

Python

# Provide the customer data as a Company type. The API requires
# a name and at least one owner.
company = {'companyName':'XYZ Corp', \
  'ownerEmails':['liz@example.com', 'darcy@example.com'], \
  'adminEmails':['jane@example.com']}

# Use our reseller ID for the parent resource name.
parent_resource = 'partners/{0}'.format(PARTNER_ID)

# Call the API to create the customer using the values in the company object.
response = service.partners().customers().create(parent=parent_resource,
    body={'customer':company}).execute()

Para obtener más información sobre los roles de propietario y administrador de los empleados de tu cliente, Consulta Usuarios del portal.

Reclama dispositivos para los clientes

Después de que tus clientes compren dispositivos, querrán configurar el aprovisionamiento para estos dispositivos en su cuenta. Cuando se reclama un dispositivo, se agrega el dispositivo a la inscripción automática y le da al cliente la capacidad de configurar de aprovisionamiento.

El registro de aprovisionamiento de un dispositivo tiene una sección para la inscripción automática. Tú asignar el dispositivo reclamando la sección de inscripción automática del registro para un cliente. Llama a los métodos partners.devices.claim o partners.devices.claimAsync con el cliente como argumento. Siempre proporciona SECTION_TYPE_ZERO_TOUCH como un valor para sectionType

Deberás retirar el reclamo del dispositivo de un cliente (consulta a continuación) antes de poder reclamar el mismo dispositivo para otro cliente. Los métodos de reclamos validan los campos DeviceIdentifier, incluidos el IMEI o MEID, o el número de serie, el nombre del fabricante y el modelo, y el ID de dispositivo certificado para dispositivos ChromeOS cuando se crea un dispositivo nuevo.

En el siguiente fragmento, se muestra cómo reclamar un dispositivo:

Java

// Identify the device to claim.
DeviceIdentifier identifier = new DeviceIdentifier();
// The manufacturer value is optional but recommended for cellular devices
identifier.setManufacturer("Google");
identifier.setImei("098765432109875");

// Create the body to connect the customer with the device.
ClaimDeviceRequest body = new ClaimDeviceRequest();
body.setDeviceIdentifier(identifier);
body.setCustomerId(customerId);
body.setSectionType("SECTION_TYPE_ZERO_TOUCH");

// Claim the device.
ClaimDeviceResponse response = service.partners().devices().claim(PARTNER_ID, body).execute();

.NET

// Identify the device to claim.
var deviceIdentifier = new DeviceIdentifier
{
    // The manufacturer value is optional but recommended for cellular devices
    Manufacturer = "Google",
    Imei = "098765432109875"
};

// Create the body to connect the customer with the device.
ClaimDeviceRequest body = new ClaimDeviceRequest
{
    DeviceIdentifier = deviceIdentifier,
    CustomerId = CustomerId,
    SectionType = "SECTION_TYPE_ZERO_TOUCH"
};

// Claim the device.
var response = service.Partners.Devices.Claim(body, PartnerId).Execute();

Python

# Identify the device to claim.
# The manufacturer value is optional but recommended for cellular devices
device_identifier = {'manufacturer':'Google', 'imei':'098765432109875'}

# Create the body to connect the customer with the device.
request_body = {'deviceIdentifier':device_identifier, \
    'customerId':customer_id, \
    'sectionType':'SECTION_TYPE_ZERO_TOUCH'}

# Claim the device.
response = service.partners().devices().claim(partnerId=PARTNER_ID,
    body=request_body).execute()

Reclamo de dispositivos

Tu organización puede retirar el reclamo de un dispositivo a un cliente. Cómo retirar un dispositivo la quita de la inscripción automática. Un revendedor puede anular el reclamo de un dispositivo que desea migrar a otra cuenta, devolver o que se reclamó por error. Llama al método partners.devices.unclaim o partners.devices.unclaimAsync para anular el reclamo de un dispositivo de un cliente.

Proveedores

Puedes usar proveedores para representar a socios revendedores en tu red de concesionarios, operadores locales dentro de una red de revendedores global o cualquier organización que venda dispositivos en tu nombre. Los proveedores te ayudan a separar a tus usuarios, clientes y dispositivos:

  • Los proveedores que crees no podrán ver tu cuenta de inscripción automática ni las de los demás.
  • Puedes ver los clientes y los dispositivos de tus proveedores, y puedes cancelar el registro de los dispositivos de los proveedores. Sin embargo, no puedes asignar dispositivos a las cuentas de tus proveedores clientes.

Usa el portal para crear proveedores para tu organización. No puedes usar la API. Para crear un proveedor nuevo, tu rol de cuenta debe ser Propietario. Si tu organización tiene proveedores, puedes llamar a partners.vendors.list para que muestre tus proveedores y partners.vendors.customers.list para atraer a los clientes del proveedor. En el siguiente ejemplo, se usan ambos métodos para imprimir un informe que muestra el estado de las Condiciones del Servicio de los clientes de los proveedores:

Java

// First, get the organization's vendors.
String parentResource = String.format("partners/%d", PARTNER_ID);
ListVendorsResponse results = service.partners().vendors().list(parentResource).execute();
if (results.getVendors() == null) {
  return;
}

// For each vendor, report the company name and a maximum 5 customers.
for (Company vendor: results.getVendors()) {
  System.out.format("\n%s customers\n", vendor.getCompanyName());
  System.out.println("---");
  // Use the vendor's API resource name as the parent resource.
  AndroidProvisioningPartner.Partners.Vendors.Customers.List customerRequest =
      service.partners().vendors().customers().list(vendor.getName());
  customerRequest.setPageSize(5);
  ListVendorCustomersResponse customerResponse = customerRequest.execute();

  List<Company> customers = customerResponse.getCustomers();
  if (customers == null) {
    System.out.println("No customers");
    break;
  } else {
    for (Company customer: customers) {
      System.out.format("%s: %s\n",
          customer.getCompanyName(),
          customer.getTermsStatus());
    }
  }
}

.NET

// First, get the organization's vendors.
var parentResource = String.Format("partners/{0}", PartnerId);
var results = service.Partners.Vendors.List(parentResource).Execute();
if (results.Vendors == null)
{
    return;
}

// For each vendor, report the company name and a maximum 5 customers.
foreach (Company vendor in results.Vendors)
{
    Console.WriteLine("\n{0} customers", vendor);
    Console.WriteLine("---");
    // Use the vendor's API resource name as the parent resource.
    PartnersResource.VendorsResource.CustomersResource.ListRequest customerRequest =
        service.Partners.Vendors.Customers.List(vendor.Name);
    customerRequest.PageSize = 5;
    var customerResponse = customerRequest.Execute();

    IList<Company> customers = customerResponse.Customers;
    if (customers == null)
    {
        Console.WriteLine("No customers");
        break;
    }
    else
    {
        foreach (Company customer in customers)
        {
            Console.WriteLine("{0}: {1}", customer.Name, customer.TermsStatus);
        }
    }
}

Python

# First, get the organization's vendors.
parent_resource = 'partners/{0}'.format(PARTNER_ID)
vendor_response = service.partners().vendors().list(
    parent=parent_resource).execute()
if 'vendors' not in vendor_response:
  return

# For each vendor, report the company name and a maximum 5 customers.
for vendor in vendor_response['vendors']:
  print '\n{0} customers'.format(vendor['companyName'])
  print '---'
  # Use the vendor's API resource name as the parent resource.
  customer_response = service.partners().vendors().customers().list(
      parent=vendor['name'], pageSize=5).execute()
  if 'customers' not in customer_response:
    print 'No customers'
    break
  for customer in customer_response['customers']:
    print '  {0}: {1}'.format(customer['name'], customer['termsStatus'])

Si tienes una colección de dispositivos, es posible que debas saber qué revendedor o proveedor reclamó el dispositivo. Para obtener el ID numérico del revendedor, inspecciona el valor del campo resellerId en el registro de reclamos de un dispositivo.

Tu organización puede retirar un reclamo de un dispositivo reclamado por el proveedor. En el caso de otras llamadas a la API que modifican dispositivos, debes verificar que tu organización haya reclamado el dispositivo antes de llamar al método de la API. En el siguiente ejemplo, se muestra cómo puedes hacerlo:

Java

// Get the devices claimed for two customers: one of our organization's
// customers and one of our vendor's customers.
FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest();
body.setSectionType("SECTION_TYPE_ZERO_TOUCH");
body.setCustomerId(Arrays.asList(resellerCustomerId, vendorCustomerId));
body.setLimit(MAX_PAGE_SIZE);
FindDevicesByOwnerResponse response =
    service.partners().devices().findByOwner(PARTNER_ID, body).execute();
if (response.getDevices() == null) {
  return;
}

for (Device device: response.getDevices()) {
  // Confirm the device was claimed by our reseller and not a vendor before
  // updating metadata in another method.
  for (DeviceClaim claim: device.getClaims()) {
    if (claim.getResellerId() == PARTNER_ID) {
      updateDeviceMetadata(device.getDeviceId());
      break;
    }
  }
}

.NET

// Get the devices claimed for two customers: one of our organization's
// customers and one of our vendor's customers.
FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest
{
    Limit = MaxPageSize,
    SectionType = "SECTION_TYPE_ZERO_TOUCH",
    CustomerId = new List<long?>
    {
        resellerCustomerId,
        vendorCustomerId
    }
};
var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute();
if (response.Devices == null)
{
    return;
}

foreach (Device device in response.Devices)
{
    // Confirm the device was claimed by our reseller and not a vendor before
    // updating metadata in another method.
    foreach (DeviceClaim claim in device.Claims)
    {
        if (claim.ResellerId == PartnerId)
        {
            UpdateDeviceMetadata(device.DeviceId);
            break;
        }
    }
}

Python

# Get the devices claimed for two customers: one of our organization's
# customers and one of our vendor's customers.
request_body = {'limit':MAX_PAGE_SIZE, \
  'pageToken':None, \
  'customerId':[reseller_customer_id, vendor_customer_id], \
  'sectionType':'SECTION_TYPE_ZERO_TOUCH'}
response = service.partners().devices().findByOwner(partnerId=PARTNER_ID,
    body=request_body).execute()

for device in response['devices']:
  # Confirm the device was claimed by our reseller and not a vendor before
  # updating metadata in another method.
  for claim in device['claims']:
    if claim['resellerId'] == PARTNER_ID:
      update_device_metadata(device['deviceId'])
      break

Operaciones por lotes de larga duración

La API incluye versiones asíncronas de los métodos de dispositivos. Estos métodos permiten el procesamiento por lotes de muchos dispositivos, mientras que los métodos síncronos procesan un dispositivo para cada solicitud a la API. Los nombres de métodos asíncronos Tener un sufijo Async, por ejemplo, claimAsync.

Los métodos asíncronos de la API muestran un resultado antes de que se complete el procesamiento. Los métodos asíncronos también ayudan a que tu app (o herramienta) sea responsiva para tu usuarios mientras esperan que se complete una operación de larga duración. Tu app debe verificar el estado de la operación de forma periódica.

Operaciones

Usas un Operation para hacer un seguimiento de una operación por lotes de larga duración. Una llamada correcta a un método asíncrono muestra una referencia a la operación en la respuesta. En el siguiente fragmento JSON, se muestra una respuesta típica después de llamar a updateMetadataAsync:

{
  "name": "operations/apibatchoperation/1234567890123476789"
}

Cada operación contiene una lista de tareas individuales. Llamada operations.get para obtener información sobre el estado y resultados de las tareas contenidas en la operación. El siguiente fragmento muestra cómo podría hacer esto. En tu propia app, deberás controlar cualquier error.

Java

// Build out the request body to apply the same order number to a customer's
// purchase of 2 devices.
UpdateMetadataArguments firstUpdate = new UpdateMetadataArguments();
firstUpdate.setDeviceMetadata(metadata);
firstUpdate.setDeviceId(firstTargetDeviceId);

UpdateMetadataArguments secondUpdate = new UpdateMetadataArguments();
secondUpdate.setDeviceMetadata(metadata);
secondUpdate.setDeviceId(firstTargetDeviceId);

// Start the device metadata update.
UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest();
body.setUpdates(Arrays.asList(firstUpdate, secondUpdate));
Operation response = service
    .partners()
    .devices()
    .updateMetadataAsync(PARTNER_ID, body)
    .execute();

// Assume the metadata update started, so get the Operation for the update.
Operation operation = service.operations().get(response.getName()).execute();

.NET

// Build out the request body to apply the same order number to a customer's
// purchase of 2 devices.
var updates = new List<UpdateMetadataArguments>
{
    new UpdateMetadataArguments
    {
        DeviceMetadata = metadata,
        DeviceId = firstTargetDeviceId
    },
    new UpdateMetadataArguments
    {
        DeviceMetadata = metadata,
        DeviceId = secondTargetDeviceId
    }
};

// Start the device metadata update.
UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest
{
    Updates = updates
};
var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute();

// Assume the metadata update started, so get the Operation for the update.
Operation operation = service.Operations.Get(response.Name).Execute();

Python

# Build out the request body to apply the same order number to a customer's
# purchase of 2 devices.
updates = [{'deviceMetadata':metadata,'deviceId':first_target_device_id},
    {'deviceMetadata':metadata,'deviceId':second_target_device_id}]

# Start the device metadata update.
response = service.partners().devices().updateMetadataAsync(
    partnerId=PARTNER_ID, body={'updates':updates}).execute()

# Assume the metadata update started, so get the Operation for the update.
operation = service.operations().get(name=response['name']).execute()

Para saber si una operación finalizó, busca un campo done con un valor de true. Si falta done o false, la operación aún está en marcha.

Respuestas

Después de que finaliza una operación, la API la actualiza con el resultado, incluso si todas o ninguna de las tareas individuales se realizan correctamente. El campo response es un objeto DevicesLongRunningOperationResponse que detalla el procesamiento de cada dispositivo en la operación.

Inspecciona el campo successCount para averiguar de manera eficiente si alguna tarea falló. evitar iterar a través de grandes listas de resultados. El campo perDeviceStatus de DevicesLongRunningOperationResponse es una lista de OperationPerDevice instancias que detallan cada dispositivo en la operación. El orden de la lista coincide con las tareas de la solicitud original.

Cada tarea OperationPerDevice contiene un campo result y un resumen de recordatorio de la solicitud que recibió el servidor. Verifica si la tarea se realizó correctamente o falló con el campo result.

En el siguiente fragmento JSON, se muestra parte de una respuesta típica de una operación después de una llamada a updateMetadataAsync:

"response": {
  "perDeviceStatus": [
    {
      "result": {
        "deviceId": "12345678901234567",
        "status": "SINGLE_DEVICE_STATUS_SUCCESS"
      },
      "updateMetadata": {
        "deviceId": "12345678901234567",
        "deviceMetadata": {
          "entries": {
            "phonenumber": "+1 (800) 555-0100"
          }
        }
      }
    }
  ],
  "successCount": 1
}

Realice un seguimiento del progreso

Si tu app necesita hacer un seguimiento del progreso, debes volver a recuperar la operación de forma periódica. El campo metadata contiene una instancia de DevicesLongRunningOperationMetadata para ayudar a tu app a verificar el progreso más reciente de una operación en ejecución. Usa los campos de DevicesLongRunningOperationMetadata que se enumeran a continuación para realizar un seguimiento del progreso de la operación:

Campo Uso habitual
processingStatus Cambios de BATCH_PROCESS_PENDING a BATCH_PROCESS_IN_PROGRESS y, luego, a BATCH_PROCESS_PROCESSED a medida que avanza la operación.
progress El porcentaje de actualizaciones procesadas. Tu app puede usar esto para estimar una hora de finalización. Debido a que progress puede ser 100 mientras la operación está terminando, revisa el campo done de una operación para saber si haya terminado y tenga un resultado.
devicesCount Muestra la cantidad de actualizaciones en la operación. Es posible que esto sea diferente de la cantidad de actualizaciones en tu solicitud si la API no puede analizar algunas de ellas.

En el siguiente ejemplo simplificado, se muestra cómo una app podría usar los metadatos de progreso para establecer intervalos de sondeo. En tu app, es posible que necesites un ejecutor de tareas más sofisticado para la sondeo. También deberás agregar el manejo de errores.

Java

// Milliseconds between polling the API.
private static long MIN_INTERVAL = 2000;
private static long MAX_INTERVAL = 10000;

// ...
// Start the device metadata update.
Operation response = service
    .partners()
    .devices()
    .updateMetadataAsync(PARTNER_ID, body)
    .execute();
String operationName = response.getName();

// Start polling for completion.
long startTime = new Date().getTime();
while (true) {

  // Get the latest update on the operation's progress using the API.
  Operation operation = service.operations().get(operationName).execute();

  if (operation.get("done") != null && operation.getDone()) {
    // The operation is finished. Print the status.
    System.out.format("Operation complete: %s of %s successful device updates\n",
        operation.getResponse().get("successCount"),
        operation.getMetadata().get("devicesCount"));
    break;

  } else {
    // Estimate how long the operation *should* take - within min and max value.
    BigDecimal opProgress = (BigDecimal) operation.getMetadata().get("progress");
    double progress = opProgress.longValue();
    long interval = MAX_INTERVAL;
    if (progress > 0) {
      interval = (long) ((new Date().getTime() - startTime) *
          ((100.0 - progress) / progress));
    }
    interval = Math.max(MIN_INTERVAL, Math.min(interval, MAX_INTERVAL));

    // Sleep until the operation should be complete.
    Thread.sleep(interval);
  }
}

.NET

// Milliseconds between polling the API.
private static double MinInterval = 2000;
private static double MaxInterval = 10000;

// ...
// Start the device metadata update.
var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute();
var operationName = response.Name;

// Start polling for completion.
var startTime = DateTime.Now;
while (true)
{

    // Get the latest update on the operation's progress using the API.
    Operation operation = service.Operations.Get(operationName).Execute();

    if (operation.Done == true)
    {
        // The operation is finished. Print the status.
        Console.WriteLine("Operation complete: {0} of {1} successful device updates",
                          operation.Response["successCount"],
                          operation.Metadata["devicesCount"]);
        break;
    }
    else
    {
        // Estimate how long the operation *should* take - within min and max value.
        double progress = (double)(long)operation.Metadata["progress"];
        double interval = MaxInterval;
        if (progress > 0)
        {
            interval = DateTime.Now.Subtract(startTime).TotalMilliseconds *
                                     ((100.0 - progress) / progress);
        }
        interval = Math.Max(MinInterval, Math.Min(interval, MaxInterval));

        // Sleep until the operation should be complete.
        System.Threading.Thread.Sleep((int)interval);
    }
}

Python

# Seconds between polling the API.
MIN_INTERVAL = 2;
MAX_INTERVAL = 10;

# ...
# Start the device metadata update
response = service.partners().devices().updateMetadataAsync(
  partnerId=PARTNER_ID, body={'updates':updates}).execute()

op_name = response['name']
start_time = time.time()

# Start polling for completion
while True:
  # Get the latest update on the operation's progress using the API
  op = service.operations().get(name=op_name).execute()

  if 'done' in op and op['done']:
    # The operation is finished. Print the status.
    print('Operation complete: {0} of {1} successful device updates'.format(
      op['response']['successCount'], op['metadata']['devicesCount']
    ))
    break
  else:
    # Estimate how long the operation *should* take - within min and max.
    progress = op['metadata']['progress']
    interval = MIN_INTERVAL
    if progress > 0:
      interval = (time.time() - start_time) * ((100.0 - progress) / progress)
    interval = max(MIN_INTERVAL, min(interval, MAX_INTERVAL))

    # Sleep until the operation should be complete.
    time.sleep(interval)

Elige un enfoque de sondeo que sea adecuado para los usuarios de tu app. Algunos usuarios de la app podría beneficiarse de las actualizaciones de progreso periódicas si están esperando que se complete un proceso que se completó.

Resultados paginados

Es posible que el método de la API de partners.devices.findByOwner muestre listas muy grandes de dispositivos. Para reducir el tamaño de la respuesta, este y otros métodos de la API (como partners.devices.findByIdentifier) admiten resultados paginados. Con los resultados paginados, tu aplicación puede solicitar y procesar de forma iterativa listas grandes, una página a la vez.

Después de llamar al método de la API, verifica si la respuesta incluye un valor para nextPageToken. Si nextPageToken no es null, tu app puede usarlo para recuperar otra página de dispositivos llamando nuevamente al método. Debes establecer un límite superior para la cantidad de dispositivos en el parámetro limit Si nextPageToken es null, tu app solicitó la última página.

En el siguiente método de ejemplo, se muestra cómo tu app podría imprimir una lista de dispositivos, una página a la vez:

Java

private static long MAX_PAGE_SIZE = 10;

// ...
/**
 * Demonstrates how to loop through paginated lists of devices.
 * @param pageToken       The token specifying which result page to return.
 * @throws IOException    If the zero-touch API call fails.
 */
private void printDevices(String pageToken) throws IOException {

  // Create the request body to find the customer's devices.
  FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest();
  body.setLimit(MAX_PAGE_SIZE);
  body.setSectionType("SECTION_TYPE_ZERO_TOUCH");
  body.setCustomerId(Collections.singletonList(targetCustomerId));

  // Call the API to get a page of Devices. Send a page token from the method
  // argument (might be None). If the page token is None, the API returns the first page.
  FindDevicesByOwnerResponse response =
      service.partners().devices().findByOwner(PARTNER_ID, body).execute();
  if (response.getDevices() == null) {
    return;
  }

  // Print the devices included in this page of results.
  for (Device device: response.getDevices()) {
    System.out.format("Device %s\n", device.getName());
  }
  System.out.println("---");

  // Check to see if another page of devices is available. If yes,
  // fetch and print the devices.
  if (response.getNextPageToken() != null) {
    this.printDevices(response.getNextPageToken());
  }
}

// ...
// Pass null to start printing the first page of devices.
printDevices(null);

.NET

private static int MaxPageSize = 10;

// ...
/// <summary>Demonstrates how to loop through paginated lists of devices.</summary>
/// <param name="pageToken">The token specifying which result page to return.</param>
private void PrintDevices(string pageToken)
{
    // Create the request body to find the customer's devices.
    FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest
    {
        PageToken = pageToken,
        Limit = MaxPageSize,
        SectionType = "SECTION_TYPE_ZERO_TOUCH",
        CustomerId = new List<long?>
        {
            targetCustomerId
        }
    };

    // Call the API to get a page of Devices. Send a page token from the method
    // argument (might be None). If the page token is None, the API returns the first page.
    var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute();
    if (response.Devices == null)
    {
        return;
    }

    // Print the devices included in this page of results.
    foreach (Device device in response.Devices)
    {
        Console.WriteLine("Device: {0}", device.Name);
    }
    Console.WriteLine("---");

    // Check to see if another page of devices is available. If yes,
    // fetch and print the devices.
    if (response.NextPageToken != null)
    {
        this.PrintDevices(response.NextPageToken);
    }
}

// ...
// Pass null to start printing the first page of devices.
PrintDevices(null);

Python

MAX_PAGE_SIZE = 10;

# ...
def print_devices(page_token):
  """Demonstrates how to loop through paginated lists of devices.

  Args:
    page_token: The token specifying which result page to return.
  """

   # Create the body to find the customer's devices.
  request_body = {'limit':MAX_PAGE_SIZE, \
    'pageToken':page_token, \
    'customerId':[target_customer_id], \
    'sectionType':'SECTION_TYPE_ZERO_TOUCH'}

  # Call the API to get a page of Devices. Send a page token from the method
  # argument (might be None). If the page token is None,
  # the API returns the first page.
  response = service.partners().devices().findByOwner(partnerId=PARTNER_ID,
    body=request_body).execute()

  # Print the devices included in this page of results.
  for device in response['devices']:
    print 'Device: {0}'.format(device['name'])
  print '---'

  # Check to see if another page of devices is available. If yes,
  # fetch and print the devices.
  if 'nextPageToken' in response:
    print_devices(response['nextPageToken'])

# ...
# Pass None to start printing the first page of devices.
print_devices(None);

Próximos pasos

Ahora que sabes cómo funciona la API, prueba los ejemplos con una guía de inicio rápido para Java, .NET o Python. Puedes usar un colab para ver de llamadas a la API y prueba llamar a la API tú mismo.