# Integración con sistemas externos

Para las integraciones con sistemas externos, Optiwe utiliza un webhook. Un webhook es simplemente un end-point que el sistema externo disponibiliza en un servidor para que Optiwe pueda enviar los datos del cliente y la información de la conversación una vez finalizada.&#x20;

El momento donde Optiwe ejecuta el webhook puede configurarse y las opciones aceptadas son:

* Al iniciarse una conversación
* Al finalizar una conversación
* En cierto momento especificado en el flujo conversacional

Para realizar la integración, Optiwe simplemente necesita conocer la URL pública del end-point REST del sistema externo y el end-point necesita aceptar los parámetros json en el body de la request según la definición escrita en este documento.

### Webhook del tipo API REST POST

El sistema externo debe disponibilizar una API en un servidor con el formato definido a continuación. La URL es solo a modo de ejemplo. Optiwe va a requerir la información de la URL final para configurarla en su sistema.

* **URL de ejemplo**: `https://sistema-externo.com/customer/`
* **Verbo HTTP**: `POST`
* **Encabezados de solicitud**:
  * Content-Type: `application/json`
  * Accept: `application/json`
* **Encabezados de respuesta**:
  * Content-Type: `application/json`
* **HTTP status esperado**: `2xx`
* **Cuerpo de solicitud**

```json
{
    "id": int,
    "customer": {
        "id": int,
        "fullName": str,
        "phone": str,
        "email": str,
        "extraData": object
    },
    "customerChannel": {
        "type": ChatChannel
    },
    "ownedByAgentType": Optional[AgentType],
    "ownedBy": Optional[User],   
    "agents": [
        {
            "type": AgentType,
            "assistantUser": Optional[User]       
        },
        {
            "type": AgentType   
        }  
    ],
    "createdOn": datetime("yyyy-mm-ddThh:mm:ss.ffffffZ"),
    "updatedOn": datetime("yyyy-mm-ddThh:mm:ss.ffffffZ"),
    "status": ConversationState,
    "messages": List[Message],
    "labelers": List[Labeler]
}
```

Detalle de campos:

* `customerChannel`: Indica el canal en donde la conversación fue creada. El campo `type` es del tipo `ChatChannel` y los posibles valores son:&#x20;
  * `WHATSAPP`&#x20;
  * `FACEBOOK`
  * `OPTIWE_CHAT`
  * `INSTAGRAM`
  * `FACEBOOK_COMMENT`
  * `INSTAGRAM_COMMENT`.
* `ownedByAgentType` : Campo del tipo `Optional[`AgentType`]`. Las conversaciones pueden tener un agente asignado, en dicho caso este campo esta presente. Los posibles valores que toma son:&#x20;
  * `ASSISTANT`: Indica que un agente humano tiene asignada la conversación.
  * `FACEBOOk_CHAT_BOT`: Indica que un chatbot de Facebook tiene asignada la conversación.
  * `INSTAGRAM_CHAT_BOT`: Indica que un chatbot de Instagram tiene asignada la conversación.
  * `OPTIWE_CHAT_BOT`: Indica que un chatbot de Chat Web tiene asignada la conversación.
  * `WHATSAPP_CHAT_BOT`: Indica que un chatbot de Whatsapp tiene asignada la conversación.
* `ownedBy`: Campo del tipo `Optional[User]`. Cuando la conversación está asignada a un agente humano, este campo esta presente y toma el siguiente valor.

```
{
       "firstName": str, 
       "lastName": str,
       "email": str
}
```

* `agents`: Una lista con todos los agentes que participaron de la conversación. En el caso de que un agente humano haya participado de la conversación , se especifica el campo `assistantUser` cuyo tipo es `Optional[User]`.
* `status`: Campo del tipo `ConversationState`. Indica el estado de la conversación. Los posibles valores son `ACTIVE`, `ENDED`, `INIT_BY_AGENT`.
* `messages:` Campo del tipo `List[Message]`. Especifica todos los mensajes ocurridos en la conversación. A continuación podemos ver un detalle de los valores que puede tomar.

### Generacion deep link

En base al `id` de la conversación es posible generar un link para abrir la misma directamente en el agente. Este link tiene el formato:

```
https://agent.optiwe.com/chat/<chatId>/
```

Ejemplo: para la conversación con `id=123` el link seria `https://agent.optiwe.com/chat/123/`

Para el caso donde no existe un chat con el `id` seleccionado, la interfaz mostrara un mensaje indicando que no existe la conversación.

**Mensajes**

A continuación podemos ver un detalles de los tipo de mensajes.

```
{
    "messageFrom": UserChatType,
    "messagePayload": object,     
    "createdOn": datetime("yyyy-mm-ddThh:mm:ss.ffffffZ"),
    "updatedOn": datetime("yyyy-mm-ddThh:mm:ss.ffffffZ"),
    "assistantUser": Optional[User]
}
```

* `messageFrom`: Campo del tipo UserChatType. Los posibles valores que toma son:
  * `END_USER`: Especifica que el mensaje es del usuario en el canal `OPTIWE_CHAT`.
  * `FACEBOOK_MESSENGER_END_USER`: Especifica que el mensaje es del usuario en el canal `FACEBOOK`.
  * `INSTAGRAM_END_USER`: Especifica que el mensaje es del usuario en el canal `INSTAGRAM`.
  * `WHATSAPP_END_USER`: Especifica que el mensaje es del usuario en el canal `WHATSAPP`.
  * `FACEBOOK_COMMENT_END_USER`: Especifica que el mensaje es del usuario en el canal `FACEBOOK_COMMENT`.
  * `INSTAGRAM_COMMENT_END_USER`: Especifica que el mensaje es del usuario en el canal `INSTAGRAM_COMMENT`.
  * `ASSISTANT`: Especifica que el mensaje es de un agente humano.
  * `DEFAULT_ASSISTANT`: Especifica que el mensaje es del agente default. Por ejemplo cuando se envía una plantilla de Whatsapp, el owner del mensaje es el `DEFAULT_ASSISTANT.`
  * `FACEBOOK_CHAT_BOT`: Especifica que el mensaje es de un chatbot para el canal `FACEBOOK`.
  * `INSTAGRAM_CHAT_BOT`: Especifica que el mensaje es de un chatbot para el canal `INSTAGRAM`.
  * `OPTIWE_CHAT_BOT`: Especifica que el mensaje es de un chatbot para el canal `OPTIWE_CHAT`.
  * `WHATSAPP_CHAT_BOT`: Especifica que el mensaje es de un chatbot para el canal `WHATSAPP`.
* `messagePayload`: Especifica el contenido del mensaje. Para mensajes del tipo texto el contenido es el siguiente:

```
{
    "text": str
}
```

* `assistantUser`: Objeto del tipo `Optional[User]`. Cuando el mensaje es de un agente humano este campo especifica los datos del agente que envió el mensaje.

### **Etiquetas**

Las conversaciones pueden ser etiquetadas ya sea automáticamente por un chatbot o manualmente por un agente. En este caso, la conversación tendrá la información de las etiquetas asignadas a la conversación en el campo \`labelers\`.&#x20;

El campo \`labelers\` es una lista de objetos del tipo \`Labeler\` el cual se detalla a continuación:

```
{
    "conversationLabel": {
        "id": Int,
        "value": str,
    },
    "labeledBy": "ASSISTANT" | "*_CHAT_BOT"
}
```

**Campos adicionales de clientes**

El atributo `extraData` de `customer` contiene propiedades dinámicas. Estas propiedades se cargan dinámicamente a partir del diseño de conversación con el cual está configurado el chatbot.

Por ejemplo es posible configurar al chatbot para que pida una ubicación, en tal caso, los datos a recibir son:

```json
{
   ...,
   "customer": {
       "fullName": "Nombre completo del cliente",
       "phone": "Numero de teléfono del cliente",
       "email": "Email del cliente",
       "extraData": {
           "location": {
               "lat": float,
               "lng": float,
               "city": str,
               "state": str,
               "country": str
           }
       }
   }
}
```

El chatbot puede estar configurado para solicitar multiple datos. Por ejemplo si además de la ubicación se solicita un producto de interés, los datos a recibir pueden ser:

```json
{
   ...,
   "customer": {
       "fullName": "Nombre completo del cliente",
       "phone": "Numero de teléfono del cliente",
       "email": "Email del cliente",
       "extraData": {
           "location": {
               "lat": float,
               "lng": float,
               "city": str,
               "state": str,
               "country": str
           },
          "producto": str
       }
   }
}
```

### Integracion con Salesforce

Optiwe puede integrarse con la plataforma Salesforce de manera muy sencilla. Para realizar la conexión, dirigirse a la vista de **Configuración** y dentro de la misma a la solapa **Integraciones**. Allí encontrará una tarjeta de Salesforce donde deberá introducir los datos y credenciales de su App de Salesforce con la cual desea integrarse.

Los campos requeridos son:

* Client ID: Dentro de la App de Salesforce es el identificador alfanumérico que figura bajo el nombre "Consumer Key"
* Client Secret: Dentro de la App de Salesforce es el identificador alfanumérico que figura bajo el nombre "Consumer Secret"
* Usuario: El usuario utilizado para acceder a la App de Salesforce.
* Contraseña: Contraseña utilizada para acceder a la App de Salesforce.

<figure><img src="/files/sPh2CjzoidhQ37O0IcSv" alt=""><figcaption><p>Tarjeta de conexión con Salesforce</p></figcaption></figure>

Una vez ingresados los datos, hacer click en el botón "Conectar". Si la conexión se realizó correctamente, se podrá observar un tilde verde en la parte superior. En caso contrario, aparecerá un mensaje de error avisando que la conexión no pudo realizarse y se observará un signo de exclamación amarillo en la integración.

Si el espacio de trabajo cuenta con la integración con Salesforce conectada, los Webhooks que se envíen desde Optiwe tendrán el encabezado **Authorization** cargado con el valor **OAuth ACCESS\_TOKEN**. Para más información sobre el envío de Webhooks, dirigirse a la sección [**Notificaciones por webhook**](/developers/notificaciones-por-webhook.md) dentro del manual.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://soporte.optiwe.com/developers/integracion-con-sistemas-externos.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
