Request directa a WEB API de CRM Online mediante Azure AD

Cómo hacer una petición directa a la WEB API de CRM para la versión Online mediante Azure AD.

Normalmente cuando queremos hacer una consulta a nuestra base de datos en CRM Dynamics utilizamos la SDK que Microsoft nos proporciona y escribimos un código donde instanciaremos el objeto OrganizationService desde el cual podremos ejecutar un RetrieveMultiple para obtener la información que deseemos de nuestro CRM.

Cuando disponemos de un CRM On Premise podemos también recurrir a la invocación de webservices con autenticación delegada o NTLM, cosa que no podemos hacer en el CRM Online.

Pero ¿qué ocurre si la aplicación que estamos desarrollando no está ideada en C#? En principio no podremos usar la SDK que nos proporciona Microsoft para integrarnos con el CRM. Una solución podría ser utilizar Xamarin para compilar nuestro código en otro lenguaje que necesitemos pero Xamarin no cubre todo el abanico de lenguajes. ¿Cómo podríamos integrarnos con un CRM Online si nuestra aplicación está hecha en PHP, NodeJS, Javascript, etc? ¿Podríamos conectar un CRM Online con otro CRM Online mediante Javascript y sin utilizar un Middleware?, ¿Un sistema tercero podría conectarse con nuestro CRM para enviar información sin necesidad de un Middleware? ¿Un JIRA podría integrarse con nuestro CRM directamente? La respuesta es que sí. Podemos realizar una petición a la API Rest de CRM directamente desde cualquier entorno utilizando el protocolo OAuth2 del Azure Active Directory.

Existe un modo genérico de integrarse con un CRM Online que podemos explotar desde cualquier lenguaje de programación que nos proporcione herramientas para ejecutar peticiones web.

El proceso es el siguiente: primero lanzamos una petición a Azure con nuestros credenciales y la URL del CRM sobre el que queremos ejecutar la query y será el propio Azure el que nos los validará. Si son correctos, Azure nos responderá a nuestra petición con un token. Este token es un “codigo de acceso temporal” a nuestro CRM. Podremos utilizar este código para hacer queries al CRM durante un tiempo limitado (normalmente 3600 segundos) y después caducará. Podremos entonces volver a pedir otro token y repetir el proceso.

Tenemos pues 2 peticiones web: obtener el token y realizar la query en CRM.

Vamos a ver cómo configurarlo paso a paso. Lo primero de todo que tenemos que tener en cuenta es que nuestro Dynamics 365 Online tendrá asociado siempre una cuenta de Azure.

Accedemos a nuestro CRM Online:

Página de inicio de CRM Dynamics 365

Página de inicio de CRM Dynamics 365

 

Una vez logados en nuestro CRM accedemos a Azure mediante el portal de acceso: https://portal.azure.com. El usuario con el que nos hará automáticamente el login será el mismo que nuestro CRM Online.

Página de inicio de Azure

Página de inicio de Azure

 

Accedemos a la sección Registro de aplicaciones mediante la barra de búsqueda superior.

Búsqueda de "Registro de aplicaciones" en azure

Búsqueda de “Registro de aplicaciones” en azure

 

Accedemos a Puntos de conexión en la parte superior.

Puntos de conexiones o "endpoints"

Puntos de conexiones o “endpoints”

 

Bajamos un poco y copiamos la URL del Punto de conexión de token de OAuth 2.0. La URL será del estilo: https://login.microsoftonline.com/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token

Descripción de puntos de conexión. Token de OAuth 2.0

Descripción de puntos de conexión. Token de OAuth 2.0

 

Bien, esta será la URL a la que tendremos que solicitar el token. Nos la guardamos para más adelante.

Volvemos a Registro de aplicaciones y creamos una nueva aplicación.

Nuevo registro de aplicación

Nuevo registro de aplicación

 

De nombre pondremos “Acceso API CRM”, tipo de aplicación “Aplicación web o API” y URL de inicio de sesión podremos la URL de nuestro Dynamics:

Detalles de la nueva aplicación

Detalles de la nueva aplicación

 

Una vez creada la buscamos entre la lista y la abrimos. Vamos al apartado Propiedades y copiamos el código  Id de aplicación. Este ID lo tendremos que incluir también en petición de token. Lo guardamos junto con la URL.

Propiedades de la nueva aplicación

Propiedades de la nueva aplicación

 

Vamos al apartado Claves:

Claves de la aplicación

Claves de la aplicación

 

Creamos una nueva Clave con descripción “Token” y que expire en 1 año (eres libre de seleccionar lo que más te convenga en este punto). Pulsamos “Guardar” y nos aparecerá el valor (denominado secreto). Debemos copiarlo y guardarlo en este instante pues no tendremos otra posibilidad de volver a conseguirlo:

"Secreto" del token de la nueva aplicación

“Secreto” del token de la nueva aplicación

 

Vamos al apartado Permisos necesarios y pulsamos en Agregar.

Agregar permisos de aplicación

Agregar permisos de aplicación

 

Como API seleccionamos Dynamics CRM Online.

Seleccionar aplicación Dynamics CRM Online

Seleccionar aplicación Dynamics CRM Online

 

Como permisos seleccionamos Access CRM Online as organization users.

Seleccionar permisos delegados

Seleccionar permisos delegados

 

Una vez agregado tenemos que pulsar “Conceder permisos” en la parte superior. Importante: si estás en un Azure de una compañía esta acción la tendrá que realizar un administrador.

Conceder permisos

Conceder permisos

 

Con esto ya tenemos configurado lo necesario en Azure.

Los datos que tendremos por el momento son los siguientes:

Dato Valor Descripción
URL OAuth2.0  https://login.microsoftonline.com/d627e6dd-343b-4323-8d8d-b9381c722c7a/oauth2/token La URL de petición de token
URL CRM  https://micrm.crm4.dynamics.com/ La URL de nuestro CRM
Usuario CRM  ddiaz@micrm.onmicrosoft.com Usuario de nuestro CRM
Password CRM  MiPassw0rd! El password de nuestro usuario
Id Aplicación  b68b3b21-9f40-4923-85e1-7f8e3bc5b746 Id de la aplicación creada en Azure
Secreto  I/sRo1MyR6wRFUS9RgYnCJmCMWiIbq2IPx9evCm45Qc= Disponible solo por 1 año

Con esta información ya podemos ejecutar una query sobre nuestro CRM.

 

Peticiones web

Obtención de token

Los datos que tenemos que incluir en la petición de token son los siguientes

Nombre Key Value
ID Cliente client_id b68b3b21-9f40-4923-85e1-7f8e3bc5b746
URL CRM* resource https://micrm.crm4.dynamics.com/
Usuario* username ddiaz@micrm.onmicrosoft.com
Contraseña* password MiPassw0rd!
Tipo acceso grant_type password
Secreto client_secret I/sRo1MyR6wRFUS9RgYnCJmCMWiIbq2IPx9evCm45Qc=

(*) Los valores tendrán que ser incluidos con encodeURIComponent, por ejemplo el usuario ddiaz@micrm.onmicrosoft.com quedaría como ddiaz%40micrm.onmicrosoft.com

La petición que tendremos que lanzar será

Un ejemplo de petición con datos reales

La respuesta a la petición será como la siguiente:

Y el parámetro en cuestión que nos interesa es el access_token. Con esto ya tenemos el token.

 

Ejecución de query

Una vez que tenemos el token podemos acceder a la WEB API de CRM invocando cualquiera de sus métodos, siempre teniendo en cuenta el nivel de seguridad del usuario para el que hemos obtenido el token. Esto significa que si el usuario ddiaz@micrm.onmicrosoft.com no tiene permisos en CRM para editar contactos, no podrá ejecutar una petición de actualización de un contacto.

Otro punto importante es que mediante este método solo podremos acceder a la WEB API de tipo Rest de CRM y no podremos invocar peticiones directas al OrganizationService con SOAP.

La petición que hagamos tendrá que incluir en el header la propiedad “Authorization” con el valor “Bearer:” + token. Esto será suficiente para obtener acceso a la base de datos de CRM.

El ejemplo que vamos a mostrar es una petición a la API Rest para crear un contacto en CRM.

La petición sería:

 

La URL a donde  enviaremos la petición es de la API Rest de CRM. En particular nos referimos a la entidad “Contacto”. Como vemos, en el header incluimos el token con la palabra “Bearer:” antes. El método POST indica que queremos crear un registro de la entidad. Y en el objeto Data incluimos los logicalName de los campos de la entidad y sus correspondientes valores.

Para sacar partido a la WEB API de CRM existe mucha documentación oficial al respecto para ejecutar cualquier acción sobre nuestra base de datos.

 

Resultados

He implementado un pequeño código de ejemplo en Javascript para hacer la prueba. En particular he utilizado la librería Angular para realizar las peticiones http, pero podría implementarse sin Angular o con cualquier otro framework.

Los archivos que he utilizado son los siguientes:

Archivos del ejemplo de autenticación por OAuth 2.0

Archivos del ejemplo de autenticación por OAuth 2.0

El framework de Angular lo podéis descargar del sitio oficial. Los archivos indexOauth.html y js_api_rest_oauth.js los detallo a continuación:

indexOauth.html:

js_api_rest_oauth.js:

El resultado de la ejecución del código anterior genera la siguiente respuesta:

Resultados de ejecución del ejemplo

Resultados de ejecución del ejemplo

Si lo ejecutáis desde vuestro PC en local es posible que obtengáis el error de No ‘Access-Control-Allow-Origin’. Para solucionarlo existen extensiones de Google Chrome que lo resuelven.

Como veis hemos creado un contacto en CRM a través de un token obtenido mediante OAuth del Azure Active Directory ejecutando una petición a la WEB API.

Espero que os sirva!

 

Peticiones SOAP con AngularJS en CRM Dynamics

Soap request con AngularJS en Microsoft Dynamics CRM

La librearía AngularJS nos proporciona un potente framework de herramientas y procedimientos con los que implementar páginas web basadas en MVC. Toda esta funcionalidad se puede también utilizar dentro de nuestros recursos web –web resources- en CRM. En este post vamos a ver cómo implementar llamadas Soap con AngularJS y encadenar respuestas con los objetos promises.

Como sabemos, cuando se hace una query a CRM desde el frontal web utilizando la API debemos trabajar con funciones Callback –ya sea para peticiones utilizando la librería SDK.Rest o peticiones Soap a través del Organization Service- y en determinadas ocasiones, cuando tenemos que encadenar varias queries una detrás de otra el modo común de realizarlo es anidando Callbacks:

Con la librería AngularJS, los objetos promises que veremos a continuación y los servicios “$http” y “$q”, este ejemplo anterior se transformaría en algo del estilo:

Como vemos, el código queda más limpio en el segundo caso. Además de dejar el código más bonito la librería angular nos ofrece una mayor libertad para controlar procesos asíncronos permitiéndonos acceder al proceso de carga o ejecutando varias peticiones en paralelo.

Recordemos que para realizar una llamada Soap necesitamos tres cosas: la URL del endpoint, la acción que vamos a utilizar, y el cuerpo del mensaje. Con estas tres cosas podemos realizar la petición Soap con AngularJS.

Para construir la llamada utilizaremos el servicio “$http” de Angular como se muestra en el ejemplo.

La propiedad data del objeto response en el primer then del método RequestData contendrá el resultado de la petición. En este caso el cuerpo del mensaje es una petición de RetrieveMultiple con un filtro y nos devolverá las cuentas cuyos nombres empiecen por “A”. Recordar que esta es una respuesta http y por defecto el endpoint de CRM que estamos atacando nos devolverá mensajes serializados en XML -no es posible cambiar la respuesta a JSON como sí permite la API REST OData-. Para deserializar el XML podemos recurrir a herramientas externas o implementar nuestro propio deserializador utilizando la versión reducida de jQuery que trae angular, analizando los nodos. Yo he utilizado como base este ejemplo con una pequeña modificación.

El resultado de la ejecución nos mostraría un array de todos los Ids de las cuentas que empiezan por “A” en nuestro CRM.

Ids de todas las cuentas de CRM que empiezan por “A”

Pero donde realmente se puede sacar partido a esta librería es en el uso del servicio “$q”. Este servicio nos permite añadirle N objetos promesa y ejecutarlo. El código que esté dentro del then sucesivo se ejecutará cuando todas las peticiones hayan terminado y nos devolverá N respuestas, una para cada una de las peticiones ejecutadas. Esto es una gran noticia puesto que nos avisará cuando todas las peticiones tengan respuesta, y no se ejecutará cada vez que termine una de ellas. Así permitirá controlar el flujo de información de nuestro código de una manera mucho más limpia y clara.

Siguiendo con el ejemplo anterior, imaginemos que después de obtener todas las cuentas que empiecen por “A”, para cada una de ellas queremos obtener el nombre de todos los contactos asociados a esas cuentas.

El resultado de esta ejecución nos proporcionaría el siguiente array de nombres:

Nombres de todos los contactos que pertenecen a alguna de las empresas del ejemplo anterior

Nombres de todos los contactos que pertenecen a alguna de las empresas del ejemplo anterior

Estos son sólo dos ejemplos de lo que esta librería puede ofrecernos en CRM Dynamics  pero realmente las posibilidades son infinitas cuando juntamos peticiones Soap con AngularJS.

Parametros que se envian a Web Resource desde formulario

Cuando creamos un Web Resource desde el menú de edición del formulario de la entidad, podemos configurar que se envíen parámetros al mismo en la iniciación del formulario. Esto se consigue marcando la casilla “Pasar código tipo de objeto de registro e id. Único como parámetros”.

Configuración de Web Resource para pasar parámetros desde el formulario

Configuración de Web Resource para pasar parámetros desde el formulario

Cuando tenemos esta casilla activada durante la carga del Web Resource en nuestro formulario se invocará la URL y se añadirán algunos parámetros del contexto donde se está abriendo ese Web Resource. Esto es algo bueno puesto que mediante este contexto de información podremos desarrollar un Web Resource personalizado, por ejemplo, para el cliente que se esté viendo en ese momento.

Los parámetros que se envían por defecto cuando seleccionamos esta casilla son los siguientes:

# Parámetro Descripción
1 OrgLCID Id del código de lengua de la organización
2 UserLCID Id del código de lengua del usuario
3 Id Id del registro que estamos cargando
4 Orgname Nombre de la organización
5 Type Tipo de formulario.  0 = Undefined, 1 = Create, 2 = Update, 3 = Read Only, 4 = Disabled, 5 = Quick Create, 6 =  Bulk Edit, 11 = Read Optimized
6 Typename Nombre de la entidad donde se ha abierto el WR

Un ejemplo de URL completa para nuestro sería el siguiente:

new_prueba_web_resource?OrgLCID=3082&UserLCID=3082&id={42DCC3D2-7339-E611-80D6-C4346BAC8D78}&orgname=NuestraOrganizacion&type=2&typename=contact

El modo en el que podemos capturar estos parámetros desde nuestro javascript se ha indicado ya en este post antiguo. En este caso el proceso sería similar.

CRM también nos permite enviar parámetros personalizados introduciéndolos en el cuadro de texto que está encima del check indicado con anterioridad, en las propiedades del Web Resource. Si fuese este el caso, estos parámetros se enviarán a continuación de los ya indicados.

Podéis ver los parámetros que se han enviado a un Web Resource fácilmente con la extensión HUDCRM.

Obtener parámetros de carga de un web resource desde HUDCRM

Obtener parámetros de carga de un web resource desde HUDCRM