Azure App Service: Integraciones con Salesforce (3 de 4)

Hola a todos, aquí tenemos la segunda entrega de la serie de artículos invitados de Giovanni Modica, Software Architect, .Net Developer & Salesforce Consultant.

En el artículo anterior vimos cómo crear el portal de proveedores y la integración mediante un Logic App, concretamente la parte de la creación de API Apps. En el actual nos centraremos en la creación de la Logic App, en el punto de sincronizar los registros de Salesforce a SQL Server.

Repasemos la estructura que vamos a tratar:

  • El escenario
  • Requisitos
  • Creación de la Aplicación en Salesforce
    • Probar la Aplicación creando algunos registros
  • Creación del Portal de Proveedores
    • Publicación del Portal como una Web App
  • Integración mediante un Logic App
    • Creación de API Apps
      • Salesforce API App
      • SQLServer API App
    • Creación del Logic App
      • Sincronización de Registros de Salesforce a SQL Server
      • Sincronización de Registros de SQL Server a Salesforce
      • Ejecución automática
  • Conclusiones
  • Recursos

Creación del Logic App

Paremos aquí un momento para ver qué es lo que queremos hacer. Queremos una sincronización bidireccional entre Salesforce y la BD de SQLServer.

Para la sincronización de Salesforce hacia SQLServer queremos hacer lo siguiente:

  • Lo primero es buscar todas aquellas asistencias que estén en Salesforce y que no hayan sido sincronizadas y estén en un estado de “Nuevo”
  • Para cada una de estas asistencias obtendremos los detalles
  • Para cada una de estas asistencias insertaremos un nuevo registro en la BD del portal de proveedores
  • Si esto tiene éxito entonces marcaremos la asistencia como sincronizada en Salesforce

Para la sincronización de SQLServer hacia Salesforce, queremos hacer lo siguiente:

  • Queremos ver todos aquellos registros de asistencia que hayan sido completados y que no hayan sido sincronizados
  • Para cada uno de estos registros queremos actualizar Salesforce
  • Si esto tiene éxito entonces marcaremos la asistencia como sincronizada en el portal

Debido a que, de momento, la lógica de las Logic App es una lógica lineal (el paso siguiente depende del paso anterior) tendremos que crear dos Logic App, uno por cada dirección de la sincronización.

Nota: en este caso estamos usando un campo booleano para saber los registros que debemos enviar de un sistema a otro. En una aplicación real esto no es lo mejor ya que cada registro seria sincronizado una sola vez entre sistemas. Lo mejor sería basar la sincronización en un campo de tipo timestamp que indique la última modificación realizada a un registro.

Sincronización de Registros de Salesforce a SQL Server

logic app

Ahora procederemos a realizar la lógica de sincronización entre ambas aplicaciones. Para ello crearemos un Logic App y usaremos los conectores creados anteriormente. En el portal de Azure, pincha en “New”, luego en “Web + Mobile” y selecciona “Logic App”. Se abrirá un blade donde podrás introducir el nombre de la app y el plan de servicios. De nuevo, asegúrate de seleccionar el mismo plan de servicios que has usado en el resto de las apps. Yo he llamado el mío “PortalProveedoresLogic” y he seleccionado el plan de servicios “PortalProveedores”. Pincha en “Create” para crear la aplicación. Después de un minuto aproximadamente verás la notificación de que la app ya está lista.

Abre la aplicación y selecciona la sección de “triggers and actions” mostrando el canvas de edición de acciones para la app. De momento, y para poder desarrollar nuestra app, asegúrate de marcar la opción “Run this logic manually” lo cual nos permitirá ejecutar la aplicación bajo demanda a medida que la vayamos desarrollando. En la parte derecha del canvas de edición deberán aparecer, entre otras, las dos aplicaciones API creadas en los pasos previos: la de salesforce y la de sqlserver. Si no te aparecen es que no has seleccionado los planes de servicio para que sean todos el mismo.

Comencemos por agregar el primer paso. En la parte derecha del canvas de edición, pincha en el conector de Salesforce. Esto agregara un paso a la lógica. Debes autorizar, es decir, proporcionar las credenciales de conexión, el conector para que pueda conectarse a tu instancia de Salesforce. Pincha en el botón de “Authorize”. Te aparecerá una pantalla solicitando tus credenciales de Salesforce. Una vez introducidas las credenciales Salesforce preguntará si le das acceso a la Logic App de Azure. Permite el acceso para poder continuar. Si todo va bien, el conector obtendrá la metadata de Salesforce y te presentará con algunas opciones:

logic app step 1

Es posible que se presente un error diciendo que no se ha podido generar la metadata (“Error fetching swagger api definition”). Si eliminas el paso (pinchando el icono de engranaje en la parte superior derecha del paso y seleccionando “Delete this action”) y vuelves a intentarlo posiblemente sigas teniendo el error. En este caso, tienes que recurrir a un truco: cámbiate a la vista de código pinchando en el icono “Code view” code view del editor y elimina la sección correspondiente a la subscripción de Salesforce (la que esta resaltada en la siguiente imagen) e intenta agregar de nuevo el paso.

salesforce token

Si lo anterior no arregla el problema entonces es que tienes algún error en los parámetros de configuración de la aplicación API (el conector).

En el paso, pincha en los tres puntos “…” hasta que salga la opción de “Execute Query”. Esta opción permite ejecutar una consulta SOQL contra Salesforce. Nuestra consulta será la siguiente:

 select Id from Asistencia__c where Sincronizado__c = false and Estado__c = 'Nuevo'

Queremos el Id de los registros que no hayan sido sincronizados todavía y que estén en un estado de “Nuevo”. Al validar el paso deberías ver algo como esto:

logic app step 1-done

Cuando se ejecute este paso obtendremos en la propiedad result todos los registros de asistencias que cumplen las condiciones descritas. A continuación procederemos con el segundo paso: obtener los detalles de cada asistencia.

Agrega un nuevo paso pinchando de nuevo el conector de Salesforce en la parte derecha del canvas de edición. Selecciona la acción de “Get Asistencia__c” la cual obtendrá todos los datos de una asistencia en particular. En este caso queremos que este nuevo paso se ejecute por cada uno de los registros obtenidos en el paso anterior. Para lograr esto, en el segundo paso pincharemos en el icono de engranaje y seleccionaremos “Repeat over a list”. Se habilitará un nuevo campo donde podremos indicar la lista que contendrá los registros. Para obtener esta lista usaremos una expresión. Las expresiones se especifican colocando como prefijo el carácter @. Así, si queremos obtener la lista de registros del paso anterior usaremos la siguiente formula:

 @body(‘salesforceconnector’).result.records

Esto quiere decir: obtén el body del paso llamado salesforceconnector y busca la propiedad result.records. El body está en formato JSON y la propiedad result es un objeto que a su vez tiene una propiedad llamada records de tipo array que contiene cada uno de los registros retornados por la consulta. Por defecto el nombre de cada paso es el nombre del conector más un índice, así por ejemplo el primer paso del conector de Salesforce se llamará salesforceconnector, el segundo paso se llamará salesforceconnector0, el tercer paso será salesforceconnector1 y así sucesivamente.

En el campo de “Record Id” colocaremos el Id del registro actual dentro del loop. Para obtener el registro actual usaremos la expresión @repeatItem(). Así, si queremos el id del registro colocaremos:

 @repeatItem().Id

Nuestro paso debe quedar así:

logic app step 2

Nota: podríamos ahorrarnos este segundo paso y obtener los datos necesarios como parte de la consulta en el primer paso, pero lo he hecho de esta manera para ilustrar los conceptos.

Ahora que tenemos los datos de cada registro el tercer paso es insertar los datos en la BD de la aplicación web. Para ello usaremos el conector de SQL. En la parte derecha del canvas de edición pincha en la app “Microsoft SQL Connector”. Esto agregará un nuevo paso a la lógica. Selecciona la acción “Insert Into Asistencias (JSON)”. El conector pedirá los parámetros para cada uno de los campos de la tabla. Al igual que con el paso anterior, queremos que esta inserción se realice por cada registro de la lista. Tal y como hicimos en el paso anterior, pincharemos el icono de engranaje y seleccionaremos la opción “Repeat over a list” (si no te sale esta opción, sino que sale “Do not repeat over a list”, selecciona ésta en cambio, el resultado es que debe aparecer el campo “Repeat” en el paso). En este caso la lista la obtenemos con la siguiente expresión:

 @actions('salesforceconnector0').outputs.repeatItems

salesforceconnector0 es el paso anterior, del cual queremos obtener la propiedad outputs que representa la salida del paso (varios registros ya que se ha ejecutado dentro de una lista) y de esta salida obtener la propiedad repeatItems que es un array con el resultado de cada registro obtenido en el loop. Para obtener un campo especifico del objeto usaremos de nuevo la expresión @repeatItem():

 @repeatItem().outputs.body.Id

Esto obtendría el campo Id del objeto de Salesforce. Si todo esto te parece complejo lo mejor es que vayas ejecutando la aplicación cada vez que crees un paso y te fijes en las salidas de estos para ver el JSON que se produce. Esto te dará una idea de cómo obtener los valores que necesitas.

Repetiremos la expresión para cada uno de los campos de la tabla. Recuerda una vez más que al tratarse de campos personalizados estos deben tener el prefijo __c, excepto los campos de Id y Name que se consideran campos estándar (a pesar de estar dentro de un objeto personalizado). Llenaremos los campos de la siguiente manera:

Azure01

** El campo de fecha debería tener la siguiente expresión: @repeatItem().outputs.body.Fecha__c, sin embargo, este valor producía un error a la hora de crear el registro en SQL Server, algo relacionado con el formato de la fecha. Después de intentar varios formatos no he podido lograr que la fecha se guarde en SQL Server, por lo que de momento ignoraremos el campo de fecha.

Los campos de Proveedor y Sincronizado no los llenaremos ya que estos deben ser llenados en el portal de proveedores. Nuestro paso quedaría así:

logic app step 3

Ahora nos queda el último paso que es el de actualizar Salesforce y marcar el registro como sincronizado para que este no vuelva a crearse en ejecuciones posteriores de la lógica. Agrega un nuevo paso a la lógica pinchando el conector de Salesforce en la parte derecha del canvas de edición. Para el nuevo paso selecciona la acción de “Update Asistencia__c”. Haz que el paso se ejecute sobre una lista (selecciona “Repeat over a list” de la configuración del paso). Los parámetros de “Repeat” y de “Record Id” son los mismos del paso anterior. En este caso colocaremos el campo Sincronizado en true.

logic app step 4

Ya tenemos lista la lógica. Asegúrate de guardar los cambios si no lo has hecho ya y cierra el editor (puede que te salga un mensaje preguntándote si quieres descartar los cambios, a pesar de que ya has guardado los cambios, dile que sí, los cambios ya se han guardado). Ejecuta la aplicación pinchando el icono de ejecución run now de la lógica. Si todo va bien deberías poder ver el resultado de la ejecución:

ejecucion exitosa

Adicionalmente deberías poder comprobar lo siguiente: el portal de proveedores tiene las nuevas solicitudes creadas:

portal con asistencias

Y en Salesforce las solicitudes han sido marcadas como sincronizadas:

salesforce sincronizado

Con esto hemos realizado la primera parte de la solución.

 

Muchas gracias a Giovanni Modica por esta serie de artículos uniendo Azure Apps con Salesforce.

Un saludo,

El equipo MSDN España