GuíadeIntegración Salesforce - Portrait...

30
Guía de Integración Salesforce.com Versión 5.5

Transcript of GuíadeIntegración Salesforce - Portrait...

Guía de IntegraciónSalesforce.com

Versión 5.5

© 2013 Pitney Bowes Software Inc. Todos los derechos reservados.

Este documento puede incluir información confidencial y exclusiva de propiedad de Pitney Bowes Inc. y/o sussubsidiarias y compañías asociadas.

Portrait Software, el logotipo de Portrait Software, Portrait y la marca Portrait de Portrait Software son lasmarcas comerciales de Portrait Software International Limited y se prohíbe su uso o explotación de cualquierforma sin previa autorización escrita expresa de Portrait Software International Limited.

Reconocimiento de marcas comerciales

Otros nombres de productos, nombres de compañías, marcas, logotipos y símbolos a los que se hace referenciaen la presente pueden ser marcas comerciales omarcas comerciales registradas de sus propietarios registrados.

Soporte técnico de Portrait Software

Si necesita ayuda con algún tema no abordado en esta documentación, consulte la Base de conocimientosde nuestro sitio web http://support.portraitsoftware.com y siga los enlaces que llevan al producto.

También puede descargar otra documentación de Portrait Software desde el sitio. Si no tiene nombre deusuario ni contraseña, o no los recuerda, comuníquese con nosotros a través de uno de los canalesmencionados a continuación.

Si encuentra un problema en el uso, la instalación o la documentación de este producto, comuníquese connosotros a través de cualquiera de los siguientes métodos:

Correo electrónico:[email protected]

Teléfono

• EE. UU./Canadá 1-800-335-3860 (línea gratuita)• Resto del mundo +44 800 840 0001

Cuando notifique un problema, nos resultará útil la siguiente información:

• El nombre de la aplicación de software.• Las circunstancias en las que surgió el problema.• Los mensajes de error que recibió (si hubiera).• La versión del software que utiliza.

Pitney Bowes Software Inc.

June 13, 2013

Contenidos

Capítulo 1: Introducción.............................................................................................5Objetivo................................................................................................................................6Público previsto...................................................................................................................6Documentación relacionada...............................................................................................6

Capítulo 2: Visión general..........................................................................................7Presentación de Saleforce.com/Interaction Optimizer....................................................8

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com................11Requisitos previos............................................................................................................12Limitaciones.......................................................................................................................12Consideraciones sobre el servicio web Interaction Optimizer.....................................13¿Por qué se utiliza el interceptor?...................................................................................14Instrucciones relativas al interceptor..............................................................................16Interaction Optimizer con Salesforce.com para el cliente............................................18

Componentes de Visual Force.......................................................................................18Controladores de componentes.....................................................................................19Proxy Entity Wrapper para recomendación...................................................................20Páginas Visualforce Apex..............................................................................................20Extensión del controlador Visualforce............................................................................21Descargar e instalar el código de muestra ...................................................................22Actualizar las clases proxy.............................................................................................22Gestionar las respuestas de recomendación.................................................................23

Capítulo 4: Apéndice ...............................................................................................25Fragmentos de XSLT.........................................................................................................26Código InlineXsdInWsdlBehavior.cs...............................................................................27Componentes de Salesforce.com....................................................................................29

Código Apex......................................................................................................................29

Portrait IO 5.54

Capítulo 1Introducción

En esta sección:

• Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6• Público previsto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6• Documentación relacionada . . . . . . . . . . . . . . . . . . . . . . . .6

ObjetivoEn este documento se explica cómo integrar Portrait Interaction Optimizer (Interaction Optimizer) conSaleforce.com. En él se identifican las actuales restricciones que existen en Salesforce.com paraconsumir los servicios web de Interaction Optimizer y se explica cómo sortear estas restricciones.

Público previstoEste documento está destinado a aquellos desarrolladores de Salesforce.com que deseen integrar lasrecomendaciones centradas en el cliente en tiempo real de Interaction Optimizer (Interaction Optimizer)con Salesforce.

Documentación relacionadaMedios (zip/dvd) y ubicaciónDocumento

• Medios de Portrait Interaction Optimizer en\Documentation\Portrait Interaction Optimizer AdministrationGuide.pdf

• Guía de administración dePortrait Interaction Optimizer

• Nota de prensa de PortraitInteraction Optimizer • Medios de Portrait Interaction Optimizer en

\Documentation\Interaction Optimizer-release-notes.pdf

Todos los documentos también están disponibles en el sitio web de soporte técnico dePortrait Software: http://support.portraitsoftware.com

Sugerencia:

Portrait IO 5.56

Objetivo

Capítulo 2Visión general

En esta sección:

• Presentación de Saleforce.com/Interaction Optimizer . . .8

Presentación de Saleforce.com/Interaction OptimizerSalesforce.com presenta una oferta de automatización del equipo de ventas SaaS con opciones deventas, servicio y centro de asistencia respaldadas por un modelo de datos estándar pero ampliableque incluye cuentas, contratos y oportunidades. Salesforce.com ofrece su propio entorno de desarrollode aplicaciones (Apex) que puede utilizarse para crear aplicaciones nuevas en Salesforce.com, perotambién para ampliar la funcionalidad existente mediante la integración con otros sistemas (tales comoInteraction Optimizer) a través de servicios web. El cliente de Salesforce.com para Interaction Optimizerpresenta:

• Una interfaz de servicios web Apex para Interaction Optimizer que incluye datos como contenidoconfigurable de Salesforce.com , así como todos los campos de cuentas por defecto que son asignadosen la solicitud de recomendaciones de Interaction Optimizer.

• Una ampliación del Contact Controller Salesforce.com paramostrar las recomendaciones de InteractionOptimizer mediante un código de página Visualforce de muestra. Esto muestra las recomendacionesy ofrece la opción de capturar los comentarios positivos, negativos o no presentados.

Portrait IO 5.58

Presentación de Saleforce.com/Interaction Optimizer

9Guía de Integración Salesforce.com

Capítulo 2: Visión general

Capítulo 3Integración de InteractionOptimizer conSalesforce.com

En esta sección:

• Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12• Limitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12• Consideraciones sobre el servicio web Interaction

Optimizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13• ¿Por qué se utiliza el interceptor? . . . . . . . . . . . . . . . . . .14• Instrucciones relativas al interceptor . . . . . . . . . . . . . . . .16• Interaction Optimizer con Salesforce.com para el cliente .18

Requisitos previosLos requisitos previos para integrar una instancia de Interaction Optimizer con Salesforce.com son lossiguientes:

• Una instancia de Salesforce.com que utilice vistas de contactos para las interacciones.• Una instancia de Interaction Optimizer que debe ser públicamente direccionable por Internet.• Conocimiento de la administración de Interaction Optimizer y, concretamente, de sus servicios web,tal como se describen en la Guía de administración de Interaction Optimizer.

• Conocimiento del desarrollo de Apex (el lenguaje de desarrollo de la plataforma Force.com).• Conocimiento del desarrollo de .NET/WCF para crear un interceptor que traduzca los mensajes entreel servicio web de Interaction Optimizer y Salesforce.com. Nota: Puede elegir otras plataformas dedesarrollo, como Java, según sobre qué esté construido el interceptor.

LimitacionesExisten algunas limitaciones de la plataforma de desarrollo de Force.com a la hora de consumir unservicio web SOAP (lo cual es el caso del servicio web de Interaction Optimizer). No puede analizar unWSDL SOAP que contenga los siguientes modelos:

• Wsdl:import

• Xsd:import

• Xsd:attribute

• Xsd:extension

• Xsd:enumeration

• Xsd:anyType

El modo en que Force.com reacciona a estos modelos varía.

• En el caso de algunos (p. ej. wsdl:import, xsd:import o xsd:attribute), da un mensaje deerror y no puede analizar el WSDL.

• Para los elementos xsd:Extension, Force.com genera clases, pero con elementos solo para el tipoderivado. P. ej. considerar este tipo en el WSDL:

<xsd:complexType name="GetActionsResponse"><xsd:complexContent mixed="false"><xsd:extension base="tns:IOWebServiceResponse"><xsd:sequence><xsd:element minOccurs="0" name="Output"nillable="true" type="tns:GetActionsOutput"/>

</xsd:sequence></xsd:extension>

</xsd:complexContent></xsd:complexType>

Portrait IO 5.512

Requisitos previos

Estos tipos son generados como resultado de jerarquías de herencia de clases .NET en InteractionOptimizer. Aquí, el tipo complejo GetActionsResponse deriva de IOWebServiceResponse.

Force.com genera clases tanto para IOWebServiceResponse como para GetActionsResponse,pero la clase Apex analizada para GetActionsResponse no contiene ningún miembro de la clasebase IOWebServiceResponse. Esto provoca un error de análisis del mensaje xml en el tiempo deejecución, donde el elemento GetActionsResponse contiene miembros del tipo baseIOWebServiceResponse. Si hay un miembro denominado «Foo» en IOWebServiceResponse, eltiempo de ejecución Force.com da un mensaje de error que dice: «no se pudo encontrar el tipo de Apexpara http://<namespace name>/Foo». Esto se debe a que trata de encontrar un miembro Foo enla clase generada GetActionsResponse, que no está ahí.

Para los modelos xsd:enumeration Force.com genera elementos con sus tipos xsd subyacentes.Por ejemplo, pongamos por caso el siguiente elemento:<xsd:elementname="RefData.MarketingCampaignCategory"nillable="true"type="tns:RefData.MarketingCampaignCategory"/>

Donde el tipo RefData.MarketingCampaginCategory se define de la siguiente manera:<xsd:simpleType name="RefData.MarketingCampaignCategory">

<xsd:restriction base="xsd:string">

<xsd:enumeration value="GatherInformation"/><xsd:enumeration value="Retain"/><xsd:enumeration value="Sell"/><xsd:enumeration value="Service"/>

</xsd:restriction></xsd:simpleType>

Aquí, Force.com analiza el elemento con un tipo de cadena (el tipo xsd subyacente, en este caso).

Consideraciones sobre el servicio web InteractionOptimizer

Aunque algunas de las limitaciones citadas anteriormente de Force.com pueden ser tratadas por elservicio web Interaction Optimizer, otras no.

Permitir una generación de wsdl plano en Interaction OptimizerEl servicio web Interaction Optimizer puede ser generado (por una herramienta denominadaServiceMaker) para crear un wsdl que no incluya ninguna wsdl:import o xsd:import, es decir, todoel WSDL es generado como un solo documento. Esto puede conseguirse habilitando la opción « Evitardeclaraciones de importación enWSDL» (el asistente de servicemaker) o utilizando la opción /FlatWsdl(al emplear la utilidad de la línea de comandos ServiceMaker). Aunque no es necesario, si utilizamosun interceptor (que se explica más adelante en este documento), al habilitarlo se ayuda a escribir elinterceptor.

Teclear jerarquías y espacios de nombresEl servicio web Interaction Optimizer genera un WSDL jerárquico que contiene los modelos dexsd:extensión (tal como se explica más arriba), que no pueden ser analizados por Force.com.

13Guía de Integración Salesforce.com

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com

Actualmente, no hay ninguna opción para esto en la herramienta ServiceMaker. Aunque esto se puedecambiar mediante el uso de un xslt, estos tipos a menudo pertenecen a distintos espacios de nombres,y eso da lugar a elementos xml que tienen múltiples referencias a espacios de nombres, algo queSalesforce no puede analizar en el tiempo de ejecución. Por ejemplo, pongamos por caso el siguienteelemento de unmensaje xml (se pueden generar mensajes como este a partir del servicio web InteractionOptimizer puesto que contiene jerarquías).

<ExecuteWSTestResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance"<CompletionString xmlns="http://ServiceCore/Response">Completed</CompletionString>

<Outcome xmlns="http://ServiceCore/Response">Outcome</Outcome><Suspension xmlns=http://ServiceCore/Responsexmlns:a="http://ServiceCore/Suspension"><a:ContextData>context</a:ContextData><a:ResumeID>resume</a:ResumeID><a:SerialisationStrategy>strategy</a:SerialisationStrategy>

</Suspension><Output><MyString>Hello world</MyString>

</Output></ExecuteWSTestResult>

Pensemos en el elemento CompletionString. Se trata de una cadena, pero el elemento contieneuna declaración de espacio de nombre por defecto para el espacio de nombre"http://ServiceCore/Response". Esto se debe a que este elemento está definido en uno de lostipos base (denominado Respuesta) del elemento ExecuteWSTestResult que pertenece al espaciode nombres xml "http://ServiceCore/Response".

¿Por qué se utiliza el interceptor?Debido a las funciones de análisis WSDL limitadas de Force.com (que se describen en la secciónanterior), no se puede consumir el servicio web Interaction Optimizer en su estado actual a partir deSalesforce.com.

Existen varias soluciones alternativas:

• Consumir el servicio web Interaction Optimizer a través de la generación y el análisis de los mensajesxml mediante la API de análisis del DOM de Apex: sin duda es una opción, pero no es muy adecuada,puesto que se basa en una manipulación y análisis de contenido xml basada en una cadena de bajonivel. Además, este código no puede volver a utilizarse en varias instalaciones de Interaction Optimizer(que pueden variar en cuestión de tipos de datos según los modelos utilizados, las personalizacionesrealizadas y las opciones seleccionadas para generar el servicio a través de Service Maker).

• Construir un servicio de interceptor que esté entre el servicio web Interaction Optimizer y Salesforce.comy traduzca los mensajes en uno y otro sentido entre ambos sistemas.

• Aunque el código de dicho interceptor ya no podrá reutilizarse en varias instalaciones de InteractionOptimizer (porque los datos de decisión varían), ofrece un enfoque más adecuado que la cadenabruta basada en un análisis DOM xml.

Portrait IO 5.514

¿Por qué se utiliza el interceptor?

• Dicho servicio de interceptor deberá estar alojado y expuesto a través de un terminal públicamenteaccesible (pero seguro) con el que pueda comunicarse SalesForce.

De estas alternativas, el interceptor es la estrategia recomendada para integrar Salesforce.com eInteraction Optimizer como estrategia provisional (hasta que Interaction Optimizer soporte otras opcionesen versiones futuras).

Ventajas

• No es necesario analizar DOM xml brutos.

• Por lo que respecta a Salesforce, simplemente necesita consumir el servicio de interceptor, que ofreceun WSDL que Salesforce pueda comprender.

• Este interceptor puede construirse utilizando cualquier tecnología estándar que sea capaz de analizarel WSDL actualmente expuesto por el servicio web Interaction Optimizer (p. ej. .NET/WCF, Java, etc.).

Limitaciones

• El código del interceptor no puede ser genérico en las instalaciones de Interaction Optimizer, puestoque puede haber variaciones de tipos expuestos por el servicio Interaction Optimizer y, por lo tanto,los tipos expuestos por el interceptor.

• La construcción de un interceptor requiere conocimiento de una plataforma tecnológica de otroForce.com, que puede estar o no a disposición del equipo de TI de una empresa que tenga unainstalación Salesforce.com; esta tarea puede ser asumida entonces por un equipo de serviciosprofesionales PBBI que ayude a configurar, instalar y personalizar los productos PBBI.

El servicio de interceptor y el servicio Interaction Optimizer concreto pueden ser alojados en el mismoservidor o en distintos servidores. Ambas opciones funcionan mientras el interceptor esté expuesto através de un terminal públicamente accesible (pero seguro) con el que Salesforce pueda comunicarse.

El siguiente diagrama ilustra uno de los escenarios de implementación posibles.

15Guía de Integración Salesforce.com

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com

Instrucciones relativas al interceptorAl escribir un servicio WCF de interceptor, deberá seguir una serie de instrucciones para asegurarsede que el servicio sea compatible con Salesforce.com y este pueda acceder a él.

Instrucciones

• El tipo de interceptor debe exponer todos los tipos expuestos por el servicio web Interaction Optimizerde forma plana (es decir, si Interaction Optimizer expone un tipo GetActionsResponse, que a suvez deriva de IOWebServiceResponse, entonces el interceptor debe eliminar dicha relación deherencia entre estos dos tipos en el WSDL/contrato que expone, replicar todos los miembros deIOWebServiceResponse en GetActionsResponse y tratarlos como dos clases distintas). Estogarantizará que no haya elementos xsd:extension en el wsdl que no pueda analizar Salesforce.

• Todos estos tipos aplanados deberían pertenecer a un solo espacio de nombres xml (preferentementeaquel al que pertenezca el tipo derivado del original).

• El WSDL generado no deberá tener ningún modelo xsd:attribute.• El interceptor debe exponer un WSDL plano (que no tenga modelos xsd:import o wsdl:import).

Una forma posible de crear un interceptor

• Aquí se presenta una forma posible de crear un servicio de interceptor utilizando WindowsCommunication Foundation y Visual Studio. Esta estrategia cumple con las instrucciones mencionadasmás arriba.

• Crear un proyecto de servicio WCF en Visual Studio.• Añadir una referencia de servicio al servicio web Interaction Optimizer concreto de este proyecto.• Exportar el WSDL del servicio web Interaction Optimizer (se puede ejecutar el comando svcutil.exe/t:metadata <url of the hosted Interaction Optimizer service>) cuando se indiqueel comando para hacerlo.

• Crear un xslt que:

• Transforme todas las jerarquías de tipo en planas.• Elimine todos los elementos xsd:attribute (es posible porque los xsd:attributes generados porInteraction Optimizer, actualmente, no se utilizan en ninguna de sus operaciones expuestas).

• Para ver un ejemplo de este xslt, véase el Apéndice.

• Utilizar esteWSDL transformado (generado a partir del paso anterior) para crear un conjunto de clasesproxy (se puede ejecutar el comando svcutil.exe /o:<filename> /l:CS/n:<string,string> <tel nombre del archivo WSDL transformado>. Nótese que la opción /nayuda a asignar espacios de nombres objetivo xsd/wsdl a nombres de espacios clr en código, y estopuede utilizarse para asignar tipos a un solo espacio de nombre homogéneo).

• Añadir este archivo (con las clases generadas) al proyecto de servicio WCF que se ha creado parael interceptor.

• Abrir el archivo en Visual Studio y cambiar los espacios de nombres xml de los tipos generados poralgo distinto de los espacios de nombres xml utilizados por Interaction Optimizer.

• Poner todos los tipos generados bajo un solo espacio de nombre clr (incluidas las clases de servicioy las interfaces).

Portrait IO 5.516

Instrucciones relativas al interceptor

• Buscar el código de la interfaz IIOWebService y eliminar todas las operaciones no deseadas;asegurarse de que esté dotada de un ServiceContract y sus operaciones estén dotadas de un atributoOperationContract (ya deberían estarlo, puesto que se ha generado mediante la utilidad svcutil).

• Eliminar la interfaz IIOWebServiceChannel.• Cambiar el nombre de la clase IOWebServiceClient por algo que tenga significado en este contexto,p. ej. IOWebServiceAdapter (esto hará de clase de implementación del servicio para el serviciodel interceptor y reenviará las llamadas al servicio web Interaction Optimizer real).

• Dotar la clase IOWebServiceAdapter del atributo ServiceBehavior y configurar la propiedadNameSpace de este atributo con el mismo espacio de nombre xml que el de la interfazIIOWebService.

• Escribir la lógica de traducción para transformar los tipos de servicio web Interaction Optimizer en lostipos definidos por el interceptor y viceversa.

• Crear un elemento de extensión de comportamiento que exponga un wsdl plano (es decir, uno queno tenga ningún modelo wsdl:import o xsd:import) del interceptor. El código necesario puedeencontrarse en el Apéndice B.

• Añadir el código de esta clase al proyecto de interceptor.• Construir el proyecto para asegurarse de que todo se compile según lo esperado.• Alojar el servicio de interceptor WCF en un punto de acceso público (p. ej. como un servicio de IISalojado en una máquina virtual en la nube ). Si es posible, deberá colocarse junto con el servicio webInteraction Optimizer.

• Abrir el archivo Web.Config del servicio alojado y añadir la siguiente sección que está en<system.ServiceModel>:

<extensions><behaviorExtensions><add name="WSDLFlatteningExtension"type="MessageTranslator.Extensions.InlineXsdInWsdlBehavior,MessageTranslator.Extensions"/>

</behaviorExtensions></extensions>

• En la sección comportamientos (crear una si no la hay) en <system.ServiceModel>, añadir la siguientesección:

<behaviors><endpointBehaviors><behavior name="WSDLFlatteningBehavior">

<WSDLFlatteningExtension/></behavior>

</endpointBehaviors><serviceBehaviors><behavior name="serviceBehavior"><serviceMetadata httpGetEnabled="true"/>

</behavior></serviceBehaviors>

</behaviors>

• Crear la sección servicio como sigue:

<services><service name="<ServiceImplementationClassName>"

behaviorConfiguration="serviceBehavior"><endpoint address="test" binding="basicHttpBinding"

17Guía de Integración Salesforce.com

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com

contract="<ServiceContractInterfaceName>"bindingNamespace=<BindingNameSpace>

behaviorConfiguration="WSDLFlatteningBehavior"/></service>

</services>

• Asegúrese de que el valor del bindingNamespace introducido en la sección anterior sea el mismoque el introducido en la interfaz de contrato de servicio y la clase de implementación de servicio, esdecir, las tres deberán tener el mismo valor de espacio de nombre (esto es fundamental para que elservicio del interceptor exponga un solo documento WSDL).

• Intentar navegar al archivo .svc para obtener este servicio en un navegador y asegurarse de que lapágina de descripción del servicio se visualice sin ningún error.

• Hacer clic en el enlace del WSDL de este servicio (la página de descripción del servicio deberá tenerun enlace que termine en ?wsdl) y asegurarse de que el WSDL se visualice correctamente (en algunosnavegadores, p. ej. IE 9), es posible que se muestre directamente un diálogo de descarga de archivopara guardar el WSDL). Copiar/descargar el WSDL y guardar el archivo en el sistema de archivoslocal: este es el WSDL que debe cargarse en SalesForce.com para generar los proxies Apex.

Interaction Optimizer con Salesforce.com para elcliente

En esta sección se presentan (mediante el uso de algunas páginas de muestra y componentes deSalesforce) los elementos de alto nivel que deben construirse como parte de una interfaz de cliente enSalesforce.com para consumir el servicio web de interceptor Interaction Optimizer (al que en adelantenos referiremos como servicio de Interaction Optimizer) y mostrar las recomendaciones en una páginaVisualForce. Esto se basa en un código de muestra que puede descargarse enhttps://login.salesforce.com/packaging/installPackage.apexp?p0=04tU00000004j9F. Por favor, consulteel Apéndice para ver un diagrama de clases que ilustra las relaciones entre distintos componentes deSalesforce.

A un nivel alto, deben construirse los siguientes elementos:

Componentes de Visual Force

• RecommendationForSObject.component.

• Actúa como interfaz para interactuar con el objeto de SalesForce actual en contexto.• Expone un atributo para configurar el objeto de SalesForce actual en contexto.• Se añade normalmente como componente en cualquiera de las páginas SalesForceestándar/personalizadas (p. ej. Contrato, Cuenta, etc.).

• RecommendationComponent.component.

• Ofrece la interfaz de usuario para visualizar y registrar las respuestas de las recomencaciones queprovienen de Interaction Optimizer y se muestran en las páginas SalesForce.

Portrait IO 5.518

Interaction Optimizer con Salesforce.com para el cliente

• Se añade normalmente como componente en cualquiera de las páginas SalesForceestándar/personalizadas (p. ej. Contrato, Cuenta, etc.).

• Este enfoque nos permite reutilizar la lógica y la interfaz de usuario para mostrar recomendacionesen cualquier página SalesForce y no solo en la de contactos.

• Este componente configura/accede a los campos y métodos adecuados en su controlador asociadopara pasar/recuperar datos (p. ej. las recomendaciones reales).

Controladores de componentes

• RecommendationForSObject.cls

• Controlador para el componente RecommendationForSObject.component.• Ofrece los campos y accesos o métodos para consultar y configurar el objeto de SalesForce actualen contexto (Contrato, Cuenta, etc.).

• RecommendationComponentCtlr.cls

• Controlador para el componente RecommendationComponent.component.• Expone los campos y métodos que son denominados desde elRecommendationComponent.component para recuperar las recomendaciones y registrar larespuesta de una recomendación. Los datos (introducidos) necesarios para estos métodos se pasana través de la configuración de las propiedades públicas expuestas por el controlador.

• Estos métodos delegan la lógica para obtener recomendaciones o registrar respuestas a una clasede ayuda IOHelper que actúa como contenedor para recurrir al servicio de interceptor de InteractionOptimizer (explicado en una sección anterior) mediante la utilización de las clases proxy de Apex.(Consultar el Apéndice D para ver un código de muestra que ilustra un recurso al servicio paraobtener recomendaciones y registrar la respuesta de una de las recomendaciones devueltas).

• Define y expone una clase pública anidada RecommendationsWrapper que actúa como un objetode transferencia de datos simple para pasar las recomendaciones aRecommendationComponent.component.

• Interactúa con la clase RecommendationForSObject para acceder al objeto SalesForce actual.• El método retrieveRecommendations de esta clase utiliza la información del objeto de SalesForceactual (al que se accede desde la clase RecommendationForSObject) para rellenar los parámetrosnecesarios para solicitar el método GetActions del proxy de servicio de interceptor InteractionOptimizer subyacente. Este método añade las recomendaciones devueltas a una lista de ejemplosde RecommendationsWrapper a la que se accede a través deRecommendationComponent.component para vincular con la interfaz de usuario.

• Aunque gran parte de la información obligatoria para obtener las recomendaciones se pasa en elparámetro de solicitud, los datos que guían el filtrado de las indicaciones devueltas se pasan en elcontexto adicional.

• Se puede acceder a las recomendaciones a través de la interfaz de usuario del componente talcomo se muestra a continuación:

19Guía de Integración Salesforce.com

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com

• <apex:panelBar items="{!Recommendations}" var="a"><apex:panelBarItem label="{!a.CampaignClass} - {!a.LinkText}"><table><tr><td>{!a.ContentHTML}</td><td><button onclick="">Accept</button><button onclick="">Refuse</button><button onclick="">Not Presented</button></td></tr></table></apex:panelBarItem></apex:panelBar>

Nota: Aquí a se refiere a una instancia de RecommendationsWrapper y se accede a la informaciónnecesaria a través de sus propiedades públicas.

La captura de pantalla siguiente muestra una recomendación por vez.

Proxy Entity Wrapper para recomendación

• RecommendationsWrapper.cls.

• Se trata de un objeto de transferencia de datos simple que se utiliza para vincular recomendacionescon la interfaz de usuario de SalesForce.

• Actúa como contenedor para la clase IOWebService_Action subyacente expuesta por el serviciode interceptor de Interaction Optimizer.

• Expone una interfaz más sencilla que IOWebService_Action conmiembros que son relevantes parala interfaz de usuario de SalesForce (p. ej. propiedades para indicaciones de texto, clase de campaña,etc.).

Páginas Visualforce Apex

• Recommendations.page.

• Se utiliza para ver las recomendaciones.• Se incluye en otras presentaciones de objetos estándar (p. ej. Contacto).• Hay que crear una página así para cada página estándar en la que deban mostrarserecomendaciones.

• Contiene los componentes RecommendationComponent.component andRecommendationForSObject.component.

• Configura el atributo SFDCObject del componente RecommendationForSObject con el objeto SFDCasociado de la página de la que forma parte.

Portrait IO 5.520

Proxy Entity Wrapper para recomendación

• El código de la página Visual Force para las recomendaciones (para el contacto en la páginaestándar) tiene el siguiente aspecto:

<apex:page standardController="Contact"extensions="RecommendationContactCntrlr" id="page1"><apex:form id="frm1" ><c: RecommendationComponent SFDCObject="{!Objcontact}" />

</apex:form></apex:page>

Cuando esta página se incluye como parte de la presentación de la página de contacto, la página puedetener el siguiente aspecto:

Extensión del controlador VisualforcePara cada página Visual Force en la que debanmostrarse recomendaciones, hay que crear una extensiónde controlador.

• RecommendationContactCtrlr.cls.

• Extensión para el Contact Controller estándar• El código para esta extensión de controlador puede tener el siguiente aspecto:

public with sharing class RecommendationContactCntrlr{Contact objcontact;public RecommendationContactCntrlr (ApexPages.StandardController

stdController){

objcontact=(Contact)stdController.getRecord();}public RecommendationContactCntrlr (){}public Contact getObjcontact(){return this.objContact;

21Guía de Integración Salesforce.com

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com

}}

Descargar e instalar el código de muestraEn esta sección se ilustran los pasos para descargar el código de muestra en un Sales Force org.existente.

1. Abrir una ventana del navegador y teclear la url del paquete no gestionado:https://login.salesforce.com/packaging/installPackage.apexp?p0=04tU0000000PlHWen la barra de direcciones.

2. En la pantalla de inicio de sesión, introducir los datos de SalesForce org donde deba descargarseel paquete.

3. Después de iniciar sesión, seguir las instrucciones de descarga y aceptar las opciones por defectohasta que se indique que hay que instalar el paquete.

4. Instalar el paquete.5. Ir a Configuración -> Personalizar -> Contactos -> Diseños de página6. Hacer clic en el botón Asignación de presentación de página7. En la pantalla de asignación de diseño de página, hacer clic en el botón Editar asignación.8. Hacer clic en la fila del perfil al que debe añadirse la sección de recomendaciones en el diseño (la

fila deberá aparecer destacada).9. Seleccionar Diseño del contacto para Interaction Optimizer en el menú desplegable Diseño de página

para usar.10. Así se aplicará el diseño.11. Ahora abra cualquiera de los contactos y se mostrarán todas las recomendaciones correspondientes.

Actualizar las clases proxyAunque el paquete ofrece un punto de partida del código de integración que incluye las clases proxyde Apex para recurrir al servicio de interceptor de Interaction Optimizer, en algunos casos puede serdeseable regenerarlos después de instalar el paquete (p. ej. cuando hay un cambio en el WSDL delservicio de interceptor debido a la reconfiguración o al cambio de versión de Interaction Optimizer).Estos son los pasos para modificar el código afectado que utiliza las clases proxy:

1. Cargar el WSDL actualizado en SalesForce (en el org, ir a Configuración/Desarrollar/Clases Apexy hacer clic en el botón Generar desde WSDL, navegar al documento WSDL y hacer clic en el botónAnalizar WSDL. Una vez completado el proceso, hacer clic en Finalizar).

2. Volver a Configuración/Desarrollar/Clases Apex y buscar la clase denominada IOHelper (se puedebuscar haciendo clic en el enlace del rastro para encontrar alfabéticamente el nombre de la clase)y hacer clic en el enlace Editar de este.

3. Modificar el código de esta clase para reflejar las clases proxy recién generadas en todo su código.4. Hacer clic en el botón Guardar. El código deberá guardarse sin ningún error.5. Probar los proxies recién cargados abriendo una página de contacto y asegúrandose de que las

recomendaciones sean devueltas por Interaction Optimizer.

Portrait IO 5.522

Descargar e instalar el código de muestra

Gestionar las respuestas de recomendaciónExisten distintas respuestas posibles que pueden registrarse para una recomendación buscada enInteraction Optimizer. Las opciones posibles también pueden variar según cómo se haya configuradoInteraction Optimizer. A continuación semuestran algunos ejemplos de los valores posibles (disponiblesen la instalación predeterminada de Interaction Optimizer):

• Aplication

• CaptureLead

• Refusal

• TryAgainLater

Algunas de estas opciones (p. ej. Application ) son tratadas como respuestas positivas, otras (p. ej.Refusal) como respuestas negativas y otras (p. ej. TryAgainLater) como respuestas neutrales. El códigode muestra suministrado con este documento utiliza el valor Application (se puede utilizar cualquier otrarespuesta positiva) para indicar la aceptación y Refusal para rechazar una recomendación. En cualquiercaso, la recomendación no es devuelta desde Interaction Optimizer para la siguiente lista derecomendaciones solicitadas para el mismo contacto (es decir, identificador externo). Para registrarcualquier respuesta distinta de estas, el código SalesForce debe pasar el valor de respuesta adecuado(consultar la lista posible de respuestas de recomendación soportadas de la configuración de InteractionOptimizer implementada).

Nota: En el futuro, si el analizador de WSDL de SalesForce soporta la enumeración, estos valorespodrán estar disponibles como parte del proxy Apex generado para eliminar la posibilidad de erroresde validación.

23Guía de Integración Salesforce.com

Capítulo 3: Integración de Interaction Optimizer con Salesforce.com

Capítulo 4Apéndice

En esta sección:

• Fragmentos de XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26• Código InlineXsdInWsdlBehavior.cs . . . . . . . . . . . . . . . . .27• Componentes de Salesforce.com . . . . . . . . . . . . . . . . . . .29• Código Apex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29

Fragmentos de XSLTFragmento de xslt para aplanar tipos de xsd:<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:msxsl="urn:schemas-microsoft-com:xslt"

exclude-result-prefixes="msxsl">

<xsl:output method="xml" indent="yes"/><xsl:template match="@* | node()">

<xsl:copy><xsl:apply-templates select="@* | node()"/>

</xsl:copy></xsl:template>

<!--Remove xsd:attribute elements--><xsl:template match="//xsd:attribute"/><!--Replace hierarchical xsd (xsd:extension) types with flattened ones-->

<xsl:templatematch="//xsd:complexType[xsd:complexContent[xsd:extension[@base]]]">

<xsl:element name=" {name()}"><xsl:copy-of select="@*"/><xsl:element name="xsd:sequence">

<xsl:call-template name="flattenElement"><xsl:with-param name="element" select="." /></xsl:call-template>

</xsl:element></xsl:element>

</xsl:template><xsl:template name="flattenElement">

<xsl:param name="element" /><xsl:for-each select="$element">

<xsl:if test="./xsd:complexContent/xsd:extension[@base]"><xsl:variable name ="baseElementName

"select="substring-after(.//xsd:extension/@base,':')" /><xsl:call-template name="flattenElement">

<xsl:with-param name="element"select="//xsd:complexType[@name=$baseElementName]"/>

</xsl:call-template></xsl:if><xsl:apply-templates

select="descendant::*[name()='xsd:sequence']/child::*" /></xsl:for-each>

</xsl:template></xsl:stylesheet>

Portrait IO 5.526

Fragmentos de XSLT

Código InlineXsdInWsdlBehavior.csCódigo para InlineXsdInWsdlBehavior.cs:using System;using System.Collections.Generic;using System.Linq;using System.Web.Services.Description;using WsdlDescription = System.Web.Services.Description.ServiceDescription;using System.ServiceModel.Description;using System.Xml.Schema;using System.ServiceModel.Configuration;

namespace MessageTranslator.Extensions{

public class InlineXsdInWsdlBehavior : BehaviorExtensionElement,IWsdlExportExtension, IEndpointBehavior

{public void ExportContract(WsdlExporter exporter,

WsdlContractConversionContext context){

//Not Req}

public void ExportEndpoint(WsdlExporter exporter,WsdlEndpointConversionContext context)

{var schemaSet=exporter.GeneratedXmlSchemas;exporter.GeneratedWsdlDocuments.Cast< WsdlDescription >().ToList()

.ForEach(wsdl =>{

var importsList = new List<XmlSchema>();wsdl.Types.Schemas.Cast< XmlSchema >().ToList()

.ForEach(schema =>{

AddImportedSchemas(schema, schemaSet,importsList);

});wsdl.Types.Schemas.Clear();importsList.ForEach(schema =>{

RemoveXsdImports(schema);wsdl.Types.Schemas.Add(schema);

});});

}private void RemoveXsdImports(XmlSchema schema){

for ( var i = 0; i < schema.Includes.Count; i++){

if (schema.Includes[i] is XmlSchemaImport)schema.Includes.RemoveAt(i--);

}}private void AddImportedSchemas(XmlSchema schema,

27Guía de Integración Salesforce.com

Capítulo 4: Apéndice

XmlSchemaSet schemaSet, List <XmlSchema> importsList){

schema.Includes.Cast< XmlSchemaImport >().ToList().ForEach(import =>

{schemaSet.Schemas(import.Namespace).Cast<XmlSchema>().ToList().ForEach(ixsd =>{if (!importsList.Contains(ixsd)){

importsList.Add(ixsd);AddImportedSchemas(ixsd,schemaSet, importsList);

}});

});}public void AddBindingParameters(ServiceEndpoint endpoint,System.ServiceModel.Channels.BindingParameterCollection bindingParameters){

//Not Req}public void ApplyClientBehavior(ServiceEndpoint endpoint,System.ServiceModel.Dispatcher. ClientRuntime clientRuntime){

//Not Req}public void ApplyDispatchBehavior(ServiceEndpoint endpoint,

System.ServiceModel.Dispatcher. EndpointDispatcherendpointDispatcher){

//Not Req}public void Validate(ServiceEndpoint endpoint){

//Not Req}public override Type BehaviorType{

get{

returntypeof(InlineXsdInWsdlBehavior);

}}protected override object CreateBehavior(){

return new InlineXsdInWsdlBehavior ();}

}}

Portrait IO 5.528

Código InlineXsdInWsdlBehavior.cs

Componentes de Salesforce.comDiagrama de clases que representa los componentes de SalesForce:

Código ApexCódigo Apex de muestra para obtener recomendaciones y registrar respuestas para una de lasrecomendaciones devueltas:ProxyServiceClient proxy = new IOProxyServiceClient();//Get recommendations

GetActionsResponse getActionsResp = proxy.GetActions(state, additionalContext,getActionsRequest);

//Record response for a recommendationActions actions = getActionsResp.Output.GetActionsResponse.Actions;IOWebService_Action action1 = actions.get(0);IOWebService_RecordActionResponseRequest actionResp =

29Guía de Integración Salesforce.com

Capítulo 4: Apéndice

new IOWebService_RecordActionResponseRequest();

//SetitsActionDeliveryIdtothesamevalueasthatofthereturnedrecommendation(i.e.action1inthiscase)actionResp.setActionDeliveryId(action1.ActionDeliveryId);actionResp.setResponseType(RefDataMarketingCampaignResponseType.TryAgainLater);//Set other required attributes of actionResp object..

RecordActionResponseResponseresp = proxy.RecordActionResponse(state, actionResp);

Portrait IO 5.530

Código Apex