People.People.searchDirectoryPeople() 查询多个电子邮件地址

People.People.searchDirectoryPeople() query with multiple email addresses

在 Google Apps 脚本中,我需要查询许多同事的 Google 用户个人资料图片 URL。

这是一个针对单个用户的工作示例:

searchDirectoryPeople('jimmy.neutron@example.com');

function searchDirectoryPeople(query) {
  const options = {
    query: query,
    readMask: 'photos,emailAddresses',
    sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE']
  }
  const people = People.People.searchDirectoryPeople(options);
  if(people && people.people) {
    Logger.log('size: '+people.people.length);
    people.people.forEach(person => {
      let url = '';
      let email = '';
      if(person) {
        if(person.photos && person.photos[0]) {
          url = person.photos[0].url;
        }
        if(person.emailAddresses && person.emailAddresses.length) {
          person.emailAddresses.forEach(item => {
            if(item.metadata && item.metadata.sourcePrimary) {
              email = item.value;
            }
          });
        }
      }
      Logger.log('email: '+email+': '+url);
      //Logger.log('person: %s', JSON.stringify(person, null, 2));
    });
  } else {
    Logger.log('no people.people');
  }
}

我发现我可以查询所有 jimmy 人:

searchDirectoryPeople('jimmy');

我有所有员工的电子邮件地址。我可以一个一个地遍历 1000 多名员工的大名单,但这不切实际。我正在寻找一种查询多个电子邮件地址的方法。 https://developers.google.com/people/api/rest/v1/people/searchDirectoryPeople 中的文档对于查询来说是含糊不清的。我尝试了很多类似的方法,但没有任何效果:

我正在寻找以电子邮件地址列表作为输入的查询,例如:

[ 'jimmy.neutron@example.com', 'carl.wheezer@example.com', 'cindy.vortex@example.com' ]

是否可以在 People.People.searchDirectoryPeople() 中进行 OR 查询?


更新 2022-05-31

我尝试遍历所有电子邮件并 运行 进入配额限制或脚本运行时限制。

@Lorena Gomez 的回答是正确的:首先使用 People.People.listDirectoryPeople() 获取所有电子邮件地址的资源名称,然后使用 People.People.getBatchGet() 通过资源名称获取个人资料图片 URL .前者每次呼叫限制为 1000 名员工,后者限制为 200 名。这适用于我们有 1k+ 电子邮件地址作为输入的情况,listDirectoryPeople().

返回 20k+ 员工

工作代码:

const emails = [
  'jimmy.neutron@example.com',
  'carl.wheezer@example.com',
  'cindy.vortex@example.com'
];
let emailToUrl = getGoogleProfilePictureUrls(emails);
Logger.log('emailToUrl: %s', JSON.stringify(emailToUrl, null, 2));
// expected output:
// emailToUrl: {
//  "jimmy.neutron@example.com": "https://lh3.googleusercontent.com/a-/xxxx=s100",
//  "carl.wheezer@example.com": "https://lh3.googleusercontent.com/a-/xxxx=s100",
//  "cindy.vortex@example.com": "https://lh3.googleusercontent.com/a-/xxxx=s100"
// }

function getGoogleProfilePictureUrls(emails) {
  let options = {
    readMask: 'emailAddresses',
    sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE'],
    pageSize: 1000
  }
  let run = 1;
  let resourceNameToEmails = {};
  let result = {};
  while(run === 1 || result.nextPageToken) {
    if(result.nextPageToken) {
      options.pageToken = result.nextPageToken;
    }
    result = People.People.listDirectoryPeople(options);
    Logger.log('request #' + (run++) + ', got '+result.people.length+' resource names');
    result.people.forEach(person => {
      if(person.emailAddresses) {
        person.emailAddresses.forEach(obj => {
          if(obj.metadata && obj.metadata.sourcePrimary) {
            let email = obj.value
            if(emails.indexOf(email) >= 0) {
              resourceNameToEmails[person.resourceName] = email;
            }
          }
        });
      }
    });
    Utilities.sleep(200);
  }
  run = 1;
  let emailToUrl = {};
  let resourceNames = Object.keys(resourceNameToEmails);
  let resourceNameBatch = resourceNames.splice(0, 200);
  while(resourceNameBatch.length) {
    options = {
      personFields: 'photos',
      resourceNames: resourceNameBatch,
      sources: [ 'READ_SOURCE_TYPE_PROFILE' ]
    };
    result = People.People.getBatchGet(options);
    if(result && result.responses) {
      Logger.log('request #' + (run++) + ', got '+result.responses.length+' urls');
      result.responses.forEach(person => {
        let primaryUrl = '';
        let url = '';
        if(person.person && person.person.photos) {
          person.person.photos.forEach(photo => {
            if(photo.metadata && photo.metadata.source && photo.metadata) {
              url = photo.url;
              if(photo.metadata.source.type === 'PROFILE' && photo.metadata.primary) {
                primaryUrl = url;
              }
            }
          });
        }
        let email = resourceNameToEmails[person.person.resourceName];
        emailToUrl[email] = primaryUrl || url;
      });
    }
    Utilities.sleep(200);
    resourceNameBatch = resourceNames.splice(0, 200);
  }
  return emailToUrl;
}

这个怎么样?

function searchDirectoryPeople(query) {
  const options = {
    query: query,
    readMask: 'photos,emailAddresses',
    sources: ['DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE']
  }
  const people = People.People.searchDirectoryPeople(options);
  if(people && people.people) {
    Logger.log('size: '+people.people.length);
    people.people.forEach(person => {
      let url = '';
      let email = '';
      if(person) {
        if(person.photos && person.photos[0]) {
          url = person.photos[0].url;
        }
        if(person.emailAddresses && person.emailAddresses.length) {
          person.emailAddresses.forEach(item => {
            if(item.metadata && item.metadata.sourcePrimary) {
              email = item.value;
            }
          });
        }
      }
      return {"imgurl":url,"email":email}
    });
  } 
}

function searchPlus(emailArray) {
  let oA = [];
  emailArray.forEach(e => {
    oA.push(searchDirectoryPeople(e))
  });
  if(oA && oA.length) {
    return oA;
  }
}

看起来 Method: people.searchDirectoryPeople 一次只能指定一个人。

另一个选项可能是 People.People.getBatchGet(),它需要一个额外的步骤,但会为您提供有关您指定的人员列表的信息。请求看起来像这样:

const options = {
    personFields: 'photos,emailAddresses',
    resourceNames: [
      'people/account_id',
      'people/account_id',
      'people/account_id'
    ],
    sources: [
      'READ_SOURCE_TYPE_PROFILE'
    ]
  }
  
  const people = People.People.getBatchGet(options);

您可以通过 Method: people.listDirectoryPeople

获取用户的 account_id