# Plugin AsteriskS

## About

The plugin provides integration with Asterisk PBX. The application’s users can occupy numbers as operators of a call-center and process incoming calls. There are tel: links generated for performing outgoing calls from SIP clients, history of those has been tracked other process messages together with incoming calls.

## Setup

| You can see (queue Plugin Asterisk) the plugin operation in Demo System.

### Trunk

A SIP Trunk connects your PBX with the rest of the world voice calls network. It must have a phone number(s), which is used for accepting incoming calls, which later forwarded to your PBX’s internal users. That number is also treated as the from for outgoing calls.

To obtain such a trunk, you have to select a SIP Number Provider and configure there a number, connected to your PBX via a trunk. Typically there are have to be defined IP address and port (5060 default for SIP) of the PBX.

For ability to make outgoing calls from your PBX users via the provider there have to be delivered host and port. And sometimes a secret for authentication needs. Ways of self-configuration of these settings differ for providers, in the table below are described for some of them.

#### Novofon

Create a Number: https://my.novofon.ru/vpbx/connecting-numbers

Create a SIP trunk: https://my.novofon.ru/vpbx/sip-trunk

The properties of the trunk, 91.99.128.52 is the IP of the connected PBX:

Connect the number with the trunk:

### PBX

FreePBX is an web-based shell for Asterisk PBX, allowing to configure it with UI. Despite on much more complex configuration, it is still possible to use bare Asterisk, in this case skip the sub-chapters below until AMI.

#### Install

FreePBX 17 can be installed on a dedicated Debian 12 system:

    cd /tmp &&
    wget https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh -O /tmp/sng_freepbx_debian_install.sh &&
    bash /tmp/sng_freepbx_debian_install.sh

| The process takes ~ 20 minutes for 2 CPU VPS with 4 GB RAM

After the script has done, reach the server via HTTP and finish setup there.

| Be sure that at least the SSH access is allowed in Connectivity / Firewall settings

With the SSH access you can always add an IP for accessing the HTTP interface:

    fwconsole firewall trust <IP>

Or just temporary stop the firewall:

    fwconsole firewall stop

#### Users

Create an internal user account with number in Connectivity / Extensions, like shown on the screens below.

| The password field is blurred and shown only when mouse pointer is placed on

The user credentials should be used in a your SIP Client.

#### Trunk

Under Connectivity / Trunks have to be configured Trunk(s) to the external phone network.

#### Route IN

In Connectivity / Inbound Routes is defined the configuration for incoming calls. Among many available options to handle those, they can be forwarded to PBX’s users using Queues.

Here is the simple queue configuration, they can be found later in Application / Queues

Forwarding to only one existing user 333

Usually before forwarding calls to PBX users responds an IVR. Records for that may be uploaded to Admin / System Recordings.

#### AMI

Application Manager Interface (AMI) provides the way for integration with the Plugin. That listens Asterisk events using TCP connection, defined in file `/etc/asterisk/manager.conf`. Change the file in the following way:

    [general]
    enabled = yes
    port = 5038
    bindaddr = 0.0.0.0

    [<AMI_LOGIN>]
    secret = <AMI_SECRET>
    deny = 0.0.0.0/0.0.0.0
    ; allowed networks with masks
    permit = 127.0.0.1/255.255.255.0
    permit = <BGERP_IP>/255.255.255.0
    read = call
    writetimeout = 5000

Where:

- <AMI_LOGIN> and <AMI_SECRET> - connection credentials, used by the Plugin;

- <BGERP_IP> - IP address where your BGERP is running.

To apply the changes call core reload Asterisk CLI command, for FreePBX it can be done in menu Admin / Asterisk CLI.

#### Debug

Use sngrep utility to capture SIP traffic.

### SIP Clients

The clients connect to Asterisk server and used as phone devices.

Client and Platforms | Configuration
--- | ---
https://www.linphone.org/en/getting-started iOS, Android, GNU/Linux, macOS, Windows | Add an Account
https://www.microsip.org/ Windows | Popup menu Edit Account

### Plugin

Make sure the plugin is enabled and append to the configuration:

    asterisk:amiManager.{@inc:cnt}.messageTypeId=<MESSAGE_TYPE_ID>
    asterisk:amiManager.{@cnt}.host=<HOST>
    asterisk:amiManager.{@cnt}.login=<AMI_LOGIN>
    asterisk:amiManager.{@cnt}.pswd=<AMI_SECRET>
    # optional
    # change default AMI port
    #asterisk:amiManager.{@cnt}.port=5038
    # speeds connection process up or solves problem with undetectable version
    #asterisk:amiManager.{@cnt}.version=<VERSION>
    # redefinition of listener, the custom class has to extend the defined below
    #asterisk:amiManager.{@cnt}.listenerClass=<LISTENER_CLASS>

Where:

- <MESSAGE_TYPE_ID> - ID of message type Call, used for persisting calls into the system;

- <HOST> - host where Asterisk with AMI is running;

- <AMI_LOGIN> - AMI login;

- <AMI_SECRET> - AMI password;

- <VERSION> - version string, may be: 'Asterisk 13.0', 'Asterisk 16.0', see: https://github.com/asterisk-java/asterisk-java/blob/master/src/main/java/org/asteriskjava/AsteriskVersion.java;

- <LISTENER_CLASS> - custom listener Java class, extending ru.bgcrm.plugin.asterisk.AmiEventListener

Example:

    asterisk:amiManager.{@inc:cnt}.messageTypeId=1
    asterisk:amiManager.{@cnt}.host=192.168.0.10
    asterisk:amiManager.{@cnt}.login=crm
    asterisk:amiManager.{@cnt}.pswd=234567

#### Outgoing Calls

Calling number for Outgoing Calls can be adapted using JEXL expression, assigned for message type Call with expressionOutNumberPreprocess key. To the JEXL context passed the following variables:

- p or process - object of class ru.bgcrm.model.process.Process, the process;

- pp or processParam - object of class org.bgerp.dao.expression.ParamExpressionObject, process parameters;

- value - object of class ru.bgcrm.model.param.ParameterPhoneValue, phone values.

Sample of such a script, appending calling prefixes depends on some list process parameter value.

    messageType.50.expressionOutNumberPreprocess=<<END
        if (!value) return;

        prefix = null;

        operator = pp.listValueIds(68);
        if (1 =~ operator)
            prefix = "084";
        else if (2 =~ operator)
            prefix = "056";

        if (prefix) {
            prefix = prefix + "7";

            log.debug("prefix: " + prefix + "; value: " + value);

            for (item : value.getItemList()) {
                phone = item.getPhone();
                if (phone.length() == 11)
                    item.setPhone(prefix + phone.substring(1));
            }
        }
    END

#### Debug

Incoming API events are written down to `log/bgerp.debug.log` file. The plugin catches NewStateEvent like this:

    01-24/15:16:49 DEBUG [Asterisk-Java ManagerConnection-216-Reader-0:AsyncEventPump] AmiEventListener - AMI event: org.asteriskjava.manager.event.NewStateEvent[dateReceived='Fri Jan 24 15:16:49 ALMT 2025',privilege='call,all',linkedid='1737713805.909',server=null,calleridname=null,channel='PJSIP/114-000001ec',language='ru',exten='s',calleridnum='114',context='external-context',state='Up',callerid='114',connectedlinenum='8707xxxxxxxx',uniqueid='1737713805.923',timestamp=null,channelstatedesc='Up',systemname=null,connectedlinename=null,sequencenumber=null,priority='1',channelstate='6',accountcode='',systemHashcode=1996251948]

Fields connectedlinenum is treated as FROM and callerid as TO number respectively.

Output of asterisk-java can be enabled in logger configuration.

    # for debugging library
    log4j.logger.org.asteriskjava=DEBUG, filed

## Usage

### Number Occupation

In Messages tool user can occupy an internal SIP number, used by him for connection to Asterisk. The offered number can be configured and even automatically occupied on user login.

If the wanted number is already used by someone else, the confirmation dialog has shown.

For the user, whose number was taken, sent an information news about.

Successfully occupied number does look so. The Release button should be used for releasing the number.

### Process Incoming

After occupation a number by a user, all the accepted calls there must be registered as messages and opened for processing.

To simulate such an incoming call from an arbitrary number, can be used Test button.

| The test area can be hidden by disabling Test incoming call action in user permissions.

### Outgoing Calls

On hover mouse pointer over param phone values the plugin shows popup menu for making outgoing calls.

| The popup menu isn’t shown if parameters were edited after opening process, for this case refresh the process card.

The calls itself are passed to OS application with tel: link.

If the current user’s number is occupied, once a call being responded, it appears in the Message tab of the process.