> For the complete documentation index, see [llms.txt](https://docs-conversational-ai.syntphony.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-conversational-ai.syntphony.com/voice-gateway/evg-connector.md).

# EVG Connector

Voice Gateway

The `eva-evg-connector` is an IVR integration channel for Syntphony Conversational AI.

This guide explains how to set up a project using the `eva-evg-connector`.

For information about creating flows and configuring the IVR commands used by the connector, see [Call properties](https://docs.conversational-ai.syntphony.com/user-guide/voice-gateway/call-properties?utm_source=chatgpt.com).

### Versions <a href="#user-content-versions" id="user-content-versions"></a>

The `eva-evg-connector` is a peer dependency of Syntphony Conversational AI. This provides flexibility when selecting the `eva-evg-connector` client version for the corresponding Syntphony Conversational AI version.

| eva-evg-connector | Syntphony Conversational AI |
| ----------------- | --------------------------- |
| `1.x.x`           | `4.3.x`–current             |

### Requirements <a href="#user-content-requirements" id="user-content-requirements"></a>

To build and run the application, use:

* [JDK 11](https://www.oracle.com/java/technologies/downloads/#java11)
* [Maven 3.8.6](https://maven.apache.org)

### Dependencies <a href="#user-content-dependencies" id="user-content-dependencies"></a>

The external dependencies of this project are:

* [Redis](https://redis.io/docs/)

### Environment variables

Set the following properties to change the default Redis configuration:

```
spring.cache.redis.time-to-live=1800000
spring.cache.type=${CACHETYPE}
spring.redis.host=${REDIS_HOST}
spring.redis.port=${REDIS_PORT}
spring.redis.password=${REDIS_PWD}
spring.redis.ssl=${REDIS_SSL}
```

{% hint style="info" %}
The default value of `spring.cache.redis.time-to-live` is `1800000`. This property is not required when you do not need to change the default value.
{% endhint %}

### Get Started <a href="#user-content-getting-started" id="user-content-getting-started"></a>

Create a Spring Boot Web Maven project and add the `eva-evg-connector` dependency to the `pom.xml` file:

```
<dependency>
    <groupId>com.everis.eva</groupId>
    <artifactId>eva-evg-connector</artifactId>
    <version>1.0.0</version>
</dependency>
```

You can create the Spring Boot project using [Spring Initializr](https://start.spring.io/).

### Configure Maven

Configure `settings.xml` to download the dependency:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
          http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <servers>
        <server>
            <id>artifact-registry-evg</id>

            <configuration>
                <httpConfiguration>
                    <get>
                        <usePreemptive>true</usePreemptive>
                    </get>

                    <head>
                        <usePreemptive>true</usePreemptive>
                    </head>

                    <put>
                        <params>
                            <property>
                                <name>http.protocol.expect-continue</name>
                                <value>false</value>
                            </property>
                        </params>
                    </put>
                </httpConfiguration>
            </configuration>

            <username>_json_key_base64</username>
            <password>&lt;artifact-registry-credential&gt;</password>
        </server>
    </servers>

    <profiles>
        <profile>
            <id>artifact-eva</id>

            <repositories>
                <repository>
                    <id>artifact-registry-evg</id>
                    <url>https://us-east1-maven.pkg.dev/calm-premise-168420/eva-evg</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>repo1</id>
                    <url>https://repo1.maven.org/maven2/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Sonatype Repository</id>
                    <url>https://oss.sonatype.org/content/repositories/releases/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Spring Plugins Repository</id>
                    <url>https://repo.spring.io/plugins-release/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Spring Lib M Repository</id>
                    <url>https://repo.spring.io/libs-milestone/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Hortonworks Repository</id>
                    <url>https://repo.hortonworks.com/content/repositories/releases/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Atlassian Repository</id>
                    <url>https://maven.atlassian.com/content/repositories/atlassian-public/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>JCenter</id>
                    <url>https://jcenter.bintray.com/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>JBossEA Repository</id>
                    <url>https://repository.jboss.org/nexus/content/repositories/ea/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Spring Lib Release Repository</id>
                    <url>https://repo.spring.io/libs-release/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>

                <repository>
                    <id>Apache Releases Repository</id>
                    <url>https://repository.apache.org/content/repositories/releases/</url>

                    <releases>
                        <enabled>true</enabled>
                    </releases>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>

            <pluginRepositories>
                <pluginRepository>
                    <id>repo1</id>
                    <name>repo1</name>
                    <url>https://repo1.maven.org/maven2/</url>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </pluginRepository>

                <pluginRepository>
                    <id>spring-snapshots</id>
                    <name>Spring Snapshots</name>
                    <url>https://repo.spring.io/snapshot</url>

                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>

    <activeProfiles>
        <activeProfile>artifact-eva</activeProfile>
    </activeProfiles>
</settings>
```

#### How to Include Evg Connector <a href="#user-content-how-to-include-evg-connector" id="user-content-how-to-include-evg-connector"></a>

Add the `@EnableEvgConnector` annotation to the main application class:

```
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.everis.eva.evgconnector.annotation.EnableEvgConnector;

@EnableEvgConnector
@SpringBootApplication
public class EvgDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(EvgDemoApplication.class, args);
    }
}
```

### Quickstart

Create a class named `DemoService` that extends `EvgConnectorBase`.

The `ConversationRequest` object is used when calling Syntphony Conversational AI. The parameters sent in this request are described in the example.

The example calls Syntphony Conversational AI to execute a [Welcome Flow](/nlu-agents/nlu-agents/build-your-first-bot.md). For information about configuring the call and its authentication, see [Conversation API](https://docs.conversational-ai.syntphony.com/user-guide/api-docs/api-guidelines/creating-channels-the-conversation-api?utm_source=chatgpt.com).

The call executes a flow, receives a response from Syntphony Conversational AI, and generates IVR commands based on the response.

```
import java.util.List;

import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import com.everis.eva.evgconnector.properties.EvgSettings;
import com.everis.eva.evgconnector.properties.conversation.ConversationAuthProperties;
import com.everis.eva.evgconnector.properties.provider.MicrosoftProvider;
import com.everis.eva.evgconnector.service.EvgConnectorBase;
import com.everis.eva.evgconnector.service.commands.EvgCommand;
import com.everis.eva.evgconnector.service.conversation.ConversationRequest;
import com.everis.eva.evgconnector.service.conversation.ConversationResponse;
import com.everis.eva.evgconnector.service.evg.Evg;

@Service
public class DemoService extends EvgConnectorBase {

    private final EvgSettings evgSettings;

    public DemoService(EvgSettings evgSettings) {
        this.evgSettings = evgSettings;
    }

    @Override
    public Evg start(Evg evg) {

        String evaConversationAPIURL =
            "https://api-<your_eva_instance_label>.eva.bot/eva-broker/"
            + "org/<your_org_uuid>/env/<your_env_uuid>/bot/<your_bot_uuid>/"
            + "channel/<your_channel_uuid>/v1/conversations";

        ConversationRequest conversationRequest =
            createConversationRequest(evg);

        conversationRequest.getContext().put(
            "dnis",
            evg.getTelcoData().getDnis()
        );

        HttpHeaders headers = new HttpHeaders();

        headers.add("LOCALE", "<your_bot_locale>");
        headers.add("OS", "evg");
        headers.add("API-KEY", "<your_api_key>");
        headers.add("USER-REF", evg.getTelcoData().getAni());
        headers.add("BUSINESS-KEY", evg.getTelcoData().getAni());

        ConversationAuthProperties conversationAuthProperties =
            ConversationAuthProperties.builder()
                .keycloakUrl(
                    "https://keycloak-<your_eva_admin_label>.eva.bot/"
                    + "auth/realms/<your_realm_name>/protocol/"
                    + "openid-connect/token"
                )
                .clientId("<your_client_id>")
                .secret("<your_secret>")
                .build();

        ConversationResponse conversationResponse =
            callEva(
                evg,
                evaConversationAPIURL,
                conversationRequest,
                headers,
                conversationAuthProperties
            );

        MicrosoftProvider microsoftProvider =
            MicrosoftProvider.builder()
                .region("<your_region>")
                .subscriptionKey("<your_subscription_key>")
                .language("<your_bot_locale>")
                .build();

        evgSettings.setMicrosoftProvider(microsoftProvider);

        List<EvgCommand> commands =
            createCommands(evg, conversationResponse);

        return createResponse(
            evg,
            commands,
            evgSettings.getFetch()
        );
    }
}
```

#### Test the connector

To process a call, the EVG IVR consumes the endpoint provided by the EVG Connector.

The following request is an example that can be used to test the implementation:

```
{
  "evgCallStatus": "INIT",
  "telcoData": {
    "ani": "<your_ani>",
    "dnis": "<your_dnis>",
    "sipCallId": "sip-call-id",
    "originIp": "ip-example",
    "customerSipDomain": "@exemple.com.br"
  },
  "context": {}
}
```

{% hint style="info" %}
Use this JSON to test your implementation.
{% endhint %}

### **Conversation service**

The following table describes the endpoint used by the EVG IVR:

| Property | Value              |
| -------- | ------------------ |
| Method   | `POST`             |
| URL      | `/conversations`   |
| Type     | `application/json` |

**Request body and response body**

| Name            | Type            | Required                              | Description                                                                                                                                       |
| --------------- | --------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `evgCallStatus` | `EvgCallStatus` | Yes                                   | An enumeration that represents the status of the call.                                                                                            |
| `telcoData`     | `TelcoData`     | Yes                                   | Contains call data, such as the numbers making and receiving the call.                                                                            |
| `context`       | JSON object     | Yes                                   | Helper object used to maintain the call state. It can store data retained during the call, such as the Syntphony Conversational AI `sessionCode`. |
| `commandList`   | `EvgCommand[]`  | Yes, unless `evgCallStatus` is `INIT` | A list of commands that the IVR executes.                                                                                                         |
| `fetch`         | `Fetch`         | No                                    | Defines IVR behavior when it must fetch a page, URL, or JSON resource.                                                                            |

#### **EvgCallStatus**

| Name                | Description                                                         |
| ------------------- | ------------------------------------------------------------------- |
| `INIT`              | Indicates the initial state of the call. This is the first request. |
| `CONTINUE`          | Indicates a call in progress.                                       |
| `USER_DISCONNECTED` | Indicates that the user disconnected the call.                      |
| `IVR_DISCONNECTED`  | Indicates that the IVR disconnected the call.                       |
| `TRANSFERRED`       | Indicates that the IVR disconnected the call.                       |
| `ERROR`             | Indicates an error state.                                           |

#### **TelcoData**

| Name                | Type   | Description                                            |
| ------------------- | ------ | ------------------------------------------------------ |
| `ani`               | String | Calling number.                                        |
| `dnis`              | String | Incoming number.                                       |
| `sipCallId`         | String | Unique call ID generated by the SBC.                   |
| `originIp`          | String | Call source address, corresponding to the SBC address. |
| `customerSipDomain` | String | Domain that identifies the provider.                   |

#### **EvgCommand**

| Name           | Type               | Description                                                 |
| -------------- | ------------------ | ----------------------------------------------------------- |
| `commandOrder` | `int`              | Orders the execution of commands.                           |
| `commandType`  | `EvgCommandEnum`   | Enumeration that represents the type of command to execute. |
| `result`       | `EvgCommandResult` | Result of the executed command.                             |

#### **EvgCommandEnum**

<table data-search="false"><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code>PLAY_AUDIO</code></td><td>Plays audio media. The supported formats are WAV and FLAC.</td></tr><tr><td><code>PLAY_TTS</code></td><td>Indicates the sanitization of text.</td></tr><tr><td><code>PLAY_SILENCE</code></td><td>Plays silence.</td></tr><tr><td><code>VOICE_MENU</code></td><td>Enables the user to interact in the call through voice.</td></tr><tr><td><code>DTMF_MENU</code></td><td>Enables the user to interact in the call through the phone keypad.</td></tr><tr><td><code>DTMF_VOICE_MENU</code></td><td>Enables the user to interact in the call through voice and the phone keypad.</td></tr><tr><td><code>TRANSFER</code></td><td>Indicates that the call will be transferred.</td></tr><tr><td><code>HANGUP</code></td><td>Indicates that the call will be terminated.</td></tr></tbody></table>

#### **EvgCommandResult**

| Name            | Type            | Description                                                               |
| --------------- | --------------- | ------------------------------------------------------------------------- |
| `status`        | `EvgResultEnum` | Enumeration that indicates the execution status of the requested command. |
| `message`       | String          | Contains execution details.                                               |
| `digits`        | String          | User input. The value is populated when the user uses the phone keypad.   |
| `transcription` | String          | User input. The value is populated when the user speaks.                  |

#### **EvgResultEnum**

| Name         | Description                                                                                                                                                                                                         |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SUCCESS`    | Indicates that the audio file or TTS synthesizer request command was queued successfully.                                                                                                                           |
| `ERROR`      | Indicates that an error occurred in the command. More information is available in the error message.                                                                                                                |
| `FILLED`     | Indicates that the user response to the voice or DTMF menu met the configured criteria, such as the correct number of DTMF digits or a successful transcription.                                                    |
| `DISCONNECT` | Indicates that the customer disconnected the call while it was being processed. This usually occurs during menus or transfer requests.                                                                              |
| `NO_INPUT`   | Indicates that the user response did not meet the configured voice or DTMF menu criteria because the user did not enter a DTMF option or speak any words or phrases.                                                |
| `NO_MATCH`   | Indicates that the user response did not meet the configured voice or DTMF menu criteria because the user entered an invalid DTMF length or spoke input that could not be transcribed, although noise was detected. |

#### **Fetch**

| Name                 | Type   | Description                                                                                                                                    |
| -------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `fetchTimeout`       | Long   | Default time, in milliseconds, that the IVR waits for a page or JSON fetch.                                                                    |
| `fetchAudio`         | String | Path to the default audio file used during IVR platform fetch events.                                                                          |
| `fetchAudioDelay`    | Long   | Default delay before the fetch audio starts. This is the time, in milliseconds, that the IVR waits while transitioning and fetching resources. |
| `fetchAudioMinimum`  | Long   | Minimum time, in milliseconds, that the fetch audio plays after it starts, even if the fetch result becomes available.                         |
| `fetchAudioInterval` | Long   | Time interval between fetch-audio loops. The default value is `0`. A value of `-1` prevents the audio from looping.                            |

## Configure DNIS

The following JSON contains the data and configurable properties that must be provided to Syntphony Conversational AI.

The JSON defines the default DNIS configuration, including the Conversation Property configuration for voice providers.

The properties can be modified individually in flows by using the **technical text** field in Answer cells.

See [**Call properties**](/voice-gateway/call-properties.md) for the configurable fields and their reference values, including [TTS (text-to-speech)](/voice-gateway/call-properties.md#tts-configurations) properties, **BargeIn**, **Flush**, [audio ](/voice-gateway/call-properties.md#audio-template)and text [Answer ](/voice-gateway/call-properties.md#text-template)templates,[ Play Silence](/voice-gateway/call-properties.md#play-silence), [DTMF menu](/voice-gateway/call-properties.md#dtmf-menu), [Voice menu](/voice-gateway/call-properties.md#voice-menu), [Transfer](/voice-gateway/call-properties.md#transfer-to-human), [Fetch](/voice-gateway/call-properties.md#fetch), [Default Error Behaviour](/voice-gateway/call-properties.md#default-error-behavior), and [Regional Expressions](/voice-gateway/call-properties.md#synonyms-for-regional-expressions), etcetera.&#x20;

### DNIS configuration JSON

```
{
  "dnis": "913",
  "properties": {
    "tts": {
      "bargeIn": false,
      "flush": false,
      "bargeInOffset": 200,
      "mask": "\u003cspeak xmlns\u003d\u0027http://www.w3.org/2001/10/synthesis\u0027 xmlns:mstts\u003d\u0027http://www.w3.org/2001/mstts\u0027 xmlns:emo\u003d\u0027http://www.w3.org/2009/10/emotionml\u0027 version\u003d\u00271.0\u0027 xml:lang\u003d\u0027en-US\u0027\u003e\u003cvoice name\u003d\u0027pt-BR-FranciscaNeural\u0027\u003e\u003cprosody rate\u003d\u0027-15%\u0027 pitch\u003d\u00270%\u0027\u003e $TEXT \u003c/prosody\u003e\u003c/voice\u003e\u003c/speak\u003e",
      "voiceProvider": "MICROSOFT",
      "microsoftTtsConfig": {
        "region": "brazilsouth",
        "subscriptionKey": "***",
        "language": "pt-BR"
      }
    },
    "audio": {
      "bargeIn": false,
      "flush": false,
      "bargeInOffset": 200
    },
    "playSilence": {
      "time": 50,
      "bargeIn": false,
      "flush": false
    },
    "dtmfMenu": {
      "numOfDigits": 1,
      "timeout": 20000,
      "interDigitTimeout": 3000,
      "termTimeout": 500,
      "termChar": "#"
    },
    "voiceMenu": {
      "sensitivity": 0.01,
      "maxSpeechTimeout": 30000,
      "timeout": 20000,
      "incompleteTimeout": 20000,
      "voiceProvider": "MICROSOFT",
      "microsoftAsrConfig": {
        "region": "brazilsouth",
        "subscriptionKey": "***",
        "language": "pt-BR"
      }
    },
    "transfer": {
      "uui": "evatest",
      "dest": "1234@172.16.0.7"
    },
    "fetch": {
      "fetchTimeout": 45000,
      "fetchAudio": "",
      "fetchAudioDelay": 0,
      "fetchAudioMinimum": 0,
      "fetchAudioInterval": 0
    },
    "defaultErrorBehaviour": {
      "audio": "",
      "tts": "ssml",
      "transfer": false
    },
    "firstConversationRequest": {
      "text": "",
      "code": "%EVA_WELCOME_MSG",
      "entities": {},
      "context": {}
    },
    "conversationProperties": {
      "headers": {
        "API-KEY": "***",
        "OS": "evg",
        "LOCALE": "pt-BR"
      },
      "conversationUrl": "https://api-dev-instance1.eva.bot/eva-broker/org/2fbe99b2-ea98-484f-b392-f649f1844e03/env/f5317429-55bb-4418-a7ca-00f6992388b2/bot/80d9ab14-5374-402a-9a93-6f1dc77f7675/channel/47a77735-d652-4c6c-a283-4d18028a3b18/v1/conversations"
    },
    "conversationAuthProperties": {
      "keycloakUrl": "https://keycloak-dev-admin.eva.bot/auth/realms/everis/protocol/openid-connect/token",
      "secret": "***",
      "clientId": "***"
    },
    "regionalExpressionsFileUrl": "https://***/regional-expressions.json",
    "welcomeTimeout": 5000,
    "conversationTimeout": 30000
  }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs-conversational-ai.syntphony.com/voice-gateway/evg-connector.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
