작동 방식

소개

제로터치 등록 API는 기기 리셀러가 통합을 자동화하는 데 도움이 됩니다. 조직의 영업 도구에 제로터치 등록을 내장하여 사용자와 고객의 생산성을 높일 수 있습니다. API를 사용하여 사용자를 지원하세요.

  • 구매한 기기를 고객의 제로터치 등록 계정에 할당합니다.
  • 고객의 제로터치 등록 계정을 만듭니다.
  • 조직의 전화 및 주문 메타데이터를 기기에 연결합니다.
  • 고객에게 할당된 기기에 대한 보고서를 만듭니다.

이 문서에서는 API를 소개하고 패턴을 설명합니다. 원하는 경우 API를 직접 살펴보고 자바 .NET 또는 Python.

API 개념

고객과 기기는 API에서 사용하는 핵심 리소스입니다. 만들기 create를 호출합니다. 기기를 만들 수 있습니다. 소유권 주장 API 메서드 사용 (아래 참조) 또한 조직에서는 제로터치 등록 포털을 사용하여 고객과 기기를 생성합니다.

기기 및 고객 리소스 관계

고객
조직에서 기기를 판매하는 회사입니다. 고객에게 name이(가) 있음 및 ID가 포함됩니다. 고객의 기기를 소유권 주장하거나 찾으려면 고객을 사용하세요. 받는사람 자세한 내용은 Customer를 참고하세요.
기기
조직에서 고객에게 판매하는 제로터치 등록이 가능한 Android 또는 ChromeOS 기기입니다. 기기에는 하드웨어 ID, 메타데이터, 고객 소유권 주장이 있습니다. 기기는 API의 중심이므로 거의 모든 메서드를 참조하세요. 자세한 내용은 Device을 참조하세요.
DeviceIdentifier
IMEI 또는 MEID와 같은 하드웨어 ID를 캡슐화하여 제조된 기기를 식별합니다. DeviceIdentifier를 사용하여 기기 타겟팅 소유권을 주장할 수 있습니다. 자세한 내용은 식별자.
DeviceMetadata
기기 메타데이터의 키-값 쌍을 저장합니다. DeviceMetadata를 사용하여 조직의 메타데이터를 저장합니다. 자세한 내용은 기기 메타데이터를 참고하세요.

앱에서 사용할 수 있는 모든 API 메서드와 리소스를 나열하려면 API 참조를 참고하세요.

고객 만들기

Android 기기의 경우 리셀러가 고객을 대신하여 고객 계정을 만들어야 합니다. 고객은 이 계정을 사용하여 제로터치 포털에 액세스하여 기기의 프로비저닝 설정을 구성합니다. 프로비저닝 설정을 구성하는 데 사용할 Google Workspace 계정이 이미 있는 ChromeOS 기기에는 이 작업이 필요하지 않습니다.

create API 메서드를 호출하여 제로터치 등록을 사용할 수 있습니다. 고객이 제로터치 등록 포털에서 회사 이름을 보게 되므로 앱 사용자는 회사 이름이 올바른지 확인해야 합니다. 고객을 만든 후에는 고객 이름을 수정할 수 없습니다.

소유자가 되려면 Google 계정과 연결된 회사 이메일 주소를 하나 이상 포함해야 합니다. API에 액세스할 수 있습니다. 고객이 계정 연결에 도움이 필요한 경우 의 지침 Google 계정 연결

API를 호출하여 고객을 만든 후에는 고객이 직원의 포털 액세스 권한을 관리합니다. API를 사용하여 고객의 사용자를 수정할 수는 없습니다. 아래 스니펫은 고객을 만드는 방법을 보여줍니다.

자바

// 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()

고객 직원의 소유자 및 관리자 역할에 대해 자세히 알아보려면 포털 사용자를 읽어보세요.

고객의 기기 소유권 주장

고객이 기기를 구매한 후에는 계정에서 이러한 기기의 프로비저닝 설정을 구성해야 합니다. 기기를 소유권 주장하면 기기가 제로터치 등록에 추가되고 고객에게 프로비저닝 설정을 구성할 수 있는 권한이 부여됩니다.

기기의 프로비저닝 레코드에는 제로터치 등록 섹션이 있습니다. 나 레코드의 제로터치 등록 섹션을 요청하여 있습니다. partners.devices.claim를 호출하거나 partners.devices.claimAsync 메서드 있습니다. 항상 SECTION_TYPE_ZERO_TOUCHsectionType의 값으로 제공합니다.

먼저 고객 기기에 대한 소유권 주장을 취소 (아래 참조)해야 합니다. 다른 고객에 대해 동일한 기기의 소유권을 주장할 수 없습니다. 소유권 주장 방법 DeviceIdentifier 필드를 확인합니다. IMEI 또는 MEID, 또는 일련번호를 포함하여 제조업체 이름과 모델, 새 기기를 만들 때 ChromeOS 기기의 증명된 기기 ID입니다.

아래 스니펫은 기기를 소유권 주장하는 방법을 보여줍니다.

자바

// 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()

기기 소유권 주장 취소

조직에서는 고객의 기기 소유권 주장을 취소할 수 있습니다. 기기의 소유권 주장을 취소하면 기기가 제로터치 등록에서 삭제됩니다. 리셀러는 다른 계정으로 이전하거나 반품하려는 기기 또는 실수로 소유권 주장이 제기된 기기의 소유권 주장을 취소할 수 있습니다. partners.devices.unclaim 메서드를 호출합니다. 소유권 주장을 취소하려면 partners.devices.unclaimAsync 받을 수 없습니다.

공급업체

공급업체를 통해 대리점 네트워크, 지역 업체에서 리셀러 파트너를 대표할 수 있습니다. 또는 글로벌 리셀러 네트워크 내의 운영자 또는 사용자를 대신하여 이 기기를 관리합니다. 공급업체는 사용자, 고객, 기기:

  • 내가 만든 공급업체는 내 제로터치 등록 계정이나 다른 공급업체의 계정을 볼 수 없습니다.
  • 공급업체의 고객과 기기를 확인하고 등록을 취소할 수 있습니다. 제공할 수 있습니다. 하지만 기기를 공급업체에 할당할 수는 없습니다. 고객을 유치하세요
를 통해 개인정보처리방침을 정의할 수 있습니다.

포털을 사용하여 조직의 공급업체를 만듭니다. API는 사용할 수 없습니다. 새 공급업체를 만들려면 계정 역할이 소유자여야 합니다. 조직에 공급업체가 있는 경우 partners.vendors.list를 호출하여 공급업체 및 partners.vendors.customers.list 협력업체의 고객을 확보할 수 있습니다. 다음 예에서는 이러한 두 가지 메서드를 모두 사용하여 공급업체 고객의 서비스 약관 상태를 보여주는 보고서를 출력합니다.

자바

// 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'])

여러 기기를 보유하고 있는 경우 어떤 리셀러 또는 리셀러가 공급업체가 기기를 요구했습니다. 숫자로 된 리셀러 ID를 가져오려면 기기 클레임 레코드의 resellerId 필드

조직에서는 공급업체가 소유권을 주장한 기기의 소유권을 주장할 수 있습니다. 다른 API 호출의 경우 기기를 수정하려면 조직에서 해당 기기의 소유권을 주장했는지 확인해야 합니다. API 메서드를 호출하기 전에 확인할 수 있습니다. 다음 예는 이를 수행하는 방법을 보여줍니다.

자바

// 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

장기 실행 일괄 작업

API에는 비동기 버전의 기기 메서드가 포함됩니다. 이러한 메서드를 사용하면 여러 기기를 일괄 처리할 수 있지만 동기식 메서드는 API 요청마다 하나의 기기를 처리합니다. 비동기 메서드 이름에는 Async 접미사가 붙습니다(예: claimAsync).

비동기 API 메서드는 처리가 완료되기 전에 결과를 반환합니다. 또한 비동기식 메서드는 앱 (또는 도구)이 사용자가 장기 실행 작업이 완료되기를 기다리는 동안 앱은 다음과 같아야 합니다. 주기적으로 작업 상태를 확인합니다

운영

Operation를 사용하여 장기 실행 일괄 작업을 추적합니다. 비동기 메서드 호출에 성공하면 응답에서 작업 참조가 반환됩니다. 아래 JSON 스니펫은 updateMetadataAsync를 호출한 후의 일반적인 응답을 보여줍니다.

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

각 작업에는 개별 태스크 목록이 포함됩니다. 전화걸기 operations.get: 상태에 대한 정보를 확인하고 결과를 반환합니다. 아래 스니펫은 이를 수행하는 방법을 보여줍니다. 자체 앱에서는 모든 오류를 처리해야 합니다.

자바

// 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()

작업이 완료되었는지 확인하려면 작업에서 done 필드를 확인합니다. 값을 true로 바꿉니다. done가 누락되거나 false인 경우 작업은 여전히 유지됩니다. 있습니다

대답

작업이 완료되면 API는 결과로 작업을 업데이트하며 개별 태스크가 모두 성공하거나 성공하지 않는 경우 response 필드는 작업의 각 기기 처리를 자세히 설명하는 DevicesLongRunningOperationResponse 객체입니다.

successCount 필드를 검사하여 실패한 작업이 있는지 효율적으로 확인하고 대규모 결과 목록을 반복하지 않습니다. perDeviceStatus 필드 DevicesLongRunningOperationResponse은(는) 각 기기를 자세히 설명하는 OperationPerDevice 인스턴스 작업을 수행합니다. 목록 순서는 원래 요청의 작업과 일치합니다.

OperationPerDevice 작업에는 result 필드와 리마인더 요약이 포함되어 있습니다. 서버로부터 수신된 요청의 응답 시간을 나타냅니다. result 필드를 사용하여 작업이 성공했는지 또는 실패했는지 확인합니다.

아래 JSON 스니펫은 작업 완료 후의 작업에서 일반적인 응답의 일부를 보여줍니다. updateMetadataAsync 호출:

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

진행률 추적

앱에서 진행 상황을 추적해야 하는 경우 연산으로 해석됩니다. metadata 필드에는 앱이 실행 중인 작업의 최신 진행 상황을 확인하는 데 도움이 되는 DevicesLongRunningOperationMetadata 인스턴스가 포함되어 있습니다. 사용 아래 나열된 DevicesLongRunningOperationMetadata의 필드 테이블을 사용하여 작업 진행 상황을 추적할 수 있습니다.

필드 일반적인 용도
processingStatus BATCH_PROCESS_PENDING에서 (으)로의 변경사항 BATCH_PROCESS_IN_PROGRESS 다음 BATCH_PROCESS_PROCESSED입니다.
progress 처리된 업데이트의 비율입니다. 앱은 이를 사용하여 완료 시간을 추정할 수 있습니다. progress 값은 작업이 완료되는 동안 100일 수 있습니다. 작업의 done 필드를 확인하여 결과가 나타납니다.
devicesCount 작업의 업데이트 수를 표시합니다. API가 일부 업데이트를 파싱할 수 없는 경우 이 값은 요청의 업데이트 수와 다를 수 있습니다.

아래의 간소화된 예는 앱에서 진행률 메타데이터를 사용하여 폴링 간격을 설정하는 방법을 보여줍니다. 앱에서는 보다 정교한 작업이 필요할 수 있습니다. 있습니다. 오류 처리도 추가해야 합니다.

자바

// 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)

앱 사용자에게 적합한 폴링 접근 방식을 선택합니다. 일부 앱 사용자는 프로세스가 완료될 때까지 기다리는 경우 정기적인 진행률 업데이트의 이점을 누릴 수 있습니다.

페이지로 나눈 결과

partners.devices.findByOwner API 메서드는 매우 큰 기기 목록을 반환할 수 있습니다. 응답 크기를 줄이기 위해 이 및 기타 API 메서드 (예: partners.devices.findByIdentifier) 페이징된 결과를 지원합니다. 페이징된 결과를 사용하면 애플리케이션이 반복적으로 한 번에 한 페이지씩 큰 목록을 요청하고 처리할 수 있습니다.

API 메서드를 호출한 후 응답에 nextPageToken 값이 포함되어 있는지 확인합니다. nextPageToken인 경우 null가 아니면 앱에서 다음을 호출하여 기기의 다른 페이지를 가져올 수 있습니다. 다시 호출할 수 있습니다. limit 매개변수에서 기기 수의 상한값을 설정해야 합니다. nextPageTokennull이면 앱에서 마지막 페이지를 요청한 것입니다.

아래의 메서드 예는 앱에서 기기 목록을 한 번에 한 페이지씩 출력하는 방법을 보여줍니다.

자바

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);

다음 단계

이제 API가 어떻게 작동하는지 알았으니 빠른 시작과 함께 자바 .NET 또는 Python. colab에서 보기 API 호출 예시를 살펴보고 API를 직접 호출해 보세요.