|
|
| (9 intermediate revisions by the same user not shown) |
| Line 1: |
Line 1: |
| == Important: Correct API Endpoint Path == | | = VoIPmonitor Web API = |
|
| |
|
| All API requests MUST be sent to the correct endpoint path:
| | This page documents VoIPmonitor's Web APIs for programmatic access to CDR data, recordings, active calls, and system functions. |
|
| |
|
| * '''Correct:''' <code>/voipmonitor/php/api.php</code>
| | == Overview == |
| * '''Incorrect:''' <code>/voipmonitor/api.php</code>
| |
|
| |
|
| Using the wrong path (missing the <code>/php/</code> directory) will cause API calls to fail with various errors.
| | <kroki lang="mermaid"> |
| | %%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 30}}}%% |
| | flowchart LR |
| | subgraph Client |
| | A[Application] |
| | end |
| | subgraph API["API Endpoints"] |
| | B["/php/api.php"] |
| | C["/php/model/sql.php"] |
| | end |
| | subgraph Tasks |
| | E[getVoipCalls] |
| | F[getVoiceRecording] |
| | G[getPCAP] |
| | H[listActiveCalls] |
| | I[getShareURL] |
| | end |
| | A -->|user/password| B |
| | A -->|Session cookie| C |
| | B --> E & F & G & H & I |
| | </kroki> |
|
| |
|
| If your VoIPmonitor GUI is installed in the default web root (/var/www/html), use:
| | {| class="wikitable" |
| curl -X POST 'http://yourserver/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD'
| | |- |
| | ! API !! Endpoint !! Authentication !! Use Case |
| | |- |
| | | '''HTTP API 2''' || <code>/php/api.php</code> || user/password params || CDR queries, recordings, PCAP, active calls |
| | |- |
| | | '''CDR HTTP API''' || <code>/php/model/sql.php</code> || Session cookie || Advanced CDR filtering with GUI filters |
| | |} |
|
| |
|
| If using a subdirectory like /demo:
| | {{Warning|1='''Correct path is critical:''' Always use <code>/php/api.php</code> (not <code>/api.php</code>). Missing the <code>/php/</code> directory causes "action parameter missing" errors.}} |
| curl -X POST 'http://yourserver/demo/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD'
| |
|
| |
|
| == Custom Login == | | == HTTP API 2 == |
|
| |
|
| VoIPmonitor supports custom authentication mechanisms (such as LDAP) via the <code>custom_login.php</code> script. This script intercepts login requests from the web GUI and allows you to validate credentials against external systems.
| | Preferred API for programmatic access. Requests via HTTP POST or GET to <code>/php/api.php</code>. |
|
| |
|
| '''Important:''' Web API (HTTP API 2) authentication uses local VoIPmonitor database credentials directly and does NOT use <code>custom_login.php</code> or LDAP authentication. API requests submit <code>user</code> and <code>password</code> parameters that are validated against the local database.
| | === Authentication === |
|
| |
|
| === LDAP Example ===
| | Include <code>user</code> and <code>password</code> parameters in every request: |
|
| |
|
| Complete LDAP example available in GUI directory: scripts/ldap_custom_login_example.php.
| | <syntaxhighlight lang="bash"> |
| | curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms=...' |
| | </syntaxhighlight> |
|
| |
|
| Ensure php-ldap package (or equivalent) is installed on the OS hosting the LDAP script.
| | {{Note|1=API authentication uses local VoIPmonitor database credentials. It does NOT use LDAP or custom_login.php.}} |
|
| |
|
| ==== Troubleshooting LDAP Login Issues ====
| | '''Rate Limiting:''' Enable in GUI > Settings > System Configuration > "API maximal concurrent connections". |
|
| |
|
| If LDAP authentication is working for the local admin user but failing for non-admin users, you can debug the script manually from the command line to isolate LDAP connectivity issues.
| | === getVoipCalls === |
|
| |
|
| ===== Step 1: Enable Debug Mode for CLI Testing =====
| | Retrieve CDR records by search criteria. |
|
| |
|
| Edit the <code>custom_login.php</code> file and **uncomment the debug block** at the top of the script (if present):
| | '''Parameters:''' |
| | {| class="wikitable" |
| | |- |
| | ! Parameter !! Description |
| | |- |
| | | <code>startTime</code> || Calls starting >= this time (required) |
| | |- |
| | | <code>startTimeTo</code> || Calls starting <= this time |
| | |- |
| | | <code>callEnd</code> || Calls ending <= this time |
| | |- |
| | | <code>caller</code> / <code>called</code> || Caller/called number |
| | |- |
| | | <code>callId</code> || SIP Call-ID |
| | |- |
| | | <code>cdrId</code> || Database ID |
| | |- |
| | | <code>id_sensor</code> || Sensor number |
| | |- |
| | | <code>msisdn</code> || Match caller OR called (instead of AND) |
| | |- |
| | | <code>onlyConnected</code> || <code>1</code> = only answered calls |
| | |- |
| | | <code>customHeaders</code> || Comma-separated custom header names to return |
| | |} |
|
| |
|
| <pre>
| | '''Examples:''' |
| # debug for manual run
| |
| if (!function_exists('debug_log')) {
| |
| function debug_log($txt) {
| |
| echo $txt . "\n";
| |
| }
| |
| }
| |
| # uncomment next line for test with manual run from command line (php SCRIPTNAME)
| |
| custom_login('testuser', 'testpass');
| |
| </pre>
| |
|
| |
|
| ===== Step 2: Run Script Manually ===== | | <syntaxhighlight lang="bash"> |
| | # HTTP GET - by time range and caller |
| | curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms={"startTime":"2024-01-01","startTimeTo":"2024-01-31","caller":"123456"}' |
|
| |
|
| Execute the script directly from the command line:
| | # HTTP POST - by Call-ID |
| | echo '{"task":"getVoipCalls","user":"USER","password":"PASSWORD","params":{"startTime":"2024-01-01","callId":"abc123"}}' | curl -X POST -d @- http://server/php/api.php |
|
| |
|
| <syntaxhighlight lang="bash">
| | # With custom headers |
| cd /var/www/html/scripts/
| | curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ |
| php custom_login.php
| | --data-urlencode 'params={"startTime":"2024-01-01","caller":"123","customHeaders":"X-Custom-Header"}' |
| </syntaxhighlight> | | </syntaxhighlight> |
| | '''Response fields:''' |
| | {| class="wikitable" |
| | |- |
| | ! Field !! Description |
| | |- |
| | | <code>cdrId</code> || Database CDR ID |
| | |- |
| | | <code>id_sensor</code> || Sensor ID |
| | |- |
| | | <code>calldate</code> / <code>callend</code> || Call start/end time |
| | |- |
| | | <code>duration</code> / <code>connect_duration</code> || Total / connected duration |
| | |- |
| | | <code>caller</code> / <code>called</code> || Caller/called numbers |
| | |- |
| | | <code>sipcallerip</code> / <code>sipcalledip</code> || SIP endpoint IPs |
| | |- |
| | | <code>codec_a</code> / <code>codec_b</code> || Audio codecs |
| | |- |
| | | <code>lastSIPresponseNum</code> || '''(New in 2026.1)''' Final SIP response code (e.g., 200, 404, 503) |
| | |- |
| | | <code>callId</code> || SIP Call-ID |
| | |} |
| | === getVoiceRecording === |
|
| |
|
| This will test the script with the hardcoded 'testuser' credentials and output any connection failure messages directly to the console.
| | Download audio recording (WAV format). |
|
| |
|
| ===== Step 3: Check LDAP Server Configuration ===== | | '''Parameters:''' |
| | {| class="wikitable" |
| | |- |
| | ! Parameter !! Description |
| | |- |
| | | <code>cdrId</code> || Database CDR ID (preferred) |
| | |- |
| | | <code>callId</code> || SIP Call-ID |
| | |- |
| | | <code>calldate</code> || Date hint (default: today) |
| | |- |
| | | <code>zip</code> || <code>true</code> = return ZIP archive |
| | |- |
| | | <code>ogg</code> || <code>true</code> = return OGG format |
| | |- |
| | | <code>saveaudio_afterconnect</code> || <code>"yes"</code> = audio only after call connect |
| | |} |
|
| |
|
| Verify the LDAP server configuration in your script:
| | '''Examples:''' |
| | |
| * Check the <code>$ldapsrvs</code> variable contains correct LDAP server IP addresses
| |
| * Verify the LDAP server ports are correct and accessible
| |
| * Ensure network connectivity exists from the VoIPmonitor server to the LDAP endpoints
| |
| | |
| If the CLI test shows connection failures, verify network connectivity:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| telnet <ldap_server_ip> <ldap_port>
| | # By CDR ID |
| # or | | curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":12345}' > call.wav |
| nc -zv <ldap_server_ip> <ldap_port>
| |
| </syntaxhighlight>
| |
| | |
| ===== Step 4: Verify Required Dependencies ===== | |
|
| |
|
| Ensure the LDAP PHP extension is installed:
| | # By Call-ID |
| | curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"abc123"}' > call.wav |
|
| |
|
| <syntaxhighlight lang="bash">
| | # Multiple recordings (returns ZIP) |
| # Debian/Ubuntu
| | echo '{"task":"getVoiceRecording","user":"USER","password":"PASSWORD","params":{"cdrId":[6,7]}}' | php api.php > calls.zip |
| php -m | grep ldap
| |
| sudo apt-get install php-ldap
| |
| | |
| # CentOS/RHEL
| |
| php -m | grep ldap | |
| sudo yum install php-ldap
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ===== Step 5: Check User Mapping ===== | | === getPCAP === |
|
| |
|
| The <code>custom_login</code> function must return a valid array containing a required numeric unique identifier (<code>id</code>). If your script successfully authenticates against LDAP but users cannot log in, verify:
| | Download PCAP file. Automatically merges multiple legs and returns ZIP if needed. |
|
| |
|
| 1. The user exists in the VoIPmonitor local database (<code>users</code> table)
| | '''Parameters:''' |
| 2. The script correctly queries the local database to retrieve the user's ID
| | {| class="wikitable" |
| 3. The returned array includes the <code>id</code> field
| | |- |
| | ! Parameter !! Description |
| | |- |
| | | <code>cdrId</code> || Database CDR ID |
| | |- |
| | | <code>callId</code> || SIP Call-ID |
| | |- |
| | | <code>cidInterval</code> || Time window (seconds) to search for matching Call-ID |
| | |- |
| | | <code>cidMerge</code> || <code>true</code> = merge multiple legs |
| | |- |
| | | <code>zip</code> || <code>true</code> = force ZIP output |
| | |} |
|
| |
|
| Create users in the GUI (Settings → Users) with the same usernames as in your LDAP directory if you require local user record mapping.
| | '''Examples:''' |
|
| |
|
| ===== Step 5.5: Ensure Unique User IDs for Individual Settings ===== | | <syntaxhighlight lang="bash"> |
| | # By CDR ID |
| | curl 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"cdrId":"12345"}' > call.pcap |
|
| |
|
| '''Critical:''' Each LDAP user must return a '''unique numeric identifier''' in the <code>id</code> field. If multiple LDAP users return the same <code>id</code>, they will share ALL user settings including timezone, dashboard preferences, and other GUI customizations. | | # By Call-ID with merge |
| | curl -G 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \ |
| | --data-urlencode 'params={"callId":"abc123","cidInterval":60,"cidMerge":true}' |
| | </syntaxhighlight> |
|
| |
|
| ===== Symptoms of Non-Unique IDs =====
| | {{Tip|Use <code>curl -G --data-urlencode</code> for complex JSON params to avoid encoding issues.}} |
|
| |
|
| If your LDAP users see settings changing unexpectedly or appearing to be shared (e.g., changing timezone for one user affects all users), your script is likely returning the same <code>id</code> for all users.
| | === listActiveCalls === |
| | |
| ===== Extracting Unique IDs from LDAP ===== | |
| | |
| To ensure each LDAP user has a unique identity, retrieve a unique identifier from your LDAP directory such as <code>uidnumber</code>:
| |
| | |
| <pre>
| |
| <?php
| |
| function custom_login($user, $password) {
| |
| // Connect to LDAP server and authenticate $user/$password
| |
| $connect = ldap_connect('ldap://your-ldap-server');
| |
| ldap_bind($connect, $ldap_user, $ldap_password);
| |
|
| |
|
| // Search for the user
| | Get currently active calls from sensor. |
| $search = ldap_search($connect, $dn, "(uid=$user)", array('uidnumber', 'cn'));
| |
| $res_id = ldap_get_entries($connect, $search);
| |
|
| |
|
| // Extract unique identifier from LDAP
| | '''Parameters:''' <code>sensorId</code> (optional), <code>callId</code> (optional) |
| $userIdUniqueNum = 0; // Default invalid ID that will cause login fail
| |
| if (isset($res_id[0]['uidnumber'][0])) {
| |
| // Use LDAP uidnumber as unique identifier
| |
| $userIdUniqueNum = (int)$res_id[0]['uidnumber'][0];
| |
| } else if (isset($res_id[0]['cn'][0])) {
| |
| // Fallback: use CRC hash of cn as unique ID
| |
| $userIdUniqueNum = crc32($res_id[0]['cn'][0]);
| |
| }
| |
| | |
| return(array(
| |
| 'username' => $user,
| |
| 'is_admin' => false,
| |
| 'id' => $userIdUniqueNum, // MUST be unique for each user!
| |
| ));
| |
| }
| |
| ?>
| |
| </pre>
| |
| | |
| '''Common Mistakes to Avoid:''' | |
| | |
| * '''Hardcoded ID:''' Returning a constant like <code>'id' => 1</code> for all users (everyone shares settings)
| |
| * '''Missing ID:''' Omitting the <code>id</code> field entirely (login will fail)
| |
| * '''String ID:''' Returning a username string instead of a number (ID must be numeric)
| |
| * '''Non-numeric ID:''' Using <code>uid</code> string instead of <code>uidnumber</code> integer
| |
| | |
| ===== Testing Unique ID Logic =====
| |
| | |
| Verify that different users return different IDs by running your script manually:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| cd /var/www/html/scripts/
| | curl 'http://server/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD¶ms={"sensorId":"1"}' |
| PHP_USER=user1 php -r 'require "custom_login.php"; var_dump(custom_login("user1", "test"));'
| |
| PHP_USER=user2 php -r 'require "custom_login.php"; var_dump(custom_login("user2", "test"));'
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Ensure the <code>["id"]</code> values differ between users.
| | {{Note|1=IP addresses in response are integers. Convert with <code>INET_NTOA()</code> in MySQL or equivalent in your code.}} |
|
| |
|
| ===== Step 6: LDAP Users Cannot View CDRs Despite Being Assigned to Groups ===== | | === handleActiveCall === |
|
| |
|
| If LDAP users can authenticate successfully but cannot view CDRs even though they are assigned to groups with the correct permissions in the GUI, the issue is likely caused by the <code>is_admin</code> flag in your <code>custom_login.php</code> return array.
| | Pause/unpause RTP recording on active call. |
|
| |
|
| When <code>is_admin</code> is set to <code>false</code> (the default recommended setting), VoIPmonitor applies the group permissions from the user's local database record. However, if your script incorrectly includes <code>is_admin</code> with any value (even <code>false</code> itself), it may interfere with group-based permission inheritance depending on your specific configuration.
| | '''Parameters:''' |
| | * <code>sensorId</code> - Sensor number |
| | * <code>command</code> - <code>pausecall</code> or <code>unpausecall</code> |
| | * <code>callRef</code> - Call reference from listActiveCalls |
|
| |
|
| To fix this issue:
| |
|
| |
| 1. Ensure your script returns the correct <code>id_group</code> value that matches the group assigned in the GUI Users & Audit section.
| |
|
| |
| 2. Set <code>is_admin</code> to <code>false</code> (or omit it entirely to use default values) to allow group permissions to be applied correctly:
| |
| <pre>
| |
| return(array(
| |
| 'username' => $user,
| |
| 'is_admin' => false, // Allows group permissions to be applied
| |
| 'id' => $userIdUniqueNum,
| |
| 'id_group' => $groupIdNum, // Must match GUI group ID
| |
| // ... other parameters
| |
| ));
| |
| </pre>
| |
|
| |
| 3. Debug the <code>$groupIdNum</code> variable by running your script manually from the command line:
| |
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| cd /var/www/html/scripts/
| | curl 'http://server/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD¶ms={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}' |
| php custom_login.php
| |
| </syntaxhighlight> | | </syntaxhighlight> |
| Check the debug output to verify that <code>$groupIdNum</code> is being assigned the correct integer value before the return statement.
| |
|
| |
|
| 4. Implement a fallback mechanism for users without a valid role to prevent login failures. For example:
| | === getShareURL === |
| <pre>
| |
| if ($groupIdNum === 0){
| |
| debug_log("User $user does not have valid permissions to login, setting the group 1 with low permissions");
| |
| $groupIdNum = 1;
| |
| }
| |
| </pre>
| |
| This ensures users without group mappings can still log in with restricted access rather than being completely blocked.
| |
|
| |
|
| === File Being Automatically Deleted (Antivirus Protection) ===
| | Generate public shareable link for a CDR. |
|
| |
|
| ==== Issue Overview ==== | | '''Parameters:''' |
| | {| class="wikitable" |
| | |- |
| | ! Parameter !! Description |
| | |- |
| | | <code>callId</code> or <code>cdrId</code> || Call identifier |
| | |- |
| | | <code>cidInterval</code> || Time window for Call-ID search |
| | |- |
| | | <code>rtp</code> || <code>true</code> = include RTP data |
| | |- |
| | | <code>sip_history</code> || <code>true</code> = SIP history only (no RTP) |
| | |- |
| | | <code>anonIps</code> || <code>true</code> = anonymize IPs |
| | |- |
| | | <code>validDays</code> || Link validity in days |
| | |} |
|
| |
|
| If your <code>custom_login.php</code> file or any GUI directory scripts are being automatically deleted from the system, this is caused by the **VoIPmonitor GUI antivirus security scanner**. The scanner proactively searches for malicious patterns in custom PHP files and automatically removes files it identifies as potential threats.
| | <syntaxhighlight lang="bash"> |
| | | curl 'http://server/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"abc123","rtp":true,"validDays":15}' |
| The antivirus primarily triggers on:
| |
| * PHP functions that execute shell commands, such as <code>shell_exec()</code>, <code>exec()</code>, <code>system()</code>, <code>passthru()</code>, or <code>popen()</code>
| |
| * Suspicious code patterns that resemble backdoor scripts or PHP webshells
| |
| * Code that attempts to interact with the system shell beyond the expected GUI usage
| |
| | |
| ==== Solution 1: Disable Antivirus ==== | |
| | |
| The fastest solution is to disable the antivirus scanner for your VoIPmonitor GUI installation.
| |
| | |
| Edit the <code>system_configuration.php</code> file (located in <code><GUI_INSTALL_DIR>/config/system_configuration.php</code>) and add this line:
| |
| | |
| <syntaxhighlight lang="php">
| |
| // File location: ./gui/config/system_configuration.php
| |
| define('DISABLE_ANTIVIRUS', true);
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| After adding this line, the antivirus scanner will be disabled and your custom scripts will not be deleted.
| | === reportSummary === |
|
| |
|
| '''Note:''' Disabling antivirus removes an additional security layer. Only do this if your GUI is running in a trusted environment with restricted access (e.g., behind a firewall, VPN-only access).
| | Generate pre-configured summary report as image or JSON. |
|
| |
|
| ==== Solution 2: Move Shell Commands to External File (Recommended) ==== | | {{Warning|1=Reports must be created in '''GUI → Reports → Daily Report''' BEFORE using the API. The <code>report_name</code> parameter must match the report's Description field.}} |
|
| |
|
| To maintain antivirus protection while using custom shell commands in your login script, move the shell execution code to an external PHP file located outside the web directory and include it from your <code>custom_login.php</code>.
| | '''Parameters:''' |
| | | * <code>report_name</code> - Description field from GUI report |
| ===== Step 1: Create External Script Outside Web Root =====
| | * <code>datetime_from</code> / <code>datetime_to</code> - Date range |
| | | * <code>json</code> - <code>true</code> = return JSON instead of image |
| Create a new PHP file in a directory outside <code><GUI_INSTALL_DIR></code>:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| # Example: Create file in /opt/voipmonitor-custom/
| | curl 'http://server/php/api.php?task=reportSummary&user=USER&password=PASSWORD¶ms={"report_name":"Daily Summary","datetime_from":"2024-01-01","datetime_to":"2024-01-31"}' |
| mkdir -p /opt/voipmonitor-custom
| |
| nano /opt/voipmonitor-custom/ldap_check.php
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ===== Step 2: Move Shell Command Code to External File ===== | | === Other Tasks === |
| | |
| <code>/opt/voipmonitor-custom/ldap_check.php</code>:
| |
| <syntaxhighlight lang="php">
| |
| <?php
| |
| // This file contains shell_exec calls that would trigger antivirus
| |
| // It is safe here because it's outside the web directory and will not be scanned
| |
| | |
| function check_ldap_connectivity($server) {
| |
| $output = shell_exec("ping -c 1 -W 1 $server 2>&1");
| |
| return $output;
| |
| }
| |
|
| |
|
| function run_custom_checks() {
| | {| class="wikitable" |
| $result = exec("/usr/local/bin/custom-auth-check", $output, $return_var);
| | |- |
| return array(
| | ! Task !! Description |
| 'output' => $output,
| | |- |
| 'return_var' => $return_var
| | | <code>listCdrIds</code> || List CDR IDs with basic info. Params: <code>offset</code>, <code>size</code> |
| );
| | |- |
| }
| | | <code>getAudioGraph</code> || Get spectrogram/waveform image. Params: <code>cdrId</code>, <code>type</code> (S/P/ALL), <code>side</code> (L/R) |
| ?>
| | |} |
| </syntaxhighlight> | |
|
| |
|
| ===== Step 3: Include External Script in custom_login.php ===== | | == CDR HTTP API == |
|
| |
|
| <code><GUI_INSTALL_DIR>/scripts/custom_login.php</code>:
| | Session-based API using GUI filter parameters. Requires login first. |
| <syntaxhighlight lang="php">
| |
| <?php
| |
| // Safe to include - no direct shell commands in this file
| |
| require_once('/opt/voipmonitor-custom/ldap_check.php');
| |
|
| |
|
| function custom_login($user, $password) {
| | === Authentication === |
| debug_log('custom_login');
| |
|
| |
|
| // Example: Check LDAP server connectivity using external function
| | <syntaxhighlight lang="bash"> |
| $ping_result = check_ldap_connectivity('ldap.example.com');
| | # Step 1: Login and get session |
| | curl -X POST 'http://server/php/model/sql.php?module=bypass_login&user=USER&pass=PASSWORD' |
| | # Returns: {"SID":"abc123...","cookie_name":"PHPSESSID","success":true} |
|
| |
|
| // Example: Run custom authentication checks
| | # Step 2: Use session cookie for requests |
| $check = run_custom_checks();
| | curl -X POST --cookie "PHPSESSID=abc123..." \ |
| | | 'http://server/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2024-01-01T00:00:00&fcaller=123' |
| return(array(
| |
| 'username' => $user,
| |
| 'is_admin' => false,
| |
| 'id' => $userIdUniqueNum
| |
| ));
| |
| }
| |
| ?>
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ==== Summary ==== | | {{Note|1=If GUI is in subdirectory (e.g., <code>/demo</code>), cookie name changes to <code>PHPSESSID-demo</code>.}} |
| | |
| * '''Disable antivirus (fastest):''' Add <code>define('DISABLE_ANTIVIRUS', true);</code> to <code>system_configuration.php</code>
| |
| * '''Move shell commands (recommended):** Put <code>shell_exec()</code> code in external PHP file outside web directory, include it in <code>custom_login.php</code>
| |
| * The antivirus is a security feature to protect your GUI from compromised custom scripts
| |
| * If antivirus is disabled, ensure GUI access is properly secured (firewall, strong passwords, HTTPS)
| |
|
| |
|
| === Custom Script ===
| | '''Disable authorization:''' GUI > Settings > System Configuration > "Disable authorization for API usage" |
|
| |
|
| Custom login enables implementing your own mechanism. Create file: scripts/custom_login.php with function custom_login.
| | === Filter Parameters === |
|
| |
|
| Location: <GUI_INSTALL_DIR>/scripts/custom_login.php
| | '''Mandatory:''' <code>task=LISTING</code>, <code>module=CDR</code>, and at least one of <code>fdatefrom</code> or <code>fdateto</code>. |
|
| |
|
| <?php
| | {| class="wikitable" |
| function custom_login($user, $password) {
| | |- |
| debug_log('custom_login');
| | ! Parameter !! Description !! Example |
| return(array(
| | |- |
| 'username' => $user,
| | | <code>fdatefrom</code> / <code>fdateto</code> || Date range || <code>2024-01-01T00:00:00</code> |
| 'is_admin' => false,
| | |- |
| 'id' => $userIdUniqueNum, // required numeric unique identifier for each user
| | | <code>fcaller</code> / <code>fcalled</code> || Caller/called number || <code>123456</code> |
| // 'id_group' => 1, // you can set user rights with the gui's group id too
| | |- |
| 'enable_sensors' => array(2,3)
| | | <code>fcallerd_type</code> || <code>0</code>=OR, <code>1</code>=AND || <code>1</code> |
| ));
| | |- |
| }
| | | <code>fcaller_domain</code> / <code>fcalled_domain</code> || SIP domain || <code>sip.example.com</code> |
| ?>
| | |- |
| | | <code>fsipcallerip</code> / <code>fsipcalledip</code> || SIP IP address || <code>192.168.1.1</code> |
| | |- |
| | | <code>fcallid</code> || SIP Call-ID || <code>abc123</code> |
| | |- |
| | | <code>fsipresponse</code> || SIP response code || <code>503</code> |
| | |- |
| | | <code>fdurationgt</code> / <code>fdurationlt</code> || Duration (seconds) || <code>10</code> |
| | |- |
| | | <code>fsensor_id</code> || Sensor ID || <code>1</code> |
| | |- |
| | | <code>fcodec</code> || Codec numbers (comma-sep) || <code>0,8</code> |
| | |- |
| | | <code>suppress_results</code> || <code>1</code>=count only || <code>1</code> |
| | |} |
|
| |
|
| Returned array parameters:
| | '''Paging:''' <code>page</code>, <code>start</code>, <code>limit</code> |
|
| |
|
| *enable_sensors - array(A,B,...) where the number is number of the sensor. If no enable_sensors provided the user will see all sensors CDR.
| | '''Sorting:''' <code>sort=[{"property":"calldate","direction":"DESC"}]</code> |
| *username
| |
| *name
| |
| *secret
| |
| *id_group
| |
| *group_name
| |
| *group_blocked
| |
| *can_cdr
| |
| *can_write_cdr
| |
| *can_play_audio
| |
| *can_download_audio
| |
| *can_listen_active_call
| |
| *can_show_fax
| |
| *can_pcap
| |
| *can_upload_pcap
| |
| *can_messages
| |
| *can_view_content_message
| |
| *can_view_message_url
| |
| *is_admin
| |
| *no_rtp
| |
| *simple_cdr
| |
| *hide_cdr_groups
| |
| *can_graphs
| |
| *can_tracker
| |
| *can_activecalls
| |
| *can_register
| |
| *can_sip_msg
| |
| *can_livesniffer
| |
| *can_capture_rules
| |
| *crules_remove_expire_time
| |
| *can_audit
| |
| *can_alerts_edit
| |
| *can_alerts_show_sent
| |
| *can_reports_edit
| |
| *can_reports_show_sent
| |
| *can_cdr_share_local_public
| |
| *can_cdr_share_local_private
| |
| *can_cdr_share_voipmonitor_org
| |
| *hide_license_information
| |
| *can_ipacc
| |
| *can_mtr
| |
| *can_show_sql_query
| |
| *can_sensors_operations
| |
| *show_only_connected_calls
| |
| *can_dashboard
| |
| *dashboard_read_only
| |
| *can_report_functions
| |
| *hide_change_password
| |
| *hide_user_configuration
| |
| *password_expired
| |
| *can_svg_paint
| |
| *can_3d_rtp_charts
| |
| *can_network
| |
| *can_edit_codebooks
| |
| *can_edit_all_templates
| |
| *can_delete_all_templates
| |
| *ip
| |
| *number
| |
| *domain
| |
| *vlan
| |
| *custom_headers_cdr
| |
| *custom_headers_message
| |
| *ip_number_domain_or
| |
| *note
| |
| *email
| |
| *blocked
| |
| *blocked_reason
| |
| *max_bad_login_attempt
| |
| *password_expiration_days
| |
| *enable_login_ip
| |
| *uc_color_theme_shift_h
| |
| *uc_color_theme_shift_s
| |
| *uc_color_theme_shift_v
| |
| *uc_color_theme_shift
| |
| *uc_font_main_menu
| |
| *uc_disable_confirm_before_unload
| |
| *uc_enable_dns_cdr
| |
| *uc_enable_dns_message
| |
| *uc_enable_flags_cdr_number
| |
| *uc_enable_flags_cdr_ip
| |
| *uc_enable_flags_message_number
| |
| *uc_enable_flags_message_ip
| |
| *uc_csv_field_separator
| |
| *count_audit_log
| |
| *req_2fa
| |
|
| |
|
| == CDR HTTP API == | | {{Warning|1=Use <code>=</code> (equals) for parameters, not <code>:</code> (colon). Example: <code>fcallerd_type=1</code> (correct), not <code>fcallerd_type:1</code> (wrong).}} |
|
| |
|
| Retrieves CDR rows in JSON, using WEB GUI filters: [[Call_Detail_Record_-_CDR#Filter_Form_button]].
| | === Wildcards === |
|
| |
|
| Requires valid session: [[GUI_automate_login]]. Send parameters via POST.
| | Use <code>%25</code> (URL-encoded <code>%</code>) for SQL LIKE patterns: |
|
| |
|
| Disable authorization (safe environments): '''GUI > Settings > System Configuration > Disable authorization for API usage'''.
| | <syntaxhighlight lang="bash"> |
| | # Caller starting with "00" |
| | curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ |
| | --data-urlencode 'params={"startTime":"2024-01-01","caller":"%2500%25"}' |
| | </syntaxhighlight> |
|
| |
|
| === CURL Notes === | | === Codec Values === |
|
| |
|
| Use -G and --data-urlencode for special characters (e.g., + in caller).
| | {| class="wikitable" |
| | |- |
| | ! Value !! Codec !! Value !! Codec |
| | |- |
| | | 0 || PCMU (G.711 μ-law) || 8 || PCMA (G.711 A-law) |
| | |- |
| | | 3 || GSM || 9 || G.722 |
| | |- |
| | | 4 || G.723 || 12 || QCELP |
| | |- |
| | | 18 || G.729 || 97 || iLBC |
| | |- |
| | | 98 || Speex || 301-305 || SILK variants |
| | |- |
| | | 306-308 || iSAC variants || 1000 || T.38 (Fax) |
| | |} |
|
| |
|
| Example:
| | === RTP Quality Filters === |
|
| |
|
| curl -G -X GET 'http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' --data-urlencode 'params=[{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251414414"},{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"1+1","customHeaders":"Cell-ID-Caller,Cell-ID-Called"}]'
| | {| class="wikitable" |
| | |- |
| | ! Parameter !! Description |
| | |- |
| | | <code>fmosf1</code>, <code>fmosf2</code>, <code>fmosadapt</code> || MOS score filters |
| | |- |
| | | <code>frtcp_maxjitter</code>, <code>frtcp_avgjitter</code> || RTCP jitter |
| | |- |
| | | <code>frtcp_maxfr</code>, <code>frtcp_avgfr</code> || RTCP frame rate |
| | |- |
| | | <code>floss1</code> - <code>floss10</code> || Packet loss distribution |
| | |- |
| | | <code>f_d50</code>, <code>f_d70</code>, <code>f_d90</code>, ... || Delay distribution (50ms, 70ms, etc.) |
| | |} |
|
| |
|
| === Input === | | == Utility Endpoints == |
|
| |
|
| HTTP POST address: php/model/sql.php
| | === Direct PCAP Download === |
|
| |
|
| ==== Important: Query Parameter Syntax ==== | | <syntaxhighlight lang="bash"> |
| | curl 'http://server/php/pcap.php?id=12345' # Full PCAP |
| | curl 'http://server/php/pcap.php?id=12345&disable_rtp=1' # SIP only |
| | </syntaxhighlight> |
|
| |
|
| When building API requests, use **equals signs (=)** for parameter assignment in HTTP query strings, not colons.
| | === CDR URL for Browser === |
|
| |
|
| * '''Correct:''' <code>&fcallerd_type=1&</code>
| | <syntaxhighlight lang="text"> |
| * '''Incorrect:''' <code>&fcallerd_type:1&</code>
| | http://server/admin.php?cdr_filter={fcallid:"abc123"} |
| | </syntaxhighlight> |
|
| |
|
| The wiki documentation uses colons to separate parameter names from descriptions (e.g., <code>fcaller: caller num</code>), which is standard documentation format. However, in actual HTTP requests you must use the equals sign for parameter assignment.
| | === SIP History === |
|
| |
|
| '''Common Syntax Mistakes:'''
| | Requires session authentication first. |
| * Using <code>:</code> instead of <code>=</code> in query parameters
| |
| * Example error: <code>http://server/php/api.php?task=getVoipCalls&fcallerd_type:1</code>
| |
| * Example correction: <code>http://server/php/api.php?task=getVoipCalls&fcallerd_type=1</code>
| |
|
| |
|
| If your filters are not working (e.g., changing the called domain filter does not affect results), double-check that you are using <code>=</code> instead of <code>:</code> in your parameter syntax.
| | <syntaxhighlight lang="bash"> |
| | # JSON data |
| | curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief_data&id=12345' |
|
| |
|
| ==== Mandatory Parameters ==== | | # HTML table |
| | curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief&id=12345' |
|
| |
|
| task:LISTING module:CDR
| | # MSC diagram |
| | curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=getMSC&id=12345' |
| | </syntaxhighlight> |
|
| |
|
| fdatefrom:DATE or fdateto:DATE is required due to mysql overloading
| | === License Check === |
|
| |
|
| ==== Suppress Results ==== | | <syntaxhighlight lang="bash"> |
| | # Basic license check |
| | curl 'http://server/php/apilicensecheck.php?task=licenseCheck' |
|
| |
|
| suppress_results:1
| | # Concurrent calls limit check |
| | | curl 'http://server/php/apilicensecheck.php?task=licenseCallsLimitCheck' |
| will not list CDR but only {"total":"135"}
| | </syntaxhighlight> |
| | |
| ==== Datetime Range ====
| |
| | |
| fdatefrom:1986-01-09T00:00:00 fdateto:2013-05-28T00:00:00
| |
| | |
| ==== Caller / Called Numbers ====
| |
| | |
| fcaller: caller num
| |
| fcalled: called num
| |
| fcallerd_type: 0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)
| |
| | |
| ==== Using Wildcards in Filters ====
| |
|
| |
|
| You can use wildcard characters in API filter parameters. However, the <code>%</code> character (used for SQL LIKE patterns) must be URL-encoded as <code>%25</code> when passed in API requests.
| | == Share CDR Configuration == |
|
| |
|
| '''Example: Filter for caller numbers starting with "00"'''
| | === Share Link Types === |
|
| |
|
| curl -G -X GET 'http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' --data-urlencode 'params={"startTime":"2023-01-01","endTime":"2023-12-31","caller":"%2500"}'
| | Use <code>/php/model/utilities.php</code> with <code>task=shareCdr</code>: |
|
| |
|
| '''Important Notes:'''
| | {| class="wikitable" |
| * Use <code>%25</code> to represent a literal <code>%</code> wildcard character in the URL
| | |- |
| * <code>%</code> followed by any two digits in a URL query string is interpreted as a URL-encoded character
| | ! Type !! subType !! Description |
| * Without encoding, <code>%25</code> would be decoded as just <code>%</code>, but the API needs to receive the <code>%25</code> characters to construct the SQL LIKE pattern correctly
| | |- |
| * The <code>--data-urlencode</code> flag in curl handles this automatically for you
| | | Local Public || <code>self_protected_link</code> || Password-protected local link |
| | |- |
| | | Local Private || <code>self_login_link</code> || Requires GUI login |
| | |- |
| | | voipmonitor.org || <code>share_link</code> || Public via share.voipmonitor.org |
| | |} |
|
| |
|
| '''Common wildcard patterns:'''
| | === Custom Branding === |
| * <code>%2500</code> - matches caller numbers starting with "00"
| |
| * <code>123%</code> - matches caller numbers starting with "123" (no encoding needed when <code>%</code> is at the end)
| |
| * <code>%25abc</code> - matches caller numbers containing "abc" anywhere
| |
| | |
| ==== Domain ==== | |
| | |
| fcaller_domain: caller domain fcalled_domain: caller domain
| |
| fcallerd_domain_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)
| |
| | |
| ==== Caller ID Name ====
| |
| | |
| fcallername: caller name
| |
| | |
| ==== SIP Caller / Called IP ====
| |
| | |
| fsipcallerip: caller SIP IP fsipcalledip: called SIP IP
| |
| fsipcallerdip_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)
| |
| | |
| ==== RTP Source / Destination IP ====
| |
| | |
| fa_saddr: 192.168.0.1
| |
| fb_saddr: 192.168.0.2
| |
| fab_saddr_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)
| |
| | |
| ==== Codecs ====
| |
| | |
| fcodec: 4, 12
| |
| | |
| list of numbers delimited by ','. Here is list of numbers and its codecs
| |
| define("PAYLOAD_PCMU", 0); define("PAYLOAD_GSM", 3); define("PAYLOAD_G723", 4); define("PAYLOAD_PCMA", 8); define("PAYLOAD_G722", 9); define("PAYLOAD_QCELP", 12); define("PAYLOAD_CN", 13); define("PAYLOAD_G729", 18); define("PAYLOAD_ILBC", 97); define("PAYLOAD_SPEEX", 98); define("PAYLOAD_SILK", 301); define("PAYLOAD_SILK8", 302); define("PAYLOAD_SILK12", 303); define("PAYLOAD_SILK16", 304); define("PAYLOAD_SILK24", 305); define("PAYLOAD_ISAC", 306); define("PAYLOAD_ISAC16", 307); define("PAYLOAD_ISAC32", 308); define("PAYLOAD_T38", 1000);
| |
| | |
| ==== Call Duration ====
| |
| | |
| example: less than 30 and greater than 10 seconds
| |
| fdurationgt: 30 fdurationlt: 10
| |
| | |
| ==== PDD ====
| |
| | |
| example: greater than 10 and less than 30 seconds
| |
| fpddgt: 10 fpddlt: 30
| |
| | |
| ==== SIP Response Code ====
| |
| | |
| fsipresponse: 503
| |
| | |
| ==== Interrupted Call ====
| |
| | |
| false or true
| |
| fbye:false
| |
| | |
| Direction (by trunk)
| |
| false or true
| |
| ftrunk:
| |
| | |
| SIP user agent
| |
| fa_ua: caller agent string fb_ua: called agent string
| |
| fab_ua_type:0 (if type is 0 searching is done for fcaller OR fcalled and value is taken from fcaller. If value is 1 searching is done for fcaller AND fcalled)
| |
| | |
| SIP Call-ID header
| |
| fcallid: string
| |
| | |
| SIP sensor ID (database ID)
| |
| fsensor_id:
| |
| | |
| ==== Paging ====
| |
| | |
| page:1 start:0 limit:30
| |
| | |
| ==== Ordering ====
| |
| | |
| sort:[{"property":"calldate2","direction":"DESC"}]
| |
| | |
| ==== Special Ordering ====
| |
| | |
| orderByLoss: orderByDelay: orderByFixed1: orderByFixed2: orderByAdapt: orderByCallDuration_asc: orderByCallDuration_desc: orderBySrcSIP_IP_asc: orderBySrcSIP_IP_desc: orderByDstSIP_IP_asc: orderByDstSIP_IP_desc: orderBySrcNumber_asc: orderBySrcNumber_desc: orderByDstNumber_asc: orderByDstNumber_desc: orderByCallerName_asc: orderByCallerName_desc: orderByLastSIPrespNum_asc: orderByLastSIPrespNum_desc:
| |
| | |
| ==== RTP ====
| |
| | |
| frtcp_maxjitter: frtcp_avgjitter: frtcp_maxfr: frtcp_avgfr: fmosf1: fmosf2: fmosadapt: f_d50: f_d70: f_d90: f_d120: f_d150: f_d200: f_d300: floss1: floss2: floss3: floss4: floss5: floss6: floss7: floss8: floss9: floss10: ffilterTemplate:
| |
| | |
| === Output ===
| |
| | |
| JSON formatted array of CDR.
| |
| | |
| ==== GUI in Default DocumentRoot ====
| |
| | |
| Example for /var/www/html
| |
| | |
| curl -X POST '192.168.76.201/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'
| |
| | |
| returns something like this
| |
| {"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID","success":true,"_vm_version":240034,"_debug":false}
| |
| | |
| take the SID which you will put to cookie_name variable
| |
| | |
| curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2013-05-08T00:00:00&fcaller=190"
| |
| | |
| ==== GUI in Demo Subdirectory ====
| |
| | |
| Example for /var/www/html/demo
| |
| | |
| curl -X POST '192.168.76.201/demo/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'
| |
| | |
| returns something like this
| |
| {"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID-demo","success":true,"_vm_version":240034,"_debug":false}
| |
| | |
| take the SID which you will put to cookie_name variable
| |
| | |
| curl -X POST -k --cookie "PHPSESSID-demo=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/demo/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2013-05-08T00:00:00&fcaller=190"
| |
| | |
| ==== Example Output for LISTING Task ====
| |
| | |
| See attached link: [[output of the API LISTING task]]
| |
| | |
| == Share CDR ==
| |
| | |
| Share CDR via request to php/model/utilities.php. For SIP+RTP, set type2 to "rtp"; for SIP only, type2:null.
| |
| | |
| === Show Link Local Public ===
| |
| | |
| task=shareCdr¶ms={"type":"share_cdr_show","type2":null,"subType":"self_protected_link","id":[128024514],"emailFields":null}
| |
| | |
| === Show Link Local Private ===
| |
| | |
| task=shareCdr¶ms={"type":"share_cdr_show","type2":null,"subType":"self_login_link","id":[128024514],"emailFields":null}
| |
| | |
| === Show Link share.voipmonitor.org ===
| |
| | |
| task=shareCdr¶ms={"type":"share_cdr_show","type2":null,"subType":"share_link","id":[128024590],"emailFields":null}
| |
| | |
| === Customizing Branding ===
| |
| | |
| You can customize VoIPmonitor branding in three ways:
| |
| | |
| ==== Customizing Product Name ====
| |
| | |
| To replace the default "VoIPmonitor" name in the GUI header and alert emails with your own company name, edit the <code>system_configuration.php</code> file:
| |
|
| |
|
| | '''Product Name:''' Edit <code>config/system_configuration.php</code>: |
| <syntaxhighlight lang="php"> | | <syntaxhighlight lang="php"> |
| // File location: ./gui/config/system_configuration.php
| |
| define('BRAND_NAME', 'YourCompany'); | | define('BRAND_NAME', 'YourCompany'); |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| After making this change:
| | '''Share Domain:''' Edit <code>brand.php</code> to use your domain instead of share.voipmonitor.org: |
| 1. Save the file
| |
| 2. Log out of the GUI
| |
| 3. Log back in for the changes to take effect
| |
| | |
| The new name will appear in the GUI header and in alert emails.
| |
| | |
| ==== Customizing share.voipmonitor.org Domain ====
| |
| | |
| To brand the share service with your own domain instead of using the default share.voipmonitor.org, edit the <code>brand.php</code> file in your GUI directory and add the following definitions:
| |
| | |
| <syntaxhighlight lang="php"> | | <syntaxhighlight lang="php"> |
| // File location: ./gui/brand.php
| | define('BRAND_SHARESITE', 'share.yourdomain.com'); |
| define('BRAND_SHARESITE', 'share.yourdomain.fr'); | | define('BRAND_DOMAIN', 'yourdomain.com'); |
| define('BRAND_DOMAIN', 'yourdomain.fr'); | |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Replace 'yourdomain.fr' with your actual domain. This causes share links to use your branded domain instead of share.voipmonitor.org.
| | == Custom Login (LDAP/SSO) == |
|
| |
|
| == Get PCAP File ==
| | Custom authentication via <code>scripts/custom_login.php</code>. This applies to GUI login only, NOT to API authentication. |
|
| |
|
| GET or POST request with CDR ID:
| | === Basic Structure === |
|
| |
|
| http://voipmonitor/php/pcap.php?id=203800251
| | <syntaxhighlight lang="php"> |
| | <?php |
| | function custom_login($user, $password) { |
| | // Authenticate against external system (LDAP, etc.) |
| | // ... |
|
| |
|
| Optionally filter out RTP: disable_rtp=1
| | return array( |
| | 'username' => $user, |
| | 'id' => $uniqueNumericId, // REQUIRED: Must be unique per user! |
| | 'is_admin' => false, |
| | 'id_group' => 1, // Optional: GUI group ID |
| | 'enable_sensors' => array(1,2,3) // Optional: restrict to sensors |
| | ); |
| | } |
| | ?> |
| | </syntaxhighlight> |
|
| |
|
| == Search CDR by URL == | | {{Warning|1='''The <code>id</code> field MUST be unique per user.''' If multiple users return the same ID, they share ALL settings (timezone, dashboard, etc.). Use LDAP <code>uidnumber</code> or <code>crc32($email)</code> for uniqueness.}} |
|
| |
|
| Build URL for CDR display in browser:
| | === LDAP Example === |
|
| |
|
| http://localhost/admin.php?cdr_filter={fcallid:"uDR8mtloKFa1F8625VL2OXSFp.RuG73v"}
| | See <code>scripts/ldap_custom_login_example.php</code> in GUI directory. |
|
| |
|
| cdr_filter uses same arguments as [[WEB_API#CDR_HTTP_API]]
| | '''Requirements:''' <code>php-ldap</code> package installed. |
|
| |
|
| == HTTP API 2 == | | '''Debug from CLI:''' |
| | <syntaxhighlight lang="bash"> |
| | cd /var/www/html/scripts/ |
| | php custom_login.php |
| | </syntaxhighlight> |
|
| |
|
| Preferred API for audio files by search criteria. Requests via HTTP POST or GET.
| | Enable debug by uncommenting the debug block at top of script. |
|
| |
|
| === Rate Limit === | | === Troubleshooting === |
|
| |
|
| Enable in '''GUI > Settings > System Configuration > API maximal concurrent connections'''. Limit per user.
| | '''Users share settings:''' Return unique <code>id</code> per user (see warning above). |
|
| |
|
| === getVoipCalls === | | '''LDAP users can't view CDRs:''' Ensure <code>is_admin => false</code> and correct <code>id_group</code> is returned. |
|
| |
|
| ==== Input Data ====
| | '''Script being deleted:''' GUI antivirus deletes scripts with <code>shell_exec()</code>, <code>exec()</code>, etc. |
|
| |
|
| *startTime - all calls which started >= startTime
| | '''Solutions:''' |
| *startTimeTo - all calls which started <= startTimeTo (not mandatory)
| | # Disable antivirus in <code>config/system_configuration.php</code>: |
| *callEnd - all calls which ends <= callEnd (not mandatory)
| | <syntaxhighlight lang="php"> |
| *caller - caller number
| | define('DISABLE_ANTIVIRUS', true); |
| *called - called number
| |
| *callId - Call-ID
| |
| *id_sensor - sensor's number
| |
| *msisdn - when you enter caller and called then cond is 'caller = 9999999 and called = 9999998'. With msisdn the cond is 'caller = 9999997 or called = 9999997'
| |
| *cdrId - ID number in db
| |
| *onlyConnected - 1 to get only connected calls (omit this parameter to retrieve all calls including unconnected)
| |
| *[custom header name]: [custom header value], seach cdrs by this custom header value
| |
| *customHeaders - the names of the returned custom header's values
| |
| task: getVoipCalls,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| auditReason: reason text for audit log (not required),
| |
| params: {
| |
| startTime: YYYY-MM-DD HH:II:SS,
| |
| startTimeTo: YYYY-MM-DD HH:II:SS,
| |
| callEnd: YYYY-MM-DD HH:II:SS,
| |
| caller: 9999999,
| |
| called: 9999999,
| |
| callId: 'XXXXXXXXXXXXXXXXXXXXXX',
| |
| id_sensor: 5,
| |
| msisdn: 9999997,
| |
| cdrId: 99999,
| |
| onlyConnected: 1, // Get only connected calls (omit this parameter for all calls including unconnected)
| |
| [custom header name]: [custom header value],
| |
| customHeaders: "Cell-ID-Caller,Cell-ID-Called"
| |
| }
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST Simple Parameter =====
| |
| | |
| echo '{"task": "getVoipCalls", "user": "USER", "password": "PASSWORD", "params": {"startTime": "2013-01-01", "endTime": "2013-08-01", "caller": "910251414414","customHeaders": "Cell-ID-Caller,Cell-ID-Called"}}' | php php/api.php
| |
| echo '{"task": "getVoipCalls", "user": "USER", "password": "PASSWORD", "params": {"startTime": "2023-01-01", "endTime": "2023-08-01", "callId": "a90eb404-4c12-363b-4812-56622343fbdf"}}' | php php/api.php
| |
| | |
| ===== HTTP POST Array Parameter =====
| |
| | |
| echo '{"task": "getVoipCalls", "user": "USER", "password": "PASSWORD", "params": [{"startTime": "2013-01-01", "endTime": "2013-08-01", "caller": "910251414"},{"startTime": "2013-01-01", "endTime": "2013-08-01", "caller": "910251415", "customHeaders": "Cell-ID-Caller,Cell-ID-Called"}]}' | php php/api.php
| |
| | |
| ===== HTTP GET Simple Parameter =====
| |
| | |
| http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms={"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251414","customHeaders":"Cell-ID-Caller,Cell-ID-Called"}
| |
| | |
| ===== HTTP GET Array Parameter =====
| |
| | |
| http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms=[{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251414"},{"startTime":"2013-01-01","endTime":"2013-08-01","caller":"910251415","customHeaders":"Cell-ID-Caller,Cell-ID-Called"}]
| |
| | |
| === getVoiceRecording ===
| |
| | |
| ==== Input Data ====
| |
| | |
| task: getVoiceRecording,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| auditReason: reason text for audit log (not required),
| |
| params: {
| |
| cdrId: 999999
| |
| callId: 'XXXXXXXXXXXXXXXXXXXXXX',
| |
| "CustomHeaderName": "CustomHeaderValue,
| |
| calldate: '2015-03-01' //default value is current date, not used when cdrId set
| |
| }
| |
| or
| |
| params: { customHeader: 'name of the column in cdr_next table', customHeaderValue: 'your value', calldate: '2015-03-01' } //not recommended
| |
| | |
| ===== Optional Parameters for Params =====
| |
| | |
| zip, ogg, : (true|false)
| |
| saveaudio_afterconnect : ("yes"|"no")
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"cdrId": "4919"}}' | php api.php
| |
| echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"cdrId": [6,7],"saveaudio_afterconnect":"yes"}}' | php api.php > /tmp/m6_m7.wav.zip
| |
| echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"callId": "XXXXXXXXXXXXXXXXXXXXXX"}}' | php api.php
| |
| echo '{"task": "getVoiceRecording", "user": "USER", "password": "PASSWORD", "params": {"Cust_header": "CustValue"}}' | php api.php
| |
| | |
| ===== HTTP GET =====
| |
| | |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":4919}
| |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":4919,"saveaudio_afterconnect":"yes"}
| |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"XXXXXXXXXXXXXXXXXXXXXX"}
| |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"XXXXXXXXXXXXXXXXXXXXXX","cidInterval":10}
| |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"XXXXXXXXXXXXXXXXXXXXXX","cidInterval":10,"saveaudio_afterconnect":"yes"}
| |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"Cust_header":"CustValue"}
| |
| | |
| === listActiveCalls ===
| |
| | |
| ==== Input Data ====
| |
| | |
| task: listActiveCalls,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| params: {
| |
| sensorId: 'sensor number',
| |
| callId: 'callId'
| |
| }
| |
| sensorId and callId are optional.
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| echo '{"task": "listActiveCalls", "user": "USER", "password": "PASSWORD", "params": {"sensorId": "1"}}' | php api.php
| |
| | |
| ===== HTTP GET =====
| |
| | |
| http://localhost/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD¶ms={"sensorId":"1"}
| |
| | |
| ===== Response Format and IP Address Conversion =====
| |
| | |
| The API returns a JSON object with an array of active calls under the <code>rows</code> key.
| |
| | |
| '''Important: IP Address Format'''
| |
| | |
| The <code>callerip</code> and <code>calledip</code> fields in the response are integer representations of IP addresses, not dotted-decimal format.
| |
| | |
| To convert these to standard dotted-decimal format:
| |
| | |
| * For IPv4: Use <code>INET_NTOA()</code> function in MySQL or similar conversion in your application code
| |
| * For IPv6: Use <code>INET6_NTOA()</code> function
| |
| | |
| Example MySQL query for conversion:
| |
| <syntaxhighlight lang="sql"> | |
| SELECT INET_NTOA(callerip) as caller_ip, INET_NTOA(calledip) as called_ip FROM live;
| |
| </syntaxhighlight> | | </syntaxhighlight> |
| | # Or move shell commands to external file outside web directory and <code>require_once()</code> it. |
|
| |
|
| === handleActiveCall === | | === Azure AD / Microsoft SSO === |
| | |
| Start/stop RTP recording. Pausing saves empty RTP frames to PCAP; affects 'Listening to Active call' (no audio from paused calls).
| |
| | |
| ==== Input Data ====
| |
| | |
| task: handleActiveCall,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| auditReason: reason text for audit log (not required),
| |
| params: {
| |
| sensorId: 'sensor number',
| |
| command: 'command (can be only pausecall/unpausecall now)',
| |
| callRef: 'call reference'
| |
| }
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| echo '{"task": "handleActiveCall", "user": "USER", "password": "PASSWORD", "params": {"sensorId": "1","command":"pausecall","callRef":"0x7f0e4c3c2680"}}' | php api.php
| |
| | |
| ===== HTTP GET =====
| |
| | |
| http://localhost/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD¶ms={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}
| |
| | |
| === reportSummary ===
| |
| | |
| Generates a pre-configured summary report as an image. This is the '''only''' type of report available via the web API.
| |
| | |
| '''Important:''' Reports must be created in the GUI before use with the API.
| |
| | |
| ====== Report Creation ======
| |
| | |
| Before using this API task:
| |
| 1. Navigate to '''GUI → Reports → Daily Report'''
| |
| 2. Create a new report of type ''summary''
| |
| 3. Fill in the '''Description''' field - this text becomes your '''report_name''' for API calls
| |
| 4. Configure any charts or filters as needed for the report
| |
| 5. Save the report
| |
| | |
| The API generates reports that have been pre-configured in the GUI - you cannot create new report configurations via the API.
| |
| | |
| ==== Input Data ====
| |
| | |
| task: reportSummary,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| params: {
| |
| report_name: '''the Description field from your GUI report''',
| |
| datetime_from: datetime from (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
| |
| datetime_to: datetime to (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS)
| |
| json: true or false (returns JSON response instead of image)
| |
| }
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| echo '{"task": "reportSummary", "user": "USER", "password": "PASSWORD", "params": {"report_name": "test summary", "datetime_from": "2017-12-20", "datetime_to": "2017-12-20"}}' | php api.php
| |
| | |
| ===== HTTP GET =====
| |
| | |
| http://localhost/php/api.php?task=reportSummary&user=USER&password=PASSWORD¶ms={"report_name":"test summary","datetime_from":"2017-12-20","datetime_to":"2017-12-20"}
| |
| | |
| === getShareURL ===
| |
| | |
| Parameters like [[#getVoiceRecording|getVoiceRecording]]. Returns public link for LEGs by CID. Use '''callId''' (SIP Call-ID string), '''cdrId''' (database ID), or '''custom SIP header''' to identify the call. If 'sip_history' true, only SIP history (RTP ignored).
| |
| | |
| Options: 'anonIps' anonymizes IPs/domains; 'validDays' limits validity.
| |
| | |
| Supported identification methods:
| |
| * <code>callId</code> - SIP Call-ID string
| |
| * <code>cdrId</code> - Internal database ID
| |
| * <code>"CustomHeaderName"</code> - Custom SIP header key-value pair
| |
| | |
| ==== Custom Header Query ===
| |
| | |
| You can query by custom SIP headers by adding a key-value pair in the <code>params</code> object where the key is the header name and the value is the content to match.
| |
| | |
| Example: To search for a header named <code>X-My-Header</code> with value <code>test123</code>:
| |
| | |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"X-My-Header":"test123","cidInterval":60,"sip_history":true}
| |
| | |
| ===== HTTP GET (with RTP, by SIP Call-ID) =====
| |
| | |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","cidInterval":60,"rtp":true,"anonIps":true,"validDays":15}
| |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","rtp":true}
| |
| | |
| ===== HTTP GET (by database ID/CdrId) =====
| |
| | |
| curl -G -X POST 'http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD' --data-urlencode 'params={"cdrId":"12345","rtp":true}'
| |
|
| |
|
| This returns a URL in the format: http://localhost/master/cdr.php?cdrId=12345&hash=HASH_VALUE
| | For Microsoft Entra ID integration, see [[Microsoft_Sign_in_usage]]. For Google, see [[Google_Sign_in_usage]]. |
|
| |
|
| ===== HTTP GET (only SIP) ===== | | === Return Array Parameters === |
|
| |
|
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","cidInterval":60}
| | Full list of available return parameters for custom_login: |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225"}
| |
|
| |
|
| ===== HTTP GET (SIP History) =====
| | <div class="mw-collapsible mw-collapsed"> |
| | | <syntaxhighlight lang="text"> |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","cidInterval":60, "sip_history": true}
| | username, name, id, id_group, group_name, is_admin, email |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","sip_history": true}
| | enable_sensors - array of sensor IDs user can access |
| | | can_cdr, can_write_cdr, can_play_audio, can_download_audio |
| === getPCAP ===
| | can_listen_active_call, can_pcap, can_upload_pcap |
| | | can_messages, can_view_content_message, can_graphs |
| Parameters like getVoiceRecording. Returns PCAP (merged legs if multiple in interval). Zip auto if multiple.
| | can_activecalls, can_register, can_sip_msg, can_livesniffer |
| | | can_capture_rules, can_audit, can_alerts_edit, can_reports_edit |
| ==== curl with data-urlencode ===
| | can_dashboard, can_ipacc, can_mtr, can_sensors_operations |
| | | can_network, can_edit_codebooks, hide_license_information |
| Use <code>-G</code> and <code>--data-urlencode</code> to properly encode the params string, especially when it contains special characters or complex bracket structures. This prevents <code>success:false</code> responses due to malformed parameters.
| | ip, number, domain, vlan (user restrictions) |
| | | custom_headers_cdr, custom_headers_message |
| ===== HTTP GET (with cURL recommended) =====
| | blocked, blocked_reason, req_2fa |
| | |
| curl -G -X GET 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' --data-urlencode 'params={"callId":"1502262225","cidInterval":60,"cidMerge":true}'
| |
| | |
| ===== HTTP POST (with cURL recommended for complex params) =====
| |
| | |
| curl -X POST 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \
| |
| --data 'params={"callId":"1502262225","cidInterval":60}' \
| |
| --data 'cidMerge=true' \
| |
| --data 'zip=true'
| |
| | |
| ==== Direct URL Examples (GET) =====
| |
| | |
| These work for simple cases but may fail with special characters:
| |
| | |
| http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"cdrId":"76"}
| |
| http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"callId":"1502262225"}
| |
| http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"callId":"1502262225","cidInterval":60}
| |
| | |
| === listCdrIds ===
| |
| | |
| Returns 'size' CDR records with basic info, starting from 'offset' ID.
| |
| | |
| ==== Input Data ====
| |
| | |
| task: listCdrIds,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| flags: number, //not required, bitfield format: 0x01 .. simpleOutput, 0x02 .. date in ISO8601 format
| |
| params: {
| |
| offset: starting cdr id,
| |
| size: number of cdr records to return
| |
| }}
| |
| | |
| ==== Example ====
| |
| | |
| echo '{"task": "listCdrIds", "user": "USER", "password": "PASSWORD", "params": {"offset":"offset_num","size":"number of cdr records"}}' | php api.php
| |
| | |
| ==== Request ====
| |
| | |
| task: listCdrIds,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| flags: number, //not required, bitfield format: 0x01 .. simpleOutput, 0x02 .. date in ISO8601 format
| |
| params: json_encode: {
| |
| offset: starting cdr id,
| |
| size: number of cdr records to return
| |
| }
| |
| | |
| ==== Example ====
| |
| | |
| http://localhost/php/api.php?task=listCdrIds&user=USER&password=PASSWORD¶ms={"offset":"offset_num","size":"number_of_cdr_records"}
| |
| | |
| === getAudioGraph ===
| |
| | |
| ==== Input Data ====
| |
| | |
| task: getAudioGraph,
| |
| user: USER,
| |
| password: PASSWORD,
| |
| params: {
| |
| cdrId : number (CDR.id),
| |
| type : S/P/ALL ( Spectrogram / Peaks=Waveform / ALL=including both types and both sides )
| |
| side : L/R ( Left / Right )
| |
| height: px
| |
| generating: 1 / 0 ( optional param, default 0, tells if audiograph data can be generated from packets in a spooldir. This parameter is needed if you don't use 'save_audiograph = yes' in the sensor config. If generating is 0 then the api call is looking only for created audiographs.)
| |
| }
| |
| | |
| ==== Output ====
| |
| | |
| Depends on 'type' (zip if "type":"ALL"):
| |
| | |
| PNG image
| |
| zip file
| |
| | |
| ==== Example ====
| |
| | |
| http://192.168.88.46/voipmonitor-git/gui/php/api.php?task=getAudioGraph&user=USER&password=PASSWORD¶ms={"cdrId":191,"type":"S","side":"R","height":"100"}
| |
| | |
| == Direct Links ==
| |
| | |
| Active calls: index.php?activecalls=1&hidegrid=1&hidemenu=1
| |
| | |
| == SIP History ==
| |
| | |
| Retrieves SIP history in various forms.
| |
| | |
| === Parameters ===
| |
| | |
| action: action., currently brief_data, brief, getMSC actions. required
| |
| id: cdr id of the call, required
| |
| dns_lookup: 0|1 ... make dns lookup
| |
| ip_not_allowed: exclude this ips from the output (possibility to hide some internal information)
| |
| | |
| === Example of Usage ===
| |
| | |
| # first get auth session
| |
| curl -X POST '192.168.76.201/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'
| |
| {"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID","success":true,"_vm_version":240034,"_debug":false}
| |
| | |
| * 'brief_data' action get SIP history data in JSON format
| |
| curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/pcap2text.php?action=brief_data&id=677&dns_lookup=0&ip_not_allowed=10.1.1.1,10.2.2.0/24
| |
| {"results":[{"num":"1","time":0,"src":"80.92.240.130","dst":"185.71.40.210","srcip":"80.92.240.130","dstip":"185.71.40.210","srcport":"5060","dstport":"5060","packet_len":"1046","direction":"-->","protocol":"SIP\/SDP","spec_type":null,"msg":"INVITE sip:2260@10.133.67.250:5060 len:1046","type":"request"},{"num":"2","time":0.054963111877441406,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"437","direction":"-->","protocol":"SIP","spec_type":null,"msg":"100 Trying len:437","type":"response"},{"num":"3","time":0.9610240459442139,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"588","direction":"-->","protocol":"SIP","spec_type":null,"msg":"180 Ringing len:588","type":"response"},{"num":"4","time":28.761795043945312,"src":"80.92.240.130","dst":"185.71.40.210","srcip":"80.92.240.130","dstip":"185.71.40.210","srcport":"5060","dstport":"5060","packet_len":"412","direction":"-->","protocol":"SIP","spec_type":null,"msg":"CANCEL sip:2260@10.133.67.250:5060 len:412","type":"request"},{"num":"5","time":28.795578002929688,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"433","direction":"-->","protocol":"SIP","spec_type":null,"msg":"200 OK len:433","type":"response"},{"num":"6","time":28.800518035888672,"src":"185.71.40.210","dst":"80.92.240.130","srcip":"185.71.40.210","dstip":"80.92.240.130","srcport":"5060","dstport":"5060","packet_len":"448","direction":"-->","protocol":"SIP","spec_type":null,"msg":"487 Request Cancelled len:448","type":"response"},{"num":"7","time":28.811052083969116,"src":"80.92.240.130","dst":"185.71.40.210","srcip":"80.92.240.130","dstip":"185.71.40.210","srcport":"5060","dstport":"5060","packet_len":"466","direction":"-->","protocol":"SIP","spec_type":null,"msg":"ACK sip:226@10.133.67.250:5060 len:466","type":"request"}],"total":7,"errors":{},"success":true,"_debug":false}
| |
| | |
| * 'brief' action get SIP history in simple HTML format (as table tag)
| |
| curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/pcap2text.php?action=brief&id=677&dns_lookup=0&ip_not_allowed=10.1.1.1,10.2.2.0/24
| |
| | |
| * 'genMSC' action get SIP history as diagram in HTML format
| |
| curl -X POST -k --cookie "PHPSESSID=ahs2ubdhc0ukb262be60v900ko" "http://192.168.76.201/php/pcap2text.php?action=getMSC&id=677&dns_lookup=0&ip_not_allowed=10.1.1.1,10.2.2.0/24
| |
| | |
| == Check License ==
| |
| | |
| * Basic test for license (covers ionCube issues):
| |
| | |
| 'http://localhost:88/php/apilicensecheck.php?task=licenseCheck'
| |
| {"status":1,"message":"license file key.php expired. Current date: 2021-02-23 Expiration date: 2021-02-16"}
| |
| 'http://localhost:88/php/apilicensecheck.php?task=licenseCheck'
| |
| {"status":0,"message":"License OK."}
| |
| | |
| * Test concurrent calls limit (requires functional ionCube):
| |
| | |
| 'http://localhost:88/php/apilicensecheck.php?task=licenseCallsLimitCheck'
| |
| | |
| Examples:
| |
| | |
| {"status":1,"message":"You have exceeded the license limit for concurrent calls and the system has been locked. Contact support."}
| |
| {"status":1,"message":"You have exceeded the license limit for concurrent calls. The system will be locked in 14 days. Contact support."}
| |
| {"status":0,"message":"Limit violation for 2nd consecutive day."}
| |
| | |
| === Resolving License Lockout ===
| |
| | |
| If the GUI is locked due to exceeding the licensed channel limit for more than two consecutive days, you have the following options:
| |
| | |
| '''Manually Delete CDRs from Database (Self-Service Option)'''
| |
| | |
| Reduce the concurrent call count by deleting old CDR records from the database. This can be done directly via SQL:
| |
| | |
| <syntaxhighlight lang="sql">
| |
| -- Warning: This permanently deletes call records
| |
| -- Always backup before running DELETE operations
| |
| | |
| -- Delete CDRs older than a specific date (adjust date as needed)
| |
| DELETE FROM cdr WHERE calldate < '2024-01-01';
| |
| | |
| -- Delete specific CDRs by ID range
| |
| DELETE FROM cdr WHERE ID BETWEEN 1000 AND 5000;
| |
| </syntaxhighlight> | | </syntaxhighlight> |
| | </div> |
|
| |
|
| After deleting CDRs, the system may need time to recalculate the concurrent call count. Monitor the license status using the API endpoint above.
| | == See Also == |
| | |
| '''Important Notes:'''
| |
| * Deleting CDRs is permanent and cannot be undone
| |
| * This only affects CDR records in the database, not captured audio files (PCAPs)
| |
| * The concurrent call count is based on recent CDR data; deleting older records may reduce the count below the license limit
| |
| * Always perform a full database backup before manual CDR deletion
| |
| | |
| '''Upgrade License Tier'''
| |
| | |
| Contact VoIPmonitor support to upgrade your license to a higher channel count tier:
| |
| | |
| * Higher-tier licenses support more concurrent calls
| |
| * Upgrading prevents future lockout issues
| |
| * Contact via the customer portal or email to request a license upgrade
| |
| | |
| '''Contact Support for Lockout Removal'''
| |
|
| |
|
| If you need immediate unlock without deleting CDRs:
| | * [[Call_Detail_Record_-_CDR#Filter_Form_button|CDR Filter Form]] - GUI filter options |
| | * [[Active_calls|Active Calls]] - Active calls monitoring |
| | * [[User_Management|User Management]] - User permissions |
| | * [[Google_Sign_in_usage|Google Sign-In]] - Google OAuth setup |
| | * [[Microsoft_Sign_in_usage|Microsoft Sign-In]] - Azure AD setup |
|
| |
|
| * Contact VoIPmonitor support via customer portal or email
| |
| * State that the system is locked due to exceeding the concurrent call limit
| |
| * Support can temporarily increase the limit or clear the lock on their end
| |
| * After support clears the lock, verify via Tools > System Status > License and GUI status
| |
|
| |
|
| === AI Summary for RAG ===
| | == AI Summary for RAG == |
|
| |
|
| '''Summary:''' This article covers VoIPmonitor's custom login (LDAP/script examples, parameters), CDR HTTP API (inputs/outputs, examples), sharing CDRs, getting PCAPs, URL searches, HTTP API 2 (getVoipCalls, recordings, active calls, reports, shares, PCAPs, CDR lists, audio graphs), direct links, SIP history retrieval, license checks, resolving license lockout, and GUI configuration. The LDAP troubleshooting section provides step-by-step instructions for debugging LDAP login issues by testing the custom_login.php script from the command line. The "File Being Automatically Deleted (Antivirus Protection)" section explains that VoIPmonitor GUI includes an antivirus security scanner that automatically deletes custom PHP files containing shell command functions (shell_exec, exec, system, passthru, popop) or suspicious patterns. Two solutions are documented: adding define('DISABLE_ANTIVIRUS', true); to system_configuration.php (fastest), or moving shell command code to an external PHP file outside the web directory and including it in custom_login.php (recommended for maintaining security). The getShareURL API now explicitly documents support for querying by custom SIP headers in addition to callId and cdrId. Users can specify custom headers directly in the params object as key-value pairs (e.g., {"X-My-Header":"test123"}). A new troubleshooting subsection addresses the specific issue where LDAP users can authenticate but cannot view CDRs despite being assigned to groups with correct permissions, explaining how to properly configure the is_admin flag and id_group variable. The license lockout resolution section explains three options when the GUI is locked due to exceeding the licensed channel limit: manually deleting CDRs from the database (self-service), upgrading the license tier, or contacting support for immediate lockout removal. The getPCAP documentation now includes important troubleshooting guidance on using curl --data-urlencode to properly encode params strings, which is a common solution for API requests that return success:false responses. The branding customization section explains how to replace the default "VoIPmonitor" product name in the GUI header and alert emails using the BRAND_NAME constant in system_configuration.php, as well as how to configure custom share domain using brand.php. The listActiveCalls endpoint enables programmatic retrieval of currently active calls from all connected probes, which is essential for real-time monitoring and automation scripts that need to check if a specific phone number is currently in a call. A new section on "Using Wildcards in Filters" explains how to use the percent sign (%) wildcard in API filter parameters, which must be URL-encoded as %25 when passed in API requests. This is critical when filtering caller numbers, called numbers, or other fields using LIKE patterns. | | '''Summary:''' VoIPmonitor Web API reference with two main APIs: (1) HTTP API 2 at <code>/php/api.php</code> using user/password authentication for tasks like getVoipCalls, getVoiceRecording, getPCAP, listActiveCalls, getShareURL, handleActiveCall, reportSummary; (2) CDR HTTP API at <code>/php/model/sql.php</code> using session cookies with full GUI filter support. Critical: correct endpoint path is <code>/php/api.php</code> (not <code>/api.php</code>). reportSummary requires pre-configured reports in GUI. Custom login via <code>scripts/custom_login.php</code> enables LDAP/SSO - requires unique numeric ID per user to avoid shared settings. Antivirus may delete scripts with shell_exec - disable with DISABLE_ANTIVIRUS or move to external file. Branding: BRAND_NAME for product name, BRAND_SHARESITE/BRAND_DOMAIN in brand.php for custom share domain. |
|
| |
|
| '''Keywords:''' custom login, LDAP, LDAP troubleshooting, CLI testing, group permissions, is_admin, id_group, LDAP users cannot view CDR, groupIdNum, CDR API, HTTP API, getVoipCalls, getVoiceRecording, active calls, listActiveCalls, programmatic active calls, real-time call monitoring, check active calls programmatically, reportSummary, getShareURL, getShareURL custom header, share URL by custom SIP header, custom header query, getShareURL custom header params, getPCAP, PCAP download, success:false API error, curl data-urlencode, URL encoding, params encoding, PCAP API curl example, SIP history, license check, license lockout, concurrent calls limit, delete CDRs manually, license upgrade, branding, BRAND_NAME, brand.php, system_configuration.php, custom company name, customize GUI header, customize alert emails, share.voipmonitor.org, BRAND_SHARESITE, BRAND_DOMAIN, wildcard, wildcards, LIKE filter, percent sign, %25, URL encode percent, API filter, wildcard filter, SQL LIKE, caller filter, called filter, fcaller, fcalled, antivirus, antivirus protection, file deleted, shell_exec, custom_login.php deleted, DISABLE_ANTIVIRUS, custom script deleted, GUI antivirus scanner, security scanner, PHP shell commands, webshell detection, malicious patterns, move shell commands, external PHP file, include external file | | '''Keywords:''' web api, http api, api.php, sql.php, getVoipCalls, getVoiceRecording, getPCAP, getShareURL, listActiveCalls, reportSummary, handleActiveCall, CDR filter, custom login, LDAP, authentication, session, curl, JSON, branding, BRAND_NAME, BRAND_SHARESITE, antivirus, DISABLE_ANTIVIRUS, unique user id, uidnumber |
|
| |
|
| '''Key Questions:''' | | '''Key Questions:''' |
| * Why is my custom_login.php file being automatically deleted? | | * What is the correct VoIPmonitor API endpoint path? |
| * How do I prevent custom_login.php from being deleted by VoIPmonitor's antivirus? | | * How do I retrieve CDRs via the VoIPmonitor API? |
| * What causes VoIPmonitor GUI to delete PHP files in the scripts directory?
| | * How to download PCAP or voice recordings via API? |
| * How to disable antivirus in VoIPmonitor GUI?
| | * How to list active calls via API? |
| * What is DISABLE_ANTIVIRUS in system_configuration.php?
| | * How to generate reports via API? |
| * Which PHP functions trigger VoIPmonitor antivirus scanner?
| | * How to configure LDAP authentication for VoIPmonitor? |
| * How to use shell_exec in custom_login.php without triggering antivirus? | | * Why do LDAP users share settings? (need unique ID) |
| * Can VoIPmonitor antivirus detect webshell patterns?
| | * Why is custom_login.php being deleted? (antivirus) |
| * Should I move shell commands to external PHP file for custom login?
| | * How to customize VoIPmonitor branding? |
| * How to include external PHP file in custom_login.php? | | * What's the difference between api.php and sql.php? |
| * How to query getShareURL API using a custom SIP header?
| |
| * Can I specify custom SIP headers in getShareURL API request?
| |
| * How to retrieve share URL by custom header instead of callId? | |
| * What to do when non-admin users cannot log in via LDAP?
| |
| * How to test LDAP connectivity in custom_login.php? | |
| * Why can LDAP users authenticate but not view CDRs even with correct group permissions? | |
| * How does the is_admin flag affect group permissions in custom_login.php? | |
| * How to set up id_group for LDAP users to inherit GUI group permissions? | |
| * What is the fallback mechanism for users without valid group roles? | |
| * What parameters does the CDR HTTP API support?
| |
| * How to share CDRs via API?
| |
| * What is HTTP API 2 and its methods?
| |
| * How to retrieve PCAP files via API?
| |
| * Why does getPCAP API return success:false?
| |
| * How to use curl --data-urlencode with getPCAP API?
| |
| * What is the correct curl syntax for getPCAP endpoint?
| |
| * How to URL encode params string in API requests?
| |
| * How to use wildcards in API filter parameters? | | * How to use wildcards in API filter parameters? |
| * How to filter caller numbers using LIKE pattern in API?
| |
| * Do I need to URL encode the percent sign (%) when using wildcards in API?
| |
| * How to use %25 wildcard character in API requests?
| |
| * How to filter for caller numbers starting with specific prefix using API?
| |
| * Does the percent sign wildcard need encoding when used in GET parameters?
| |
| * How to retrieve SIP history?
| |
| * How to check VoIPmonitor license via API?
| |
| * How to resolve GUI lockout due to exceeding licensed channel limit?
| |
| * Can I manually delete CDRs to unlock a locked VoIPmonitor license?
| |
| * How do I upgrade my VoIPmonitor license tier?
| |
| * What are the options when the license concurrent calls limit is exceeded?
| |
| * How to replace the default VoIPmonitor branding with a custom company name?
| |
| * How to change the product name in the GUI header and alert emails?
| |
| * How to use BRAND_NAME constant to customize VoIPmonitor branding?
| |
| * How to customize share.voipmonitor.org domain with my own domain?
| |
| * How to use brand.php for custom branding in VoIPmonitor?
| |
| * How do I programmatically check if a call to a specific phone number is currently active?
| |
| * What is the listActiveCalls API used for?
| |
| * How to retrieve active calls from all connected sensors via API?
| |
| * What is the difference between listActiveCalls and getVoipCalls?
| |