1. Overview
  2. Api Calls
  3. Merge-Results & Prevent Duplicates
  4. Sort Merged-Results
  5. Pagination

1. Overview

Spaces-App narrows down the viewer ('Me') people-search to colleagues and people with whom the viewer had prior Direct Conversation.

To achieve this Spaces-App does the followings:

2. Api Calls

Spaces app combines the search results of following apis.

  • Find Colleagues
    GET /users/me/colleagues?search={search-string}

    This api will search the user's colleagues

    Sample Response

    {  
       "data":[  
          {  
             "_id":"fake_id1",
             "username":"alexd@abcd.com",
             "name":{  
                "pronunciation_url":"",
                "pronunciation":"",
                "middlename":"",
                "honorific_suffix":"",
                "honorific_prefix":"",
                "givenname":"Alex",
                "formatted":"",
                "familyname":"Doe"
             },
             "emails":[  
                {  
                   "primary":true,
                   "value":"alexd@abcd.com"
                }
             ],         
             "phone_numbers":[  
    
             ],
             "displayname":"Alex Doe",         
             "picture_url":"fake_photo1.jpg"
          }
       ],
       "from":0,
       "to":0
    }
                        
  • Find people that had prior direct space history with the viewer (Me).
    The result of this api can include colleagues as well as people out-side of the viewer's company directory.
    GET /users/me/people/withdm?search={search-string}

    Note:

    This api will also include all hidden direct conversations.
    Read more on how to Hide Direct Spaces here.

    Sample Response

    {  
       "data":[  
          {  
             "_id":"fake_id1",
             "type":"user",
             "username":"alexd@abcd.com",
             "displayname":"Alex Doe",
             "picture_url":"fake_photo1.jpg",
             "phone_numbers":[  
    
             ]
          },
          {  
             "_id":"fake_id2",
             "type":"user",
             "username":"susan.doe@fakedomain.com",
             "displayname":"Susan Doe",
             "picture_url":"fake_photo1.jpg",
             "phone_numbers":[  
    
             ]
          }
       ],
       "nextPageUrl":"",
       "previousPageUrl":"",
       "total":2,
       "from":0,
       "to":1
    }
                        

3. Merge-Results & Prevent Duplicates

Due to scale and performance considerations, the user objects returned by/api/users/me/people/withdm are short-form/subset of user objects returned by /api/users/me/colleagues.

Note: For apps written in strongly typed programming languageslike Java, developers may need to consider transforming api-results to a common user objects before merge.

Sample JS Code

                   
const searchColleagues => async(search, nextPageUrl, findAndAdd) {
  let url = nextPageUrl || 'https://spacesapis.avayacloud.com/api/users/me/colleagues?size=10&search=' + search;
  let response = await fetch(url,
  {
    method: 'GET',
    headers: {
      Authorization: 'jwt ' + access_token,
      Accept: 'application/json',
      'Content-Type': 'application/json'
    }
  });
  let res = await response.json();
  let results = {...res, data=[]}
  for(var user of (res.data || [])) {
    findAndAdd(user)    
    results.data.push(user._id);  
  }
  return results
}

//

const searchPeopleWithDM => async (search, nextPageUrl, findAndAdd) {
  let url = nextPageUrl || 'https://spacesapis.avayacloud.com/api/users/me/people/withdm?size=10&search=' + search;
  let response = await fetch(url,
  {
    method: 'GET',
    headers: {
      Authorization: 'jwt ' + access_token,
      Accept: 'application/json',
      'Content-Type': 'application/json'
    }
  });
  let data = await response.json();
  let results = {...res, data=[]}
  for(var user of (res.data || [])) {
    findAndAdd(user);    
    results.data.push(user._id);  
  }
  return results
}

const findAndAddUser => (foundUsersIds, foundUsers, user) {
  // foundUsersIds is a dictionary object for fast access.
  if(!isUserExists(foundUsersIds, user)){
    foundUsersIds[user._id]=user._id;
    foundUsers.push(user);
  }
}

const isUserExists => (foundUsersIds, user) {
  return user && user._id && foundUsersIds[user._id] ? true : false;
}

4. Sort Merged-Results

At this point need to sort the merge-results by user displayname.

Sample JS Code

const sortByDisplayname => (foundUsers) =>{
  return foundUsers.sort((a, b)=> return a<b);
}

const searchPeople => async (search) {
  let foundUsersIds = {}; // We use dictionary object to with users-ids as key for fast access                     
  let foundUsers = [];
  let colleaguesSearch = await searchColleagues(search, '', (user)=>{
      return findAndAddUser(foundUsersIds, foundUsers, user)
  });

  let peopleWithDm = await searchPeopleWithDM(search, '', (user)=>{
    return findAndAddUser(foundUsersIds, foundUsers, user)
  });

  return {
    foundUsers: sortByDisplayname(foundUsers),
    colleaguesSearch,
    peopleWithDm
  }
}

5. Pagination

Apps implementing pagination for people search should maintain nextPageUrl and previousPageUrl for both api calls, and should go through the whole process of:

  • calling apis with their corresponding nextPageUrl or previousPageUrl
  • merge and remove duplicates
  • re-sort the merged-results