• Eigenständig gehostete oder lokal installierte Instanzen sind komplexer in der Einrichtung und Fehlerbehebung und erfordern daher kostenpflichtigen technischen Support. Kostenlosen Support erhalten Sie mit 3CX StartUP oder einer gehosteten 3CX-Installation mit einen unterstützten SIP-Trunk-Anbieter.

Suche nach der API-Dokumentation

Isen Tiefbau

Premier Customer
Mitglied seit
20. April 2020
Beiträge
180
Hallo ich habe ein paar Hinweise im englischen Forum gefunden, die mir inzwischen gestatten, die Anlage mit einem akzeptablen Monitoring auszustatten.
Ich hätte gern mehr gemacht. Nur fehlen mir dazu ein paar Infos, die sicher in einer API-Doku stehen.
Leider ist es so, dass alle Links, die in diesen Beiträgen in Richtung 3CX verweisen auf "Page not found" enden.
Anscheinend ist die Doku umgezogen. Weiss jemand wohin?

Danke und Gruss
 
Informationen zum Monitoring der Anlage, um Informationen z.B. über Icinga abzufragen und auszuwerten, fände ich auch sehr hilfreich.
  • Läuft Dienst 3CX-XYZ...?
  • Sind die SIP-Trunks registriert?
  • Wie lange läuft noch die Lizenz/Wartung?
  • Anzahl aktiver Gespräche
  • Auslastung des Trunks
Solche Sachen und andere hätte ich auch gerne über eine API oder alternativ auch gerne über Kommandozeilenbefehle.

Gibt es da schon was oder ist sowas für zukünftige Versionen in Planung?
 
Offiziell steht die Dokumentation nicht (mehr) zur Verfügung. V18 soll da wieder was ändern. Dienst-Status gibts über /api/ServiceList :p
 
So kommt doch mit kleinen Schritten wenigstens etwas vorwärts.

Danke Dir
 
Ja, so weit, so gut. Mit den JSON-Infos lässt sich schon einiges anfangen. Wie authentifiziert ihr euch aber im Vorfeld?
 
Guten Morgen mn,

über /api/login kannst Du Dich anmelden und mit /api/logout wieder abmelden.
Beim Login einfach Username und Password als Request-Parameter mitgeben.

Viel Vergnügen
 
Hallo Zusammen,

ich hab mal ein Beispiel als perl-Script, das einen Output für einen Custom-Sensor im PRTG liefert.

#############################################################################
#!/usr/bin/perl
use strict;
use warnings;
use REST::Client;
use JSON;

my $client = REST::Client->new();
my $result = "";
$client->setHost('https://yourpbx_fqdn');
$client->addHeader('Accept', 'application/json');
$client->addHeader('Content-Type', 'application/json');
$client->addHeader('charset', 'UTF-8');
$client->getUseragent()->cookie_jar({});

my $req = '{"username":"your_pbx_admin", "password":"your_admin_password"}';
$client->POST('/api/login', $req);

if ($client->responseContent() eq 'AuthSuccess') {
$client->GET('/api/SystemStatus');
my $pbxdata = from_json($client->responseContent());

$req = '{}';
$client->POST('/api/logout', $req);

$result = '{ "prtg": { "result": [ { "channel": "CPU Usage", "value": "'.$pbxdata->{'CpuUsage'}.
'" }, { "channel": "Memory Usage", "value": "'.$pbxdata->{'MemoryUsage'}.
'" }, { "channel": "physical Memory Usage", "value": "'.$pbxdata->{'PhysicalMemoryUsage'}.
'" }, { "channel": "Disk Usage", "value": "'.$pbxdata->{'DiskUsage'}.
'" }, { "channel": "Gesamt Nebenstellen", "value": "'.$pbxdata->{'ExtensionsTotal'}.
'" }, { "channel": "Nebenstellen aktiv", "value": "'.$pbxdata->{'ExtensionsRegistered'}.
'" }, { "channel": "Gesamt Trunks", "value": "'.$pbxdata->{'TrunksTotal'}.
'" }, { "channel": "Trunks aktiv", "value": "'.$pbxdata->{'TrunksRegistered'}.
'" }, { "channel": "Anrufe frei", "value": "'.($pbxdata->{'MaxSimCalls'} - $pbxdata->{'CallsActive'}).
'" }, { "channel": "Anrufe aktiv", "value": "'.$pbxdata->{'CallsActive'}.
'" }, { "channel": "Blockierte IP", "value": "'.$pbxdata->{'BlacklistedIpCount'}.
'" }, { "channel": "Chat Nachrichten", "value": "'.$pbxdata->{'ChatMessagesCount'}.
'" }, { "channel": "Anruf Historie Count", "value": "'.$pbxdata->{'CallHistoryCount'}.
'" } ] } }';

print $result . "\n";
}
else {
exit 1;
}

exit 0;
######################################################################
 
  • Like
Reaktionen: mn26826
OK. Danke für den Code.
Ich hatte gestern auch erste Versuche mit wget unternommen, bekam aber immer "400 Bad Request" als Antwort. Das gleiche mit cURL hatte dann aber funktioniert:

Bash:
curl 'https://myhost.my3cx.de:5001/api/login' \
  -H 'authority: myhost.my3cx.de:5001' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63' \
  -H 'content-type: application/json;charset=UTF-8' \
  -H 'origin: https://myhost.my3cx.de:5001' \
  -H 'sec-fetch-site: same-origin' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://myhost.my3cx.de:5001/' \
  -H 'accept-language: de' \
  -b /tmp/curl-cookies.txt \
  -c /tmp/curl-cookies.txt \
  --data-raw '{"Username":"admin","Password":"xxx"}' \
  --compressed

curl 'https://myhost.my3cx.de:5001/api/SystemStatus' \
  -H 'authority: myhost.my3cx.de:5001' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63' \
  -H 'content-type: application/json;charset=UTF-8' \
  -H 'origin: https://myhost.my3cx.de:5001' \
  -H 'sec-fetch-site: same-origin' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://myhost.my3cx.de:5001/' \
  -H 'accept-language: de' \
  -b /tmp/curl-cookies.txt \
  -c /tmp/curl-cookies.txt \
  --compressed
 
  • Like
Reaktionen: Isen Tiefbau
Hallo,
hat sich hier etwas neues ergeben? Ist die Dokumentation wieder zu finden?

LG Felix
 
  • Like
Reaktionen: mr412
Wie würde denn so ein fertiger http-Request für die Anmeldung aussehen?

Ich bekomme es nicht hin. Bin aber auch kein Experte auf dem Gebiet. Mache erst Gehversuche. Bin für jede Unterstützung dankbar :)
 
Wie würde denn so ein fertiger http-Request für die Anmeldung aussehen?
Das steht doch in den beiden Posts darüber, einmal per Perl und einmal per cUrl. Das funktioniert auch.

Welche Programmier- bzw. Skriptsprache beherrschst du denn hinreichend gut bzw. kommt für dich dafür in Frage?
 
Ich programmiere Microcontroller in C. Aber darin wollte ich es nicht machen.

Das Ziel ist es in ioBroker der 3cx Daten zu entlocken. Da es aber noch keinen 3cx-Adapter in ioBroker gibt, müsste ich mir was "basteln".

Per Blockly-Script (JavaScript) könnte das gehen. Habe schon von einer Website, die JSON zurück gibt per http-request Daten ausgelesen und weiter verarbeitet. Da gab es aber keine Authentifizierung. Daran scheitert es. Die 3cx-Daten auslesen würde auch so klappen. Aber wie schalte ich die Authentifizierung davor? Ich hatte gehofft, dass wenn ich zum Testen im Browser eine bestimmte URL eingeben, die Anmeldung da ist. Im Anschluss danach würde ich dann auch im Browser z.B. die aktiven Calls abfragen.

Wenn ich die Anmeldung im Webinterface durchführe und anschließend die API frage, kommt auch schön JSON zurück.

Die Frage ist halt, ob eine Authentifizierung über eine bestimmte URL in der ich Name und Passwort mitgebe ausreicht das Ziel zu erreichen?!?!? Aus den obigen Beispielen dann ich das so nicht ablesen. Da fehlt mir leider das Wissen.
 
Ich programmiere Microcontroller in C. Aber darin wollte ich es nicht machen.
Was in etwa? Ich nach den Mikroprozessoren der 80er und tlw. 90er div. PIC, AVM und seitdem STM32, Espressif und andere kleinere und größere Arm und MIPS in Assembler, C, C++ direkt und unter div. RTOS und *nixen auch. Aber den kleinen fehlt sicher die Power zur Datenauswertung.

Die o.g. Beispiele erzeugen je einen ersten Post Request, speichern ein Auth Cookie und danach kommt das plain GET mit der Datenabfrage. Ich könnte das (wegen des cUrl) in einer beliebigen Shell, in Powershell und sicher auch in Java nachbauen (wo soll das laufen dass das funktioniert?).

Die Frage ist halt, ob eine Authentifizierung über eine bestimmte URL in der ich Name und Passwort mitgebe ausreicht das Ziel zu erreichen?!?!?
nein
 
  • Like
Reaktionen: MarcosV_3CX
Ich programmiere (Ablauf-)Steuerungen für Industriegeräte z.B. Renesas M16C. Also nix mit GUI und Web. Reiner C-Code. Außerdem programmiere ich Fehler in einer etwas älteren Software heraus in C++, die ich nicht selber geschrieben habe. Aber das kann ich nicht wirklich gut, da ich es nur sehr selten einsetze.

Danke für Deine Erklärung. Ich hatte gehofft, dass es irgendwie einfacher geht. Aber ich sehe schon, dass ich mich da tiefer einarbeiten müsste. Vielleicht muss ja auch mal ein Buch her :)
 
Habe mich jetzt ein wenig weitergebildet und die Anmeldung verstanden (hoffe ich *fg*) und umgesetzt. Ebenso kann ich Daten über die API abrufen. Was ich noch nicht verstanden habe: Wie geht das mit der Abmeldung geht. Ein

Code:
curl 'https://myhost.my3cx.de:5001/api/logout'

alleine hat m.E. keine Auswirkung. Wenn ich das cookie lösche schon.

Wie mache ich also das Logout sauber? Wie lautet der richtige curl-Befehl? Und muss man dann noch das Cookie händisch löschen oder macht das das Logout selber?
 
alleine hat m.E. keine Auswirkung. Wenn ich das cookie lösche schon.
Der Debugger sagt, es ist ein POST request an /api/logout, es kommt ein 204 No Content zurück. Die wenigen unserer Skripte, welche sich so authentifizieren, loggen sich nicht aus. Ich würde nur das Cookie löschen, falls es denn in einer Datei zwischengespeichert wird, so wie bei cURL.
 
Zuletzt bearbeitet:
  • Like
Reaktionen: Josch
Ich hatte Probleme mit PHP die API anzusprechen.
Hier ist jetzt mein funktionierendes Script:

<pre><?php

ini_set('display_errors', 1);

$cookie = __DIR__ . DIRECTORY_SEPARATOR . "cookie.txt";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://info.3cx.de:5001/api/login");
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 2);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('Username' => 'admin', 'Password' => '********')));
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIELIST, "RELOAD");

$clist = curl_getinfo($ch, CURLINFO_COOKIELIST);

$serverLoginOutput = curl_exec($ch);

curl_close($ch);

if ($serverLoginOutput == "AuthSuccess") {

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://info.3cx.de:5001/api/ServiceList");
//curl_setopt($ch, CURLOPT_URL, "https://info.3cx.de:5001/api/SystemStatus");
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 2);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);

$serverSystemOutput = curl_exec($ch);

curl_close($ch);

$systemData = json_decode($serverSystemOutput);

var_dump($systemData);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://info.3cx.de:5001/api/logout");
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 2);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);

$serverSystemOutput = curl_exec($ch);

curl_close($ch);

$systemData = json_decode($serverSystemOutput);

}
?>
</pre>
 
  • Like
Reaktionen: fxbastler
Schön, wieder ein Beispiel mehr.
Ich würde nur zusehen, dass das Cookie anschließend und kurzfristig aus Sicherheitsgründen gelöscht wird.
 
Vielen Dank für die zahlreichen Anregungen.

Ein Beispiel in Python ohne Fehlerbehandlungen:

Python:
import requests
import urllib3

urllib3.disable_warnings()

url = 'https://pbx:5001'

credentials = {
    "username" : "USERNAME",
    "password" : "PASSWORD"
}

s = requests.Session()

login_url = '{}/api/login'.format(url)
r = s.post(login_url, json=credentials, verify=False)

status_url  = '{}/api/SystemStatus'.format(url)
r = s.get(status_url, verify=False)

system_status = r.json()
s.cookies.clear()


trunks_registered = system_status['TrunksRegistered']
...

@joshi In C sollte es analog zu den PHP-Beispielen mit libcurl (https://curl.se/libcurl) funktionieren. Weitere Beispiele unter https://curl.se/libcurl/c/example.html.

Falls cCurl für Deine Zwecke zu "mächtig" ist, könnte Dich tiny-curl (https://curl.se/tiny) interessieren.
 
  • Like
Reaktionen: fxbastler und joschi
Holen Sie sich 3CX - völlig kostenlos!

Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX register cta
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.