כיצד זה עובד

מבוא

ה-API של הרשמה דרך הארגון עוזר למפיצי מכשירים לבצע אוטומציה של השילוב שלהם. כלי המכירות של הארגון יכולים לכלול הרשמה ללא מגע, וכך לשפר את הפרודוקטיביות של המשתמשים ושל הלקוחות. תוכלו להשתמש ב-API כדי לעזור למשתמשים:

  • הקצאת מכשירים שנרכשו לחשבון של לקוח להרשמה דרך הארגון.
  • יוצרים חשבון להרשמה דרך הארגון ללא מגע עבור הלקוח.
  • מצרפים למכשירים את המטא-נתונים של הארגון ומספרי הטלפון.
  • יצירת דוחות על המכשירים שהוקצו ללקוחות שלך.

המסמך הזה מציג את ה-API ומסביר על הדפוסים. אם רוצים לבדוק את ה-API בעצמכם, נסו את המדריך למתחילים Java, .NET, או Python.

מושגי API

לקוחות ומכשירים הם המשאבים המרכזיים שבהם אתם משתמשים ב-API. כדי ליצור לקוחות, התקשרו אל create. יש לך אפשרות ליצור מכשירים באמצעות methods של Claim API (ראו בהמשך). הארגון שלך יכול גם ליצור לקוחות ומכשירים באמצעות פורטל ההרשמה דרך הארגון.

הקשר בין המכשיר לבין משאבי הלקוח

לקוח
חברות שהארגון שלך מוכר מכשירים להן. ללקוחות יש name וID. צריך להשתמש בלקוח כשרוצים לתבוע בעלות על מכשירים או לאתר אותם. למידע נוסף, אפשר לעיין במאמר Customer.
מכשיר
מכשיר Android או ChromeOS עם אפשרות הרשמה דרך הארגון מוכרים ללקוח. למכשירים יש מזהי חומרה, מטא-נתונים ולקוח תלונות. מכשירים הם מרכזיים ב-API, כך שאתם משתמשים בהם כמעט בכל שיטות. מידע נוסף זמין בכתובת Device.
DeviceIdentifier
עטיפה של מזהי חומרה, כמו IMEI או MEID, לזיהוי מכשיר שיוצר. משתמשים ב-DeviceIdentifier כדי לטרגט את המכשיר שרוצים לאתר, לעדכן או לטעון בעלות עליו. מידע נוסף זמין במאמר מזהים.
DeviceMetadata
שמירת צמדי מפתח-ערך של מטא-נתונים במכשיר. כדאי להשתמש DeviceMetadata לאחסון המטא-נתונים של הארגון. למידע נוסף, אפשר לעיין במאמר מטא-נתונים של מכשיר.

כדי להציג רשימה של כל השיטות והמשאבים של ה-API שהאפליקציה יכולה להשתמש בהם, אפשר לעיין ב הפניית API.

יצירת לקוחות

למכשירי Android, המפיץ הוא האחראי על יצירת הלקוח בשם הלקוח. הלקוח ישתמש בחשבון הזה כדי לגשת לפורטל ההרשמה דרך הארגון ולהגדיר את הגדרות הקצאת המשאבים למכשירים שלו. לא צריך לעשות את זה במכשירי ChromeOS שכבר יש להם חשבון Google חשבון Workspace שבו הם ישתמשו כדי לקבוע את הגדרות ניהול ההקצאות.

אפשר לקרוא ל-method‏ create ב-API כדי ליצור חשבונות לקוח להרשמה ללא מגע. מכיוון ששם החברה מופיע בפורטל ההרשמה ללא מגע של הלקוחות, המשתמש באפליקציה צריך לוודא שהוא נכון. לא ניתן לערוך שם של לקוח אחרי שיוצרים את לכל לקוח.

עליך לכלול לפחות כתובת אימייל אחת של החברה, שמשויכת אל חשבון Google, להיות הבעלים. אי אפשר להשתמש בחשבונות Gmail אישיים עם ה-API. אם הלקוח צריך עזרה בשיוך החשבון, צריך לשלוח את הוראות מ- שיוך של חשבון Google.

אחרי שיוצרים לקוח באמצעות קריאה ל-API, הלקוח מנהל את הגישה של העובדים שלו לפורטל – אי אפשר לערוך את המשתמשים של הלקוחות באמצעות ה-API. קטע הקוד הבא מראה איך אפשר ליצור לקוח:

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

מידע נוסף על תפקידי הבעלים והאדמין של עובדים של הלקוח זמין במאמר משתמשים בפורטל.

תביעת בעלות על מכשירים עבור לקוחות

אחרי שהלקוחות שלך ירכשו מכשירים, הם ירצו להגדיר ניהול תצורה הגדרות המכשירים האלה בחשבון שלהם. תביעת בעלות על מכשיר מוסיפה את המכשיר להרשמה דרך הארגון, ומאפשר ללקוח להגדיר הגדרות של ניהול הקצאות.

ברשומה של הקצאת ההרשאות במכשיר יש קטע להרשמה דרך הארגון. כדי להקצות את המכשיר, צריך למלא את הקטע 'הרשמה דרך הארגון' ברשומה של הלקוח. קוראים לpartners.devices.claim או partners.devices.claimAsync עם כארגומנט. תמיד צריך לספק את הערך SECTION_TYPE_ZERO_TOUCH כערך של sectionType.

כדי לטעון בעלות על מכשיר של לקוח אחר, צריך לבטל את הבעלות על המכשיר של הלקוח הקודם (מידע נוסף מופיע בהמשך). שיטות התלונה מאמתים את השדות ב-DeviceIdentifier, כולל IMEI או MEID, או המספר הסידורי, שם היצרן והדגם שלו, וכן מזהה מכשיר מאומת למכשירי ChromeOS, בזמן יצירת מכשיר חדש.

קטע הקוד הבא מראה איך להצהיר על מכשיר:

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

ביטול הבעלות על מכשירים

הארגון שלך יכול לבטל את הבעלות על מכשיר של הלקוח. הסרת בעלות על מכשיר ההרשמה דרך הארגון מסירה אותו מהרשמה דרך הארגון. מפיץ עשוי לבטל את תביעת הבעלות שלו על מכשיר הוא רוצה להעביר לחשבון אחר, להחזיר אותו או שנתבעה עליו בעלות בטעות. כדי לבטל את הבעלות של לקוח על מכשיר, צריך להפעיל את השיטה partners.devices.unclaim או partners.devices.unclaimAsync.

ספקים

ניתן להשתמש בספקים כדי לייצג שותפים שהם מפיצים ברשת של סוכנויות הרכב שלכם, מפעילים ברשת מפיצים גלובלית, או כל ארגון שמוכר מכשירים בשמך. ספקים עוזרים לך להפריד בין המשתמשים, הלקוחות מכשירים:

  • ספקים שתיצרו לא יוכלו לראות את החשבון שלכם להרשמה ללא מגע או את החשבונות של ספקים אחרים.
  • יש לך אפשרות להציג את הלקוחות והמכשירים של הספקים שלך, ואפשר לבטל את הרישום במכשירים של הספקים. עם זאת, לא ניתן להקצות מכשירים לספקים שלך .

אפשר להשתמש בפורטל כדי ליצור ספקים ארגון – לא ניתן להשתמש ב-API. כדי ליצור ספק חדש, תפקיד החשבון שלכם צריך להיות בעלים. אם יש בארגון ספקים, אפשר להתקשר אל partners.vendors.list כדי לרשום את ספקים וגם partners.vendors.customers.list כדי למשוך לקוחות של הספק. הדוגמה הבאה משתמשת בשתי השיטות האלה להדפיס דוח שבו מוצג הסטטוס של התנאים וההגבלות של הספקים לקוחות:

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

אם יש לך אוסף של מכשירים, יכול להיות שיהיה עליך לדעת מאיזה מפיץ או מאיזה מפיץ הספק תבע בעלות על המכשיר. כדי לקבל את מזהה המפיץ המספרי, צריך לבדוק את הערך של השדה resellerId ברשומת התלונות של המכשיר.

הארגון יכול לבטל את הבעלות על מכשיר שהוצהר עליו על ידי ספק. בקריאות API אחרות שמבצעות שינויים במכשירים, צריך לוודא שהארגון שלכם הגיש תלונה על הבעלות על המכשיר לפני שמפעילים את שיטת ה-API. הדוגמה הבאה מראה איך עושים את זה:

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

פעולות ממושכות באצווה

ה-API כולל גרסאות אסינכרוניות של ה-methods של המכשיר. השיטות האלה מאפשרות עיבוד ברצף של מכשירים רבים, תוך כדי method מעבדות מכשיר אחד לכל בקשת API. לשמות השיטות האסינכרוניות יש סיומת Async, לדוגמה claimAsync.

שיטות API אסינכררוניות מחזירות תוצאה לפני שהעיבוד מסתיים. שיטות אסינכרניות עוזרות גם לאפליקציה (או לכלי) להישאר תגובה למשתמשים בזמן שהם ממתינים להשלמת פעולה ממושכת. האפליקציה צריכה לבדוק את סטטוס הפעולה מדי פעם.

תפעול

צריך להשתמש ב-Operation כדי לעקוב אחר פעולה ממושכת באצווה. א' קריאה מוצלחת לשיטה אסינכרונית מחזירה הפניה לפעולה בתשובה. קטע הקוד של ה-JSON שבהמשך מציג תגובה אופיינית אחרי קריאה ל-updateMetadataAsync:

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

כל פעולה מכילה רשימה של משימות נפרדות. שיחת טלפון operations.get כדי לקבל מידע על הסטטוס, בתוצאות של המשימות במסגרת הפעולה. קטע הקוד הבא מראה איך עשויות לעשות זאת. באפליקציה שלכם תצטרכו לטפל בכל שגיאה.

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

כדי לבדוק אם פעולה הסתיימה, בודקים אם יש בשדה 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 לא יכול לנתח חלק מהעדכונים.

הדוגמה הפשוטה הבאה ממחישה איך האפליקציה יכולה להשתמש במטא-נתונים של ההתקדמות כדי להגדיר מרווחי זמן לקלפי. יכול להיות שתצטרכו להשתמש באפליקציה במנהל משימות מתוחכם יותר לצורך סקרים. בנוסף, תצטרכו להוסיף טיפול בשגיאות.

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)

עליכם לבחור גישת סקרים שמתאימה למשתמשי האפליקציה שלכם. משתמשים מסוימים באפליקציה עשויים להפיק תועלת מעדכוני התקדמות שוטפים אם הם ממתינים לסיום תהליך כלשהו.

תוצאות שמחולקות לדפים

ה-method partners.devices.findByOwner של ה-API עלול להחזיר רשימות גדולות מאוד של מכשירים. כדי להקטין את גודל התגובה, הפקודות הבאות וגם שיטות API אחרות (כמו partners.devices.findByIdentifier) שתומכות בתוצאות בדפים. על סמך תוצאות עם דפים, האפליקציה יכולה לבצע באופן איטרטיבי מבקשים ומעבדים רשימות גדולות של דף אחד בכל פעם.

אחרי שמפעילים את שיטת ה-API, בודקים אם התגובה כוללת ערך בשדה nextPageToken. אם nextPageToken לא null, האפליקציה שלך יכולה להשתמש בו כדי לאחזר דף אחר של מכשירים על ידי התקשרות את השיטה שוב. צריך להגדיר מגבלת עליון למספר המכשירים בפרמטר limit. אם הערך של nextPageToken הוא null, האפליקציה ביקשה את הדף האחרון.

בדוגמה הבאה מוסבר איך האפליקציה יכולה להדפיס רשימה של מכשירים, דף אחרי דף:

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

השלבים הבאים

עכשיו, אחרי שהבנתם איך ה-API פועל, תוכלו לנסות את הדוגמאות במדריך למתחילים בשפות Java,‏ ‎.NET ו-Python. אפשר להשתמש colab להצגה דוגמאות לקריאות ל-API ותנסו להפעיל את ה-API בעצמכם.