|
|
| Line 1: |
Line 1: |
| = VoIPmonitor Web API = | | = VoIPmonitor Web API = |
|
| |
|
| This page documents VoIPmonitor's Web API for programmatic access to CDR data, recordings, active calls, and system functions. | | This page documents VoIPmonitor's Web APIs for programmatic access to CDR data, recordings, active calls, and system functions. |
|
| |
|
| == API Overview == | | == Overview == |
|
| |
|
| <kroki lang="mermaid"> | | <kroki lang="mermaid"> |
| %%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 35}}}%% | | %%{init: {'flowchart': {'nodeSpacing': 15, 'rankSpacing': 30}}}%% |
| flowchart LR | | flowchart LR |
| subgraph Client | | subgraph Client |
| Line 14: |
Line 14: |
| B["/php/api.php"] | | B["/php/api.php"] |
| C["/php/model/sql.php"] | | C["/php/model/sql.php"] |
| D["/php/pcap.php"]
| |
| end | | end |
| subgraph Tasks | | subgraph Tasks |
| Line 23: |
Line 22: |
| I[getShareURL] | | I[getShareURL] |
| end | | end |
| A -->|HTTP POST/GET| B | | A -->|user/password| B |
| A -->|Session-based| C | | A -->|Session cookie| C |
| A -->|Direct| D
| | B --> E & F & G & H & I |
| B --> E | |
| B --> F
| |
| B --> G
| |
| B --> H
| |
| B --> I
| |
| </kroki> | | </kroki> |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! API Type !! Endpoint !! Authentication !! Use Case | | ! API !! Endpoint !! Authentication !! Use Case |
| |- | | |- |
| | '''HTTP API 2''' || <code>/php/api.php</code> || User/password params || CDR queries, recordings, PCAP | | | '''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 | | | '''CDR HTTP API''' || <code>/php/model/sql.php</code> || Session cookie || Advanced CDR filtering with GUI filters |
| |-
| |
| | '''Custom Login''' || <code>scripts/custom_login.php</code> || LDAP/Custom || GUI authentication
| |
| |} | | |} |
|
| |
|
| == Important: Correct API Endpoint Path == | | {{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.}} |
|
| |
|
| All API requests MUST be sent to the correct endpoint path:
| | == HTTP API 2 == |
|
| |
|
| * '''Correct:''' <code>/voipmonitor/php/api.php</code>
| | Preferred API for programmatic access. Requests via HTTP POST or GET to <code>/php/api.php</code>. |
| * '''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.
| | === Authentication === |
|
| |
|
| {{Warning|1=If you see an '''"action parameter missing"''' error, verify you are using <code>/voipmonitor/php/api.php</code> and not <code>/voipmonitor/api.php</code>. This is a common mistake that causes this specific error message.}}
| | Include <code>user</code> and <code>password</code> parameters in every request: |
| | |
| If your VoIPmonitor GUI is installed in the default web root (/var/www/html), use:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| curl -X POST 'http://yourserver/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' | | curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms=...' |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| If using a subdirectory like /demo:
| | {{Note|1=API authentication uses local VoIPmonitor database credentials. It does NOT use LDAP or custom_login.php.}} |
|
| |
|
| <syntaxhighlight lang="bash">
| | '''Rate Limiting:''' Enable in GUI > Settings > System Configuration > "API maximal concurrent connections". |
| curl -X POST 'http://yourserver/demo/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD'
| |
| </syntaxhighlight>
| |
|
| |
|
| == Custom Login == | | === getVoipCalls === |
|
| |
|
| 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.
| | Retrieve CDR records by search criteria. |
|
| |
|
| '''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. | | '''Parameters:''' |
| | | {| class="wikitable" |
| === LDAP Example ===
| | |- |
| | | ! Parameter !! Description |
| Complete LDAP example available in GUI directory: scripts/ldap_custom_login_example.php.
| | |- |
| | | | <code>startTime</code> || Calls starting >= this time (required) |
| Ensure php-ldap package (or equivalent) is installed on the OS hosting the LDAP script.
| | |- |
| | | | <code>startTimeTo</code> || Calls starting <= this time |
| ==== Troubleshooting LDAP Login Issues ====
| | |- |
| | | | <code>callEnd</code> || Calls ending <= this time |
| 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.
| | |- |
| | | | <code>caller</code> / <code>called</code> || Caller/called number |
| ===== Step 1: Enable Debug Mode for CLI Testing =====
| | |- |
| | | | <code>callId</code> || SIP Call-ID |
| Edit the <code>custom_login.php</code> file and '''uncomment the debug block''' at the top of the script (if present):
| | |- |
| | | <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 |
| | |} |
|
| |
|
| <syntaxhighlight lang="php">
| | '''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');
| |
| </syntaxhighlight>
| |
| | |
| ===== Step 2: Run Script Manually =====
| |
| | |
| Execute the script directly from the command line:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| cd /var/www/html/scripts/
| | # HTTP GET - by time range and caller |
| php custom_login.php
| | curl 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD¶ms={"startTime":"2024-01-01","startTimeTo":"2024-01-31","caller":"123456"}' |
| </syntaxhighlight>
| |
|
| |
|
| This will test the script with the hardcoded 'testuser' credentials and output any connection failure messages directly to the console.
| | # 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 |
|
| |
|
| ===== Step 3: Check LDAP Server Configuration =====
| | # With custom headers |
| | | curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ |
| Verify the LDAP server configuration in your script:
| | --data-urlencode 'params={"startTime":"2024-01-01","caller":"123","customHeaders":"X-Custom-Header"}' |
| | |
| * 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">
| |
| telnet <ldap_server_ip> <ldap_port>
| |
| # or
| |
| nc -zv <ldap_server_ip> <ldap_port>
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ===== Step 4: Verify Required Dependencies ===== | | === getVoiceRecording === |
|
| |
|
| Ensure the LDAP PHP extension is installed:
| | Download audio recording (WAV format). |
|
| |
|
| <syntaxhighlight lang="bash">
| | '''Parameters:''' |
| # Debian/Ubuntu
| | {| class="wikitable" |
| php -m | grep ldap
| | |- |
| sudo apt-get install php-ldap
| | ! Parameter !! Description |
| | | |- |
| # CentOS/RHEL
| | | <code>cdrId</code> || Database CDR ID (preferred) |
| php -m | grep ldap
| | |- |
| sudo yum install php-ldap
| | | <code>callId</code> || SIP Call-ID |
| </syntaxhighlight>
| | |- |
| | | | <code>calldate</code> || Date hint (default: today) |
| ===== Step 5: Check User Mapping =====
| | |- |
| | | | <code>zip</code> || <code>true</code> = return ZIP archive |
| 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:
| | |- |
| | | | <code>ogg</code> || <code>true</code> = return OGG format |
| # The user exists in the VoIPmonitor local database (<code>users</code> table)
| | |- |
| # The script correctly queries the local database to retrieve the user's ID
| | | <code>saveaudio_afterconnect</code> || <code>"yes"</code> = audio only after call connect |
| # The returned array includes the <code>id</code> field
| | |} |
| | |
| Create users in the GUI (Settings → Users) with the same usernames as in your LDAP directory if you require local user record mapping.
| |
| | |
| ===== Step 5.5: Ensure Unique User IDs for Individual Settings =====
| |
| | |
| '''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.
| |
| | |
| ====== Symptoms of Non-Unique IDs ======
| |
| | |
| 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.
| |
| | |
| ====== 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>:
| |
| | |
| <syntaxhighlight lang="php">
| |
| <?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
| |
| $search = ldap_search($connect, $dn, "(uid=$user)", array('uidnumber', 'cn'));
| |
| $res_id = ldap_get_entries($connect, $search);
| |
| | |
| // Extract unique identifier from LDAP
| |
| $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!
| |
| ));
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
| | |
| '''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 ======
| | '''Examples:''' |
| | |
| Verify that different users return different IDs by running your script manually:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| cd /var/www/html/scripts/
| | # By CDR ID |
| PHP_USER=user1 php -r 'require "custom_login.php"; var_dump(custom_login("user1", "test"));'
| | curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":12345}' > call.wav |
| PHP_USER=user2 php -r 'require "custom_login.php"; var_dump(custom_login("user2", "test"));'
| |
| </syntaxhighlight>
| |
|
| |
|
| Ensure the <code>["id"]</code> values differ between users.
| | # By Call-ID |
| | curl 'http://server/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"abc123"}' > call.wav |
|
| |
|
| ===== Step 6: LDAP Users Cannot View CDRs Despite Being Assigned to Groups =====
| | # Multiple recordings (returns ZIP) |
| | | echo '{"task":"getVoiceRecording","user":"USER","password":"PASSWORD","params":{"cdrId":[6,7]}}' | php api.php > calls.zip |
| 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.
| |
| | |
| 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.
| |
| | |
| To fix this issue:
| |
| | |
| # Ensure your script returns the correct <code>id_group</code> value that matches the group assigned in the GUI Users & Audit section.
| |
| # 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:
| |
| | |
| <syntaxhighlight lang="php">
| |
| 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
| |
| ));
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| <ol start="3">
| | === getPCAP === |
| <li>Debug the <code>$groupIdNum</code> variable by running your script manually from the command line:</li>
| |
| </ol>
| |
|
| |
|
| <syntaxhighlight lang="bash">
| | Download PCAP file. Automatically merges multiple legs and returns ZIP if needed. |
| cd /var/www/html/scripts/
| |
| php custom_login.php
| |
| </syntaxhighlight>
| |
|
| |
|
| Check the debug output to verify that <code>$groupIdNum</code> is being assigned the correct integer value before the return statement.
| | '''Parameters:''' |
| | {| class="wikitable" |
| | |- |
| | ! 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 |
| | |} |
|
| |
|
| <ol start="4">
| | '''Examples:''' |
| <li>Implement a fallback mechanism for users without a valid role to prevent login failures:</li>
| |
| </ol>
| |
| | |
| <syntaxhighlight lang="php">
| |
| if ($groupIdNum === 0){
| |
| debug_log("User $user does not have valid permissions to login, setting the group 1 with low permissions");
| |
| $groupIdNum = 1;
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| This ensures users without group mappings can still log in with restricted access rather than being completely blocked.
| |
| | |
| === File Being Automatically Deleted (Antivirus Protection) ===
| |
| | |
| ==== Issue Overview ====
| |
| | |
| 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.
| |
| | |
| 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>
| |
| | |
| After adding this line, the antivirus scanner will be disabled and your custom scripts will not be deleted.
| |
| | |
| '''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). | |
| | |
| ==== Solution 2: Move Shell Commands to External File (Recommended) ====
| |
| | |
| 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>.
| |
| | |
| ===== Step 1: Create External Script Outside Web Root =====
| |
| | |
| 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/ | | # By CDR ID |
| mkdir -p /opt/voipmonitor-custom
| | curl 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD¶ms={"cdrId":"12345"}' > call.pcap |
| nano /opt/voipmonitor-custom/ldap_check.php
| |
| </syntaxhighlight>
| |
| | |
| ===== Step 2: Move Shell Command Code to External File ===== | |
| | |
| <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) {
| | # By Call-ID with merge |
| $output = shell_exec("ping -c 1 -W 1 $server 2>&1");
| | curl -G 'http://server/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \ |
| return $output;
| | --data-urlencode 'params={"callId":"abc123","cidInterval":60,"cidMerge":true}' |
| }
| |
| | |
| function run_custom_checks() {
| |
| $result = exec("/usr/local/bin/custom-auth-check", $output, $return_var);
| |
| return array(
| |
| 'output' => $output,
| |
| 'return_var' => $return_var
| |
| );
| |
| }
| |
| ?>
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ===== Step 3: Include External Script in custom_login.php =====
| | {{Tip|Use <code>curl -G --data-urlencode</code> for complex JSON params to avoid encoding issues.}} |
|
| |
|
| <code><GUI_INSTALL_DIR>/scripts/custom_login.php</code>:
| | === listActiveCalls === |
|
| |
|
| <syntaxhighlight lang="php">
| | Get currently active calls from sensor. |
| <?php
| |
| // Safe to include - no direct shell commands in this file
| |
| require_once('/opt/voipmonitor-custom/ldap_check.php');
| |
|
| |
|
| function custom_login($user, $password) {
| | '''Parameters:''' <code>sensorId</code> (optional), <code>callId</code> (optional) |
| debug_log('custom_login');
| |
| | |
| // Example: Check LDAP server connectivity using external function
| |
| $ping_result = check_ldap_connectivity('ldap.example.com');
| |
| | |
| // Example: Run custom authentication checks
| |
| $check = run_custom_checks();
| |
| | |
| return(array(
| |
| 'username' => $user,
| |
| 'is_admin' => false,
| |
| 'id' => $userIdUniqueNum
| |
| ));
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
| | |
| ==== Summary ====
| |
| | |
| * '''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 ===
| |
| | |
| Custom login enables implementing your own mechanism. Create file: scripts/custom_login.php with function custom_login.
| |
| | |
| Location: <code><GUI_INSTALL_DIR>/scripts/custom_login.php</code>
| |
| | |
| <syntaxhighlight lang="php">
| |
| <?php
| |
| function custom_login($user, $password) {
| |
| debug_log('custom_login');
| |
| return(array(
| |
| 'username' => $user,
| |
| 'is_admin' => false,
| |
| 'id' => $userIdUniqueNum, // required numeric unique identifier for each user
| |
| // 'id_group' => 1, // you can set user rights with the gui's group id too
| |
| 'enable_sensors' => array(2,3)
| |
| ));
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
| | |
| === Azure AD SSO via Custom Login Script ===
| |
| | |
| You can integrate Azure AD (Microsoft Entra ID) using custom_login.php with SAML or OIDC libraries.
| |
| | |
| '''Note:''' For OIDC integration, consider using [[REMOTE_USER_Authentication|Apache mod_auth_openidc]] instead, which is a simpler approach. Use custom_login.php only if you need custom logic beyond basic OIDC/SAML authentication.
| |
| | |
| ==== Prerequisites ====
| |
| | |
| * Install SAML or OIDC PHP library (e.g., league/oauth2-client, simplesamlphp/simplesamlphp)
| |
| * Azure AD registered application with Redirect URI pointing to your VoIPmonitor GUI
| |
| * Azure AD Tenant ID, Client ID, and Client Secret
| |
| | |
| ==== Basic Implementation Flow ====
| |
| | |
| # Receive SAML/OIDC assertion from identity provider
| |
| # Validate the assertion against Azure AD
| |
| # Extract user email/attributes from the assertion
| |
| # Query VoIPmonitor database for matching user
| |
| # Return user permissions array
| |
| | |
| ==== Example: Azure AD via OIDC ====
| |
| | |
| This example assumes you have an external SSO flow that validates the Azure AD token and passes the user's email:
| |
| | |
| <syntaxhighlight lang="php">
| |
| <?php
| |
| // custom_login.php - Azure AD OIDC example
| |
| | |
| require_once 'vendor/autoload.php';
| |
| | |
| // Your OIDC/SAML library initialization here
| |
| // This is a simplified example showing the structure
| |
| | |
| function custom_login($user, $password) {
| |
| debug_log('Azure AD custom_login: ' . $user);
| |
| | |
| // Step 1: For OIDC, $user is typically the email address
| |
| // For SAML, you might receive a token or assertion
| |
| $userEmail = $user;
| |
| | |
| // Step 2: Connect to VoIPmonitor database to find user or determine group
| |
| $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
| |
| mysql_select_db(DB_NAME, $link);
| |
| | |
| // Step 3: Map user to local user or determine group permissions
| |
| $query = sprintf("SELECT id FROM users WHERE user='%s'", mysql_real_escape_string($userEmail));
| |
| $result = mysql_query($query, $link);
| |
| | |
| if ($row = mysql_fetch_assoc($result)) {
| |
| // User exists: return exact VoIPmonitor user ID
| |
| $userId = $row['id'];
| |
| } else {
| |
| // User does not exist: use email hash for unique ID
| |
| // This prevents all unmapped users from sharing the same settings
| |
| $userId = crc32(strtolower(trim($userEmail)));
| |
| }
| |
| | |
| mysql_close($link);
| |
| | |
| // Step 4: Return array with user permissions
| |
| return(array(
| |
| 'username' => $userEmail,
| |
| 'is_admin' => false,
| |
| 'id' => $userId, // Must be unique for each user
| |
| // Uncomment to set group-based permissions:
| |
| // 'id_group' => 1, // Get from database or AD group mapping
| |
| 'email' => $userEmail
| |
| ));
| |
| }
| |
| ?>
| |
| </syntaxhighlight>
| |
| | |
| ==== Important Notes ====
| |
| | |
| * '''Uniqueness:''' The <code>id</code> field must be unique for each user. Using email hash (crc32) is recommended for unmapped users.
| |
| * '''Permissions:''' Users must exist in the VoIPmonitor GUI (Users & Audit) for permissions, or configure a default user.
| |
| * '''Token Validation:''' This example assumes external OIDC/SAML validation. In production, validate tokens before calling custom_login.
| |
| * '''Group Mapping:''' Map Azure AD groups to VoIPmonitor groups by querying database or hardcoding group mappings in the script.
| |
| * '''Alternative:''' [[REMOTE_USER_Authentication|Apache mod_auth_openidc]] provides a simpler OIDC integration without custom PHP code.
| |
| | |
| ==== Testing ====
| |
| | |
| Test your Azure AD integration:
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| # Test with valid Azure AD email
| | curl 'http://server/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD¶ms={"sensorId":"1"}' |
| cd /var/www/voipmonitor/scripts/
| |
| php custom_login.php
| |
| | |
| # If debug block is enabled at top of script, it will run automatically
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| '''Returned array parameters:'''
| | {{Note|1=IP addresses in response are integers. Convert with <code>INET_NTOA()</code> in MySQL or equivalent in your 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.
| | === handleActiveCall === |
| * 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 == | |
| | |
| Retrieves CDR rows in JSON, using WEB GUI filters: [[Call_Detail_Record_-_CDR#Filter_Form_button]].
| |
| | |
| Requires valid session: [[GUI_automate_login]]. Send parameters via POST.
| |
| | |
| Disable authorization (safe environments): '''GUI > Settings > System Configuration > Disable authorization for API usage'''.
| |
| | |
| === CURL Notes ===
| |
|
| |
|
| Use -G and --data-urlencode for special characters (e.g., + in caller).
| | Pause/unpause RTP recording on active call. |
|
| |
|
| Example:
| | '''Parameters:''' |
| | * <code>sensorId</code> - Sensor number |
| | * <code>command</code> - <code>pausecall</code> or <code>unpausecall</code> |
| | * <code>callRef</code> - Call reference from listActiveCalls |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| curl -G -X GET 'http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ | | curl 'http://server/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD¶ms={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}' |
| --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"}]'
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| === Input === | | === getShareURL === |
|
| |
|
| HTTP POST address: php/model/sql.php
| | Generate public shareable link for a CDR. |
| | |
| ==== Important: Query Parameter Syntax ====
| |
| | |
| When building API requests, use '''equals signs (=)''' for parameter assignment in HTTP query strings, not colons.
| |
| | |
| * '''Correct:''' <code>&fcallerd_type=1&</code>
| |
| * '''Incorrect:''' <code>&fcallerd_type:1&</code>
| |
| | |
| 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.
| |
| | |
| '''Common Syntax Mistakes:'''
| |
| * 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.
| |
| | |
| ==== Mandatory Parameters ====
| |
|
| |
|
| | '''Parameters:''' |
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Parameter !! Description | | ! Parameter !! Description |
| |- | | |- |
| | <code>task</code> || <code>LISTING</code> | | | <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>module</code> || <code>CDR</code> | | | <code>sip_history</code> || <code>true</code> = SIP history only (no RTP) |
| |- | | |- |
| | <code>fdatefrom</code> or <code>fdateto</code> || Required to prevent MySQL overload | | | <code>anonIps</code> || <code>true</code> = anonymize IPs |
| | |- |
| | | <code>validDays</code> || Link validity in days |
| |} | | |} |
|
| |
|
| ==== Suppress Results ==== | | <syntaxhighlight lang="bash"> |
| | curl 'http://server/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"abc123","rtp":true,"validDays":15}' |
| | </syntaxhighlight> |
|
| |
|
| Set <code>suppress_results=1</code> to return only the total count:
| | === reportSummary === |
|
| |
|
| <syntaxhighlight lang="json"> | | Generate pre-configured summary report as image or JSON. |
| {"total":"135"}
| | |
| </syntaxhighlight> | | {{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.}} |
|
| |
|
| ==== Datetime Range ==== | | '''Parameters:''' |
| | * <code>report_name</code> - Description field from GUI report |
| | * <code>datetime_from</code> / <code>datetime_to</code> - Date range |
| | * <code>json</code> - <code>true</code> = return JSON instead of image |
|
| |
|
| <syntaxhighlight lang="text"> | | <syntaxhighlight lang="bash"> |
| fdatefrom=1986-01-09T00:00:00
| | 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"}' |
| fdateto=2013-05-28T00:00:00
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ==== Caller / Called Numbers ==== | | === Other Tasks === |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Parameter !! Description | | ! Task !! Description |
| |- | | |- |
| | <code>fcaller</code> || Caller number | | | <code>listCdrIds</code> || List CDR IDs with basic info. Params: <code>offset</code>, <code>size</code> |
| |- | | |- |
| | <code>fcalled</code> || Called number | | | <code>getAudioGraph</code> || Get spectrogram/waveform image. Params: <code>cdrId</code>, <code>type</code> (S/P/ALL), <code>side</code> (L/R) |
| |-
| |
| | <code>fcallerd_type</code> || <code>0</code> = search fcaller OR fcalled (value from fcaller); <code>1</code> = search fcaller AND fcalled
| |
| |} | | |} |
|
| |
|
| ==== Using Wildcards in Filters ==== | | == CDR HTTP API == |
|
| |
|
| 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.
| | Session-based API using GUI filter parameters. Requires login first. |
|
| |
|
| '''Example: Filter for caller numbers starting with "00"'''
| | === Authentication === |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| curl -G -X GET 'http://localhost/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ | | # Step 1: Login and get session |
| --data-urlencode 'params={"startTime":"2023-01-01","endTime":"2023-12-31","caller":"%2500"}'
| | curl -X POST 'http://server/php/model/sql.php?module=bypass_login&user=USER&pass=PASSWORD' |
| | # Returns: {"SID":"abc123...","cookie_name":"PHPSESSID","success":true} |
| | |
| | # Step 2: Use session cookie for requests |
| | curl -X POST --cookie "PHPSESSID=abc123..." \ |
| | 'http://server/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2024-01-01T00:00:00&fcaller=123' |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| '''Important Notes:'''
| | {{Note|1=If GUI is in subdirectory (e.g., <code>/demo</code>), cookie name changes to <code>PHPSESSID-demo</code>.}} |
| * 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
| |
| * 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
| |
|
| |
|
| '''Common wildcard patterns:''' | | '''Disable authorization:''' GUI > Settings > System Configuration > "Disable authorization for API usage" |
| * <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 ==== | | === Filter Parameters === |
| | |
| {| class="wikitable"
| |
| |-
| |
| ! Parameter !! Description
| |
| |-
| |
| | <code>fcaller_domain</code> || Caller domain
| |
| |-
| |
| | <code>fcalled_domain</code> || Called domain
| |
| |-
| |
| | <code>fcallerd_domain_type</code> || <code>0</code> = search fcaller OR fcalled; <code>1</code> = search fcaller AND fcalled
| |
| |}
| |
|
| |
|
| ==== Caller ID Name ==== | | '''Mandatory:''' <code>task=LISTING</code>, <code>module=CDR</code>, and at least one of <code>fdatefrom</code> or <code>fdateto</code>. |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Parameter !! Description | | ! Parameter !! Description !! Example |
| |-
| |
| | <code>fcallername</code> || Caller name
| |
| |}
| |
| | |
| ==== SIP Caller / Called IP ====
| |
| | |
| {| class="wikitable"
| |
| |- | | |- |
| ! Parameter !! Description
| | | <code>fdatefrom</code> / <code>fdateto</code> || Date range || <code>2024-01-01T00:00:00</code> |
| |- | | |- |
| | <code>fsipcallerip</code> || Caller SIP IP | | | <code>fcaller</code> / <code>fcalled</code> || Caller/called number || <code>123456</code> |
| |- | | |- |
| | <code>fsipcalledip</code> || Called SIP IP | | | <code>fcallerd_type</code> || <code>0</code>=OR, <code>1</code>=AND || <code>1</code> |
| |- | | |- |
| | <code>fsipcallerdip_type</code> || <code>0</code> = search fcaller OR fcalled; <code>1</code> = search fcaller AND fcalled | | | <code>fcaller_domain</code> / <code>fcalled_domain</code> || SIP domain || <code>sip.example.com</code> |
| |}
| |
| | |
| ==== RTP Source / Destination IP ====
| |
| | |
| {| class="wikitable"
| |
| |- | | |- |
| ! Parameter !! Description
| | | <code>fsipcallerip</code> / <code>fsipcalledip</code> || SIP IP address || <code>192.168.1.1</code> |
| |- | | |- |
| | <code>fa_saddr</code> || RTP source IP (e.g., <code>192.168.0.1</code>) | | | <code>fcallid</code> || SIP Call-ID || <code>abc123</code> |
| |- | | |- |
| | <code>fb_saddr</code> || RTP destination IP (e.g., <code>192.168.0.2</code>) | | | <code>fsipresponse</code> || SIP response code || <code>503</code> |
| |- | | |- |
| | <code>fab_saddr_type</code> || <code>0</code> = search fa OR fb; <code>1</code> = search fa AND fb | | | <code>fdurationgt</code> / <code>fdurationlt</code> || Duration (seconds) || <code>10</code> |
| |} | |
| | |
| ==== Codecs ====
| |
| | |
| Parameter: <code>fcodec</code> - comma-separated list of codec numbers (e.g., <code>4, 12</code>)
| |
| | |
| '''Available codec values:'''
| |
| | |
| <syntaxhighlight lang="php">
| |
| 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);
| |
| </syntaxhighlight>
| |
| | |
| ==== Call Duration ====
| |
| | |
| {| class="wikitable"
| |
| |- | | |- |
| ! Parameter !! Description !! Example
| | | <code>fsensor_id</code> || Sensor ID || <code>1</code> |
| |- | | |- |
| | <code>fdurationgt</code> || Duration greater than (seconds) || <code>10</code> | | | <code>fcodec</code> || Codec numbers (comma-sep) || <code>0,8</code> |
| |- | | |- |
| | <code>fdurationlt</code> || Duration less than (seconds) || <code>30</code> | | | <code>suppress_results</code> || <code>1</code>=count only || <code>1</code> |
| |} | | |} |
|
| |
|
| ==== PDD (Post Dial Delay) ====
| | '''Paging:''' <code>page</code>, <code>start</code>, <code>limit</code> |
|
| |
|
| {| class="wikitable" | | '''Sorting:''' <code>sort=[{"property":"calldate","direction":"DESC"}]</code> |
| |-
| |
| ! Parameter !! Description !! Example
| |
| |-
| |
| | <code>fpddgt</code> || PDD greater than (seconds) || <code>10</code>
| |
| |-
| |
| | <code>fpddlt</code> || PDD less than (seconds) || <code>30</code>
| |
| |}
| |
|
| |
|
| ==== SIP Response Code ==== | | {{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).}} |
|
| |
|
| {| class="wikitable"
| | === Wildcards === |
| |-
| |
| ! Parameter !! Description !! Example
| |
| |-
| |
| | <code>fsipresponse</code> || SIP response code || <code>503</code>
| |
| |}
| |
|
| |
|
| ==== Interrupted Call ====
| | Use <code>%25</code> (URL-encoded <code>%</code>) for SQL LIKE patterns: |
|
| |
|
| {| class="wikitable"
| | <syntaxhighlight lang="bash"> |
| |-
| | # Caller starting with "00" |
| ! Parameter !! Values
| | curl -G 'http://server/php/api.php?task=getVoipCalls&user=USER&password=PASSWORD' \ |
| |-
| | --data-urlencode 'params={"startTime":"2024-01-01","caller":"%2500%25"}' |
| | <code>fbye</code> || <code>true</code> or <code>false</code>
| | </syntaxhighlight> |
| |}
| |
|
| |
|
| ==== Direction (by trunk) ==== | | === Codec Values === |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
| ! Parameter !! Values | | ! Value !! Codec !! Value !! Codec |
| |- | | |- |
| | <code>ftrunk</code> || <code>true</code> or <code>false</code> | | | 0 || PCMU (G.711 μ-law) || 8 || PCMA (G.711 A-law) |
| |} | |
| | |
| ==== SIP User Agent ====
| |
| | |
| {| class="wikitable"
| |
| |- | | |- |
| ! Parameter !! Description
| | | 3 || GSM || 9 || G.722 |
| |- | |
| | <code>fa_ua</code> || Caller agent string | |
| |- | | |- |
| | <code>fb_ua</code> || Called agent string | | | 4 || G.723 || 12 || QCELP |
| |- | | |- |
| | <code>fab_ua_type</code> || <code>0</code> = search fa OR fb; <code>1</code> = search fa AND fb | | | 18 || G.729 || 97 || iLBC |
| |} | |
| | |
| ==== SIP Call-ID Header ====
| |
| | |
| {| class="wikitable"
| |
| |- | | |- |
| ! Parameter !! Description
| | | 98 || Speex || 301-305 || SILK variants |
| |- | | |- |
| | <code>fcallid</code> || SIP Call-ID string | | | 306-308 || iSAC variants || 1000 || T.38 (Fax) |
| |} | | |} |
|
| |
|
| ==== SIP Sensor ID ==== | | === RTP Quality Filters === |
|
| |
|
| {| class="wikitable" | | {| class="wikitable" |
| Line 809: |
Line 335: |
| ! Parameter !! Description | | ! Parameter !! Description |
| |- | | |- |
| | <code>fsensor_id</code> || Database sensor ID | | | <code>fmosf1</code>, <code>fmosf2</code>, <code>fmosadapt</code> || MOS score filters |
| |}
| |
| | |
| ==== Paging ====
| |
| | |
| {| class="wikitable"
| |
| |- | | |- |
| ! Parameter !! Description !! Example
| | | <code>frtcp_maxjitter</code>, <code>frtcp_avgjitter</code> || RTCP jitter |
| |- | | |- |
| | <code>page</code> || Page number || <code>1</code> | | | <code>frtcp_maxfr</code>, <code>frtcp_avgfr</code> || RTCP frame rate |
| |- | | |- |
| | <code>start</code> || Starting offset || <code>0</code> | | | <code>floss1</code> - <code>floss10</code> || Packet loss distribution |
| |- | | |- |
| | <code>limit</code> || Records per page || <code>30</code> | | | <code>f_d50</code>, <code>f_d70</code>, <code>f_d90</code>, ... || Delay distribution (50ms, 70ms, etc.) |
| |} | | |} |
|
| |
|
| ==== Ordering ==== | | == Utility Endpoints == |
| | |
| <syntaxhighlight lang="json">
| |
| sort:[{"property":"calldate2","direction":"DESC"}]
| |
| </syntaxhighlight>
| |
| | |
| ==== Special Ordering ====
| |
| | |
| Available ordering parameters (use with <code>=1</code>):
| |
| * <code>orderByLoss</code>, <code>orderByDelay</code>, <code>orderByFixed1</code>, <code>orderByFixed2</code>, <code>orderByAdapt</code>
| |
| * <code>orderByCallDuration_asc</code>, <code>orderByCallDuration_desc</code>
| |
| * <code>orderBySrcSIP_IP_asc</code>, <code>orderBySrcSIP_IP_desc</code>
| |
| * <code>orderByDstSIP_IP_asc</code>, <code>orderByDstSIP_IP_desc</code>
| |
| * <code>orderBySrcNumber_asc</code>, <code>orderBySrcNumber_desc</code>
| |
| * <code>orderByDstNumber_asc</code>, <code>orderByDstNumber_desc</code>
| |
| * <code>orderByCallerName_asc</code>, <code>orderByCallerName_desc</code>
| |
| * <code>orderByLastSIPrespNum_asc</code>, <code>orderByLastSIPrespNum_desc</code>
| |
| | |
| ==== RTP ====
| |
| | |
| Available RTP filter parameters:
| |
| * RTCP: <code>frtcp_maxjitter</code>, <code>frtcp_avgjitter</code>, <code>frtcp_maxfr</code>, <code>frtcp_avgfr</code>
| |
| * MOS: <code>fmosf1</code>, <code>fmosf2</code>, <code>fmosadapt</code>
| |
| * Delay distribution: <code>f_d50</code>, <code>f_d70</code>, <code>f_d90</code>, <code>f_d120</code>, <code>f_d150</code>, <code>f_d200</code>, <code>f_d300</code>
| |
| * Packet loss: <code>floss1</code> through <code>floss10</code>
| |
| * Template: <code>ffilterTemplate</code>
| |
| | |
| === Output ===
| |
|
| |
|
| JSON formatted array of CDR.
| | === Direct PCAP Download === |
| | |
| ==== GUI in Default DocumentRoot ==== | |
| | |
| Example for /var/www/html
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| curl -X POST '192.168.76.201/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor' | | curl 'http://server/php/pcap.php?id=12345' # Full PCAP |
| | curl 'http://server/php/pcap.php?id=12345&disable_rtp=1' # SIP only |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Returns something like this:
| | === CDR URL for Browser === |
|
| |
|
| <syntaxhighlight lang="json"> | | <syntaxhighlight lang="text"> |
| {"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID","success":true,"_vm_version":240034,"_debug":false} | | http://server/admin.php?cdr_filter={fcallid:"abc123"} |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Take the SID which you will put to cookie_name variable:
| | === SIP History === |
|
| |
|
| <syntaxhighlight lang="bash">
| | Requires session authentication first. |
| 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"
| |
| </syntaxhighlight>
| |
| | |
| ==== GUI in Demo Subdirectory ====
| |
| | |
| Example for /var/www/html/demo
| |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| curl -X POST '192.168.76.201/demo/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor' | | # JSON data |
| </syntaxhighlight>
| | curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief_data&id=12345' |
|
| |
|
| Returns something like this:
| | # HTML table |
| | curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=brief&id=12345' |
|
| |
|
| <syntaxhighlight lang="json">
| | # MSC diagram |
| {"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID-demo","success":true,"_vm_version":240034,"_debug":false}
| | curl --cookie "PHPSESSID=..." 'http://server/php/pcap2text.php?action=getMSC&id=12345' |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| Take the SID which you will put to cookie_name variable:
| | === License Check === |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| curl -X POST -k --cookie "PHPSESSID-demo=ahs2ubdhc0ukb262be60v900ko" \ | | # Basic license check |
| "http://192.168.76.201/demo/php/model/sql.php?task=LISTING&module=CDR&fdatefrom=2013-05-08T00:00:00&fcaller=190"
| | curl 'http://server/php/apilicensecheck.php?task=licenseCheck' |
| </syntaxhighlight>
| |
|
| |
|
| ==== Example Output for LISTING Task ====
| | # Concurrent calls limit check |
| | | curl 'http://server/php/apilicensecheck.php?task=licenseCallsLimitCheck' |
| 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 ===
| |
| | |
| <syntaxhighlight lang="text">
| |
| task=shareCdr¶ms={"type":"share_cdr_show","type2":null,"subType":"self_protected_link","id":[128024514],"emailFields":null} | |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| === Show Link Local Private === | | == Share CDR Configuration == |
|
| |
|
| <syntaxhighlight lang="text">
| | === Share Link Types === |
| task=shareCdr¶ms={"type":"share_cdr_show","type2":null,"subType":"self_login_link","id":[128024514],"emailFields":null}
| |
| </syntaxhighlight>
| |
|
| |
|
| === Show Link share.voipmonitor.org ===
| | Use <code>/php/model/utilities.php</code> with <code>task=shareCdr</code>: |
|
| |
|
| <syntaxhighlight lang="text">
| | {| class="wikitable" |
| task=shareCdr¶ms={"type":"share_cdr_show","type2":null,"subType":"share_link","id":[128024590],"emailFields":null}
| | |- |
| </syntaxhighlight> | | ! Type !! subType !! Description |
| | |- |
| | | 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 |
| | |} |
|
| |
|
| === Customizing Branding === | | === Custom 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: |
| # Save the file
| |
| # Log out of the GUI
| |
| # 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 === |
|
| |
|
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="php"> |
| http://voipmonitor/php/pcap.php?id=203800251
| | <?php |
| </syntaxhighlight>
| | function custom_login($user, $password) { |
| | // Authenticate against external system (LDAP, etc.) |
| | // ... |
|
| |
|
| Optionally filter out RTP: disable_rtp=1
| | return array( |
| | | 'username' => $user, |
| == Search CDR by URL == | | 'id' => $uniqueNumericId, // REQUIRED: Must be unique per user! |
| | | 'is_admin' => false, |
| Build URL for CDR display in browser:
| | 'id_group' => 1, // Optional: GUI group ID |
| | | 'enable_sensors' => array(1,2,3) // Optional: restrict to sensors |
| <syntaxhighlight lang="bash">
| | ); |
| http://localhost/admin.php?cdr_filter={fcallid:"uDR8mtloKFa1F8625VL2OXSFp.RuG73v"}
| |
| </syntaxhighlight>
| |
| | |
| cdr_filter uses same arguments as [[WEB_API#CDR_HTTP_API]]
| |
| | |
| == HTTP API 2 ==
| |
| | |
| Preferred API for audio files by search criteria. Requests via HTTP POST or GET.
| |
| | |
| === Rate Limit ===
| |
| | |
| Enable in '''GUI > Settings > System Configuration > API maximal concurrent connections'''. Limit per user.
| |
| | |
| === getVoipCalls === | |
| | |
| ==== Input Data ====
| |
| | |
| * startTime - all calls which started >= startTime
| |
| * startTimeTo - all calls which started <= startTimeTo (not mandatory)
| |
| * callEnd - all calls which ends <= callEnd (not mandatory)
| |
| * caller - caller number
| |
| * 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
| |
| | |
| <syntaxhighlight lang="json">
| |
| {
| |
| "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,
| |
| "[custom header name]": "[custom header value]",
| |
| "customHeaders": "Cell-ID-Caller,Cell-ID-Called"
| |
| }
| |
| } | | } |
| | ?> |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ==== Examples ==== | | {{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.}} |
|
| |
|
| ===== HTTP POST Simple Parameter ===== | | === LDAP Example === |
|
| |
|
| <syntaxhighlight lang="bash"> | | See <code>scripts/ldap_custom_login_example.php</code> in GUI directory. |
| 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
| | '''Requirements:''' <code>php-ldap</code> package installed. |
| </syntaxhighlight> | |
| | |
| ===== HTTP POST Array Parameter =====
| |
|
| |
|
| | '''Debug from CLI:''' |
| <syntaxhighlight lang="bash"> | | <syntaxhighlight lang="bash"> |
| 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
| | cd /var/www/html/scripts/ |
| </syntaxhighlight>
| | php custom_login.php |
| | |
| ===== HTTP GET Simple Parameter =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| 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"}
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ===== HTTP GET Array Parameter =====
| | Enable debug by uncommenting the debug block at top of script. |
|
| |
|
| <syntaxhighlight lang="text">
| | === Troubleshooting === |
| 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"}]
| |
| </syntaxhighlight>
| |
| | |
| === getVoiceRecording ===
| |
|
| |
|
| ==== Input Data ====
| | '''Users share settings:''' Return unique <code>id</code> per user (see warning above). |
|
| |
|
| <syntaxhighlight lang="json"> | | '''LDAP users can't view CDRs:''' Ensure <code>is_admin => false</code> and correct <code>id_group</code> is returned. |
| {
| |
| "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"
| |
| }
| |
| }
| |
| </syntaxhighlight> | |
|
| |
|
| Or:
| | '''Script being deleted:''' GUI antivirus deletes scripts with <code>shell_exec()</code>, <code>exec()</code>, etc. |
|
| |
|
| <syntaxhighlight lang="json"> | | '''Solutions:''' |
| {
| | # Disable antivirus in <code>config/system_configuration.php</code>: |
| "params": {
| | <syntaxhighlight lang="php"> |
| "customHeader": "name of the column in cdr_next table",
| | define('DISABLE_ANTIVIRUS', true); |
| "customHeaderValue": "your value",
| |
| "calldate": "2015-03-01"
| |
| }
| |
| }
| |
| </syntaxhighlight> | | </syntaxhighlight> |
| | # Or move shell commands to external file outside web directory and <code>require_once()</code> it. |
|
| |
|
| '''Note:''' calldate default value is current date, not used when cdrId set. The customHeader/customHeaderValue method is not recommended.
| | === Azure AD / Microsoft SSO === |
|
| |
|
| ===== Optional Parameters for Params =====
| | For Microsoft Entra ID integration, see [[Microsoft_Sign_in_usage]]. For Google, see [[Google_Sign_in_usage]]. |
|
| |
|
| * zip: true|false
| | === Return Array Parameters === |
| * ogg: true|false
| |
| * saveaudio_afterconnect: "yes"|"no"
| |
|
| |
|
| ==== Examples ====
| | Full list of available return parameters for custom_login: |
| | |
| ===== HTTP POST =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| 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
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET =====
| |
|
| |
|
| | <div class="mw-collapsible mw-collapsed"> |
| <syntaxhighlight lang="text"> | | <syntaxhighlight lang="text"> |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":4919}
| | username, name, id, id_group, group_name, is_admin, email |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"cdrId":4919,"saveaudio_afterconnect":"yes"}
| | enable_sensors - array of sensor IDs user can access |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"XXXXXXXXXXXXXXXXXXXXXX"}
| | can_cdr, can_write_cdr, can_play_audio, can_download_audio |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"XXXXXXXXXXXXXXXXXXXXXX","cidInterval":10}
| | can_listen_active_call, can_pcap, can_upload_pcap |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"callId":"XXXXXXXXXXXXXXXXXXXXXX","cidInterval":10,"saveaudio_afterconnect":"yes"}
| | can_messages, can_view_content_message, can_graphs |
| http://localhost/php/api.php?task=getVoiceRecording&user=USER&password=PASSWORD¶ms={"Cust_header":"CustValue"}
| | can_activecalls, can_register, can_sip_msg, can_livesniffer |
| | can_capture_rules, can_audit, can_alerts_edit, can_reports_edit |
| | can_dashboard, can_ipacc, can_mtr, can_sensors_operations |
| | can_network, can_edit_codebooks, hide_license_information |
| | ip, number, domain, vlan (user restrictions) |
| | custom_headers_cdr, custom_headers_message |
| | blocked, blocked_reason, req_2fa |
| </syntaxhighlight> | | </syntaxhighlight> |
| | </div> |
|
| |
|
| === listActiveCalls === | | == See Also == |
|
| |
|
| ==== Input Data ====
| | * [[Call_Detail_Record_-_CDR#Filter_Form_button|CDR Filter Form]] - GUI filter options |
| | | * [[Active_calls|Active Calls]] - Active calls monitoring |
| <syntaxhighlight lang="json">
| | * [[User_Management|User Management]] - User permissions |
| {
| | * [[Google_Sign_in_usage|Google Sign-In]] - Google OAuth setup |
| "task": "listActiveCalls",
| | * [[Microsoft_Sign_in_usage|Microsoft Sign-In]] - Azure AD setup |
| "user": "USER",
| |
| "password": "PASSWORD",
| |
| "params": {
| |
| "sensorId": "sensor number",
| |
| "callId": "callId"
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| Note: sensorId and callId are optional.
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| echo '{"task": "listActiveCalls", "user": "USER", "password": "PASSWORD", "params": {"sensorId": "1"}}' | php api.php
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| http://localhost/php/api.php?task=listActiveCalls&user=USER&password=PASSWORD¶ms={"sensorId":"1"}
| |
| </syntaxhighlight>
| |
| | |
| ===== 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>
| |
| | |
| === handleActiveCall ===
| |
| | |
| Start/stop RTP recording. Pausing saves empty RTP frames to PCAP; affects 'Listening to Active call' (no audio from paused calls).
| |
| | |
| ==== Input Data ====
| |
| | |
| <syntaxhighlight lang="json">
| |
| {
| |
| "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"
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| echo '{"task": "handleActiveCall", "user": "USER", "password": "PASSWORD", "params": {"sensorId": "1","command":"pausecall","callRef":"0x7f0e4c3c2680"}}' | php api.php
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| http://localhost/php/api.php?task=handleActiveCall&user=USER&password=PASSWORD¶ms={"sensorId":"1","command":"pausecall","callRef":"0x7f0e4c3c2680"}
| |
| </syntaxhighlight>
| |
| | |
| === 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:
| |
| # Navigate to '''GUI → Reports → Daily Report''' | |
| # Create a new report of type ''summary''
| |
| # Fill in the '''Description''' field - this text becomes your '''report_name''' for API calls
| |
| # Configure any charts or filters as needed for the report
| |
| # 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 ====
| |
| | |
| <syntaxhighlight lang="json">
| |
| {
| |
| "task": "reportSummary",
| |
| "user": "USER",
| |
| "password": "PASSWORD",
| |
| "params": {
| |
| "report_name": "the Description field from your GUI report",
| |
| "datetime_from": "YYYY-MM-DD or YYYY-MM-DD HH:MM:SS",
| |
| "datetime_to": "YYYY-MM-DD or YYYY-MM-DD HH:MM:SS",
| |
| "json": true
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| Note: json parameter returns JSON response instead of image.
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| 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
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| 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"}
| |
| </syntaxhighlight>
| |
| | |
| === 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>:
| |
| | |
| <syntaxhighlight lang="text">
| |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"X-My-Header":"test123","cidInterval":60,"sip_history":true}
| |
| </syntaxhighlight>
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP GET (with RTP, by SIP Call-ID) =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| 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}
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET (by database ID/CdrId) =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| curl -G -X POST 'http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD' \
| |
| --data-urlencode 'params={"cdrId":"12345","rtp":true}'
| |
| </syntaxhighlight>
| |
| | |
| This returns a URL in the format: <code>http://localhost/master/cdr.php?cdrId=12345&hash=HASH_VALUE</code>
| |
| | |
| ===== HTTP GET (only SIP) =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","cidInterval":60}
| |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225"}
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET (SIP History) =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","cidInterval":60,"sip_history":true}
| |
| http://localhost/php/api.php?task=getShareURL&user=USER&password=PASSWORD¶ms={"callId":"1502262225","sip_history":true}
| |
| </syntaxhighlight>
| |
| | |
| === getPCAP ===
| |
| | |
| Parameters like getVoiceRecording. Returns PCAP (merged legs if multiple in interval). Zip auto if multiple.
| |
| | |
| ==== curl with data-urlencode ====
| |
| | |
| 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.
| |
| | |
| ===== HTTP GET (with cURL recommended) =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| curl -G -X GET 'http://localhost/php/api.php?task=getPCAP&user=USER&password=PASSWORD' \
| |
| --data-urlencode 'params={"callId":"1502262225","cidInterval":60,"cidMerge":true}'
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP POST (with cURL recommended for complex params) =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| 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'
| |
| </syntaxhighlight>
| |
| | |
| ==== Direct URL Examples (GET) ====
| |
| | |
| These work for simple cases but may fail with special characters:
| |
| | |
| <syntaxhighlight lang="text">
| |
| 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}
| |
| </syntaxhighlight>
| |
| | |
| === listCdrIds ===
| |
| | |
| Returns 'size' CDR records with basic info, starting from 'offset' ID.
| |
| | |
| ==== Input Data ====
| |
| | |
| <syntaxhighlight lang="json">
| |
| {
| |
| "task": "listCdrIds",
| |
| "user": "USER",
| |
| "password": "PASSWORD",
| |
| "flags": "number (not required, bitfield: 0x01=simpleOutput, 0x02=date in ISO8601)",
| |
| "params": {
| |
| "offset": "starting cdr id",
| |
| "size": "number of cdr records to return"
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| ==== Examples ====
| |
| | |
| ===== HTTP POST =====
| |
| | |
| <syntaxhighlight lang="bash">
| |
| echo '{"task": "listCdrIds", "user": "USER", "password": "PASSWORD", "params": {"offset":"offset_num","size":"number of cdr records"}}' | php api.php
| |
| </syntaxhighlight>
| |
| | |
| ===== HTTP GET =====
| |
| | |
| <syntaxhighlight lang="text">
| |
| http://localhost/php/api.php?task=listCdrIds&user=USER&password=PASSWORD¶ms={"offset":"offset_num","size":"number_of_cdr_records"}
| |
| </syntaxhighlight>
| |
| | |
| === getAudioGraph ===
| |
| | |
| ==== Input Data ====
| |
| | |
| <syntaxhighlight lang="json">
| |
| {
| |
| "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, default 0)"
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| Note: The 'generating' parameter 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 ====
| |
| | |
| <syntaxhighlight lang="text">
| |
| 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"}
| |
| </syntaxhighlight>
| |
| | |
| {{Warning|1=The <code>params</code> object MUST be valid JSON. Use colons (<code>:</code>) for key-value pairs, NOT PHP array syntax (<code>=></code>). Incorrect format like <code>params={"cdrId"=>191}</code> will cause errors. Always ensure JSON uses proper syntax: <code>{"cdrId":191,"type":"S","generating":"1"}</code>}}
| |
| | |
| == Direct Links ==
| |
| | |
| Direct URL access to GUI pages:
| |
| | |
| {| class="wikitable"
| |
| |-
| |
| ! Link !! Description
| |
| |-
| |
| | <code>index.php?activecalls=1&hidegrid=1&hidemenu=1</code> || Active calls view (embedded mode)
| |
| |}
| |
| | |
| == 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:
| |
| | |
| <syntaxhighlight lang="bash">
| |
| curl -X POST '192.168.76.201/php/model/sql.php?module=bypass_login&user=voipmonitor&pass=voipmonitor'
| |
| </syntaxhighlight>
| |
| | |
| Response:
| |
| | |
| <syntaxhighlight lang="json">
| |
| {"SID":"ahs2ubdhc0ukb262be60v900ko","cookie_name":"PHPSESSID","success":true,"_vm_version":240034,"_debug":false}
| |
| </syntaxhighlight>
| |
| | |
| '''brief_data''' action get SIP history data in JSON format:
| |
| | |
| <syntaxhighlight lang="bash">
| |
| 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"
| |
| </syntaxhighlight>
| |
| | |
| '''brief''' action get SIP history in simple HTML format (as table tag):
| |
| | |
| <syntaxhighlight lang="bash">
| |
| 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"
| |
| </syntaxhighlight>
| |
| | |
| '''genMSC''' action get SIP history as diagram in HTML format:
| |
| | |
| <syntaxhighlight lang="bash">
| |
| 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"
| |
| </syntaxhighlight>
| |
| | |
| == Check License ==
| |
| | |
| Basic test for license (covers ionCube issues):
| |
| | |
| <syntaxhighlight lang="bash">
| |
| curl 'http://localhost:88/php/apilicensecheck.php?task=licenseCheck'
| |
| </syntaxhighlight>
| |
| | |
| Example responses:
| |
| | |
| <syntaxhighlight lang="json">
| |
| {"status":1,"message":"license file key.php expired. Current date: 2021-02-23 Expiration date: 2021-02-16"}
| |
| {"status":0,"message":"License OK."}
| |
| </syntaxhighlight>
| |
| | |
| Test concurrent calls limit (requires functional ionCube):
| |
| | |
| <syntaxhighlight lang="bash">
| |
| curl 'http://localhost:88/php/apilicensecheck.php?task=licenseCallsLimitCheck'
| |
| </syntaxhighlight>
| |
| | |
| Example responses:
| |
| | |
| <syntaxhighlight lang="json">
| |
| {"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."}
| |
| </syntaxhighlight>
| |
| | |
| === 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>
| |
| | |
| After deleting CDRs, the system may need time to recalculate the concurrent call count. Monitor the license status using the API endpoint above.
| |
| | |
| '''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:
| |
| | |
| * 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:''' Complete VoIPmonitor Web API reference. Two main API types: (1) HTTP API 2 at <code>/php/api.php</code> - stateless requests with user/password parameters for tasks like getVoipCalls, getVoiceRecording, getPCAP, listActiveCalls, getShareURL, reportSummary; (2) CDR HTTP API at <code>/php/model/sql.php</code> - session-based with full filter support. '''Critical:''' The <code>reportSummary</code> task is the ONLY API task available for generating reports - reports must be pre-configured in the GUI before API use. Custom login via <code>scripts/custom_login.php</code> enables LDAP integration (requires unique numeric ID per user, php-ldap extension). Antivirus may delete custom scripts containing shell_exec - disable with <code>DISABLE_ANTIVIRUS</code> in system_configuration.php or move shell commands to external file outside web root. URL encoding required for special characters (use curl --data-urlencode). '''Branding:''' Customize product name with BRAND_NAME; customize share service domain with BRAND_SHARESITE and BRAND_DOMAIN in brand.php - replaces share.voipmonitor.org with branded domain. | | '''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:''' web api, http api, api.php, sql.php, custom login, LDAP, getVoipCalls, getVoiceRecording, getPCAP, getShareURL, listActiveCalls, reportSummary, handleActiveCall, listCdrIds, getAudioGraph, CDR filter, license check, antivirus, DISABLE_ANTIVIRUS, branding, BRAND_NAME, BRAND_SHARESITE, BRAND_DOMAIN, share.voipmonitor.org, branded domain, custom domain, brand.php, wildcard, URL encoding, curl, data-urlencode, session, authentication | | '''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:''' |
| * What is the correct VoIPmonitor API endpoint path? | | * What is the correct VoIPmonitor API endpoint path? |
| * How do I retrieve CDRs via the VoIPmonitor API? | | * How do I retrieve CDRs via the VoIPmonitor API? |
| * How to generate reports from the Report Generator via API?
| | * How to download PCAP or voice recordings via API? |
| * How to download PCAP files programmatically via API? | |
| * How to download voice recordings via API?
| |
| * How to list active calls via API? | | * How to list active calls via API? |
| | * How to generate reports via API? |
| * How to configure LDAP authentication for VoIPmonitor? | | * How to configure LDAP authentication for VoIPmonitor? |
| * Why is my custom_login.php being deleted by antivirus? | | * Why do LDAP users share settings? (need unique ID) |
| * How to disable VoIPmonitor GUI antivirus? | | * Why is custom_login.php being deleted? (antivirus) |
| | * How to customize VoIPmonitor branding? |
| | * What's the difference between api.php and sql.php? |
| * How to use wildcards in API filter parameters? | | * How to use wildcards in API filter parameters? |
| * How to URL-encode special characters in API requests?
| |
| * How to resolve VoIPmonitor license lockout via API?
| |
| * How to customize VoIPmonitor branding?
| |
| * How to customize share.voipmonitor.org to my own branded domain?
| |
| * How to configure BRAND_SHARESITE and BRAND_DOMAIN?
| |
| * What is the difference between api.php and sql.php endpoints?
| |
| * How to get share URL for CDR via API?
| |
| * How to pause/unpause active call recording via API?
| |