Usar y crear campos nuevos sobre el perfil de usuario de Office 365 para hacer búsquedas en SharePoint. Parte 2/2

Un comentario

En la primera parte, escribí sobre como trabajar sobre una propiedad personalizada del perfil de usuario Office 365 para que fuera “rastreable“, en esta segunda parte, pasaré a una parte mas técnica, ya que estaré mostrando como usar la API de SharePoint para obtener la lista de usuarios y hacer filtro sobre campos personalizados. Para ello, mostrare ejemplos en JavaScript , trabajando en la consola del navegador (es importante que sobre la pagina que se quiera emular el ejemplo se tenga la referencia a la librería de jquery, ya que la estaré usando para realizar las consultas ajax, por lo que recomiendo usar una pagina clásica e inyectar el script con el Content Editor).

Los ejemplos estarán enfocado en el uso de la API “/_api/search/” y el uso de “/_api/Web/SiteUserInfoList/items“, ademas de explicar cual es la diferencia entre usar una y otra.

Obteniendo la lista de usuarios a través de
SiteUserInfoList

Para construir la URL de búsqueda usaré el objeto _spPageContextInfo (que trae una serie de parámetros del contexto de la pagina de SharePoint). Adicionalmente, a la consulta agregué un filtro donde el EMail de usuario no fuera null, esto permitirá filtrar la respuesta con resultados validos (de lo contrario el resultado podría traer información de grupos de SharePoint o usuarios de sistemas que para este caso en particular no queremos mostrar…)

$.ajax({ 
    url: _spPageContextInfo.webAbsoluteUrl +  "/_api/Web/SiteUserInfoList/items?$filter=EMail+ne+null",
    headers:{
        "accept": "application/json;odata=verbose",
        "content-type":"application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val()
    }
}).then((response)=>{ console.log(response)})
  .catch((response)=>{console.log(response)})

El resultado seria el siguiente (se muestra uno de los resultado del array ampliado)


Nota: Cuando el campo personalizado esta recién creado, no sera obtenible en los resultados de manera inmediata, por lo que es necesario esperar aproximadamente entre 20 minutos y 1 hora para que SharePoint lo indexe

Lo interesante (y poco agradable) de este método, es que el resultado obtenido esta limitado a la actividad de los usuarios dentro del sitio donde estamos haciendo la consulta, para explicarme mejor, el resultado obtenido solamente mostrara a los usuarios que pertenecen a los grupos de permisos del sitio, o de aquellos usuarios que han ingresado a dicho sitio. Es decir, si acabamos de crear un sitio llamado /GestorDocumental donde solamente han ingresado dos usuarios, cuando hagamos la consulta a la API, el resultado mostrara solamente la información de esos 2 usuarios, indiferentemente si en nuestro TENAN tenemos un total de 500 usuarios.

Finalmente, y para continuar, si queremos hacer una consulta filtrada basada en el campo personalizado, simplemente agregamos la condición en el $filter como se muestra a continuación

$.ajax({ 
     url: _spPageContextInfo.webAbsoluteUrl +  "/_api/Web/SiteUserInfoList/items?$filter=EMail+ne+null+and+NumeroIdentificacion+eq+'221321'",
     headers:{
         "accept": "application/json;odata=verbose",
         "content-type":"application/json;odata=verbose",
         "X-RequestDigest": $("#__REQUESTDIGEST").val()
     }
 }).then( response =>{ console.log(response)})
   .catch( response =>{console.log(response)})

Obteniendo la lista de usuarios a través de la API de búsqueda con /_api/search

La API /_api/search tiene muchas ventajas frente al anterior método, ya que lo podemos usar incluso para hacer búsqueda de documentos basado en el contenido de los archivos, pero esto sera un punto del cual escribiré en otra entrada… La forma de obtener el resultado basado exclusivamente en usuarios es adicionar a la consulta <sourceid=’B09A7990-05EA-4AF9-81EF-EDFAB16C4E31′>.

$$.ajax({ 
    url: _spPageContextInfo.webAbsoluteUrl +  "/_api/search/query?querytext='*'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&rowlimit=5&startrow=0",
    headers:{
        "accept": "application/json",
    }
}).then(response=>{ 
	var totalRow = response.PrimaryQueryResult.RelevantResults.TotalRows;
	var items = response.PrimaryQueryResult.RelevantResults.Table.Rows;
	var elementsResult = [];
	items.forEach( element =>{
		var temp = {};
			element.Cells.forEach((act, i)=>{
			temp[act.Key] = act.Value
		})
		elementsResult.push(temp)
 	})
	console.log("Filas totales: "+totalRow);
	console.log(elementsResult);
}).catch(response=>{console.log(response)})

El resultado obtenido es un poco difícil de leer, por lo que en el código anterior simplemente procesé el resultado para que quede más legible y es lo que imprimo en la consola.

Resultado ampliado de uno de los registro

La ventaja de consultar de esta manera es que no tenemos la limitante que explique sobre el SiteUserInfoList, sin embargo, esta trae otras limitantes, que explicare a continuación:

  • 500 resultados por consulta: si revisan el código anterior, notaran que coloque en el query “rowlimit=5“, esto es la cantidad de filas que me devolverá, siendo el máximo posible 500 (colocar una cantidad mayor no hará que devuelva mas registros), y también coloque startrow=0, con lo cual estoy diciendo que los 5 registros deben partir desde la fila 0, por lo que si quiero obtener los 5 registros siguientes, debo hacer otra consulta pero colocando “startrow=5″. Adicionalmente la consulta nos devuelve una propiedad donde nos indica la cantidad total de registros que cumplen con el criterio de búsqueda, por lo que con este valor podemos determinar la cantidad de veces que podemos paginar el resultado. En el ejemplo ese valor total lo almacene en la variable totalRow y lo imprimí en la consola como se muestra al inicio de la foto anterior.
  • Propiedades personalizadas de usuario no son visible de manera predeterminada: otra de las cosas que se nota a simple vista es que la propiedad personalizada no se muestra, por lo que la consulta debe ser modificada para agregar una condición que permita indicar que propiedades de usuarios queremos mostrar, como por ejemplo el numero de identificación. En este punto vale la pena acotar, que las propiedades personalizadas no serán mostradas si estas no fueron asignadas a un “Refinable” como explique en el post anterior, y para obtenerla debemos “pedirla” a través del alias que le fue definido, que en nuestro caso era NumeroIdentificacion01

Entonces para que hagamos una consulta obteniendo las propiedades personalizadas y un conjunto de propiedades nativas podemos hacerlo adicionando al final de la consulta algo como: &selectproperties=’Title,NumeroIdentificacion01,JobTitle,WorkEmail’

$.ajax({ 
    url: _spPageContextInfo.webAbsoluteUrl +  "/_api/search/query?querytext='*'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&rowlimit=5&startrow=0&selectproperties='Title,NumeroIdentificacion01,JobTitle,WorkEmail'",
    headers:{
        "accept": "application/json",
    }
}).then(response=>{ 
	var totalRow = response.PrimaryQueryResult.RelevantResults.TotalRows;
	var items = response.PrimaryQueryResult.RelevantResults.Table.Rows;
	var elementsResult = [];
	items.forEach( element =>{
		var temp = {};
			element.Cells.forEach((act, i)=>{
			temp[act.Key] = act.Value
		})
		elementsResult.push(temp)
 	})
	console.log("Filas totales:" +totalRow);
	console.log(elementsResult);
}).catch(response=>{console.log(response)})

El ultimo paso seria hacer consultas filtradas en base al parámetro personalizado, para ello simplemente modificamos el .<querytext=”*”> por <querytext=’NumeroIdentificacion01={valor}’>

$.ajax({ 
    url: _spPageContextInfo.webAbsoluteUrl +  "/_api/search/query?querytext='NumeroIdentificacion01=324234234'&sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&rowlimit=5&startrow=0&selectproperties='Title,NumeroIdentificacion01,JobTitle,WorkEmail'",
    headers:{
        "accept": "application/json",
    }
}).then(response=>{ 
	var totalRow = response.PrimaryQueryResult.RelevantResults.TotalRows;
	var items = response.PrimaryQueryResult.RelevantResults.Table.Rows;
	var elementsResult = [];
	items.forEach( element =>{
		var temp = {};
			element.Cells.forEach((act, i)=>{
			temp[act.Key] = act.Value
		})
		elementsResult.push(temp)
 	})
	console.log("Filas totales:" +totalRow);
	console.log(elementsResult);
}).catch(response=>{console.log(response)})

Espero que esta serie de post les sirva de ayuda a todos aquellos colegas que realizan soluciones hospedas (Add-Ins) y desarrollos en SPFx. Próximamente estaré liberando pequeñas soluciones básicas en SPFx que utilizan estas mismas consultas.

Singular: 1 comentario en “Usar y crear campos nuevos sobre el perfil de usuario de Office 365 para hacer búsquedas en SharePoint. Parte 2/2”

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s