Ok, damit hast Du ja einen LDAP-Server. Dann musste du den ggfs. um ein Schema erweitern, um die Adressen/Telefonnummern speichern zu können (kann sein, das der schon ein solches Schema hat). Ein solches Schema habe ich Dir angehängt.
Das Füllen vom LDAP mit Daten, dafür gibt es ja diese LDAP-Programm resp. auch ldap-php-Erweiterungen.
Bleibt das Problem, an die Kontakte zu kommen, da - wie gesagt - habe ich nichts anderes gefunden als die regelmäßig von Hand komplett zu exportieren und abzugleichen. Parsen des Formates eben mit vcfconvert
Ok, also
-
auf der 3CX unter Einstellung KDS den Export aktivieren
alle Felder zum Export aktivieren oder Script #1 anpassen
-
Server-Socket aktivieren
-
eine RegisterVaiaible anlegen
-
Dazu 2 Variablen und 2 Scripte
Variable „Record“: Typ String, protokolliert
Variable „Telefonliste“: HTML-Box
Script 1 „CDR auswerten“
<?
$scriptName = IPS_GetName($_IPS['SELF']) . '(' . $_IPS['SELF'] . ')';
$cols = [
'historyid',
'callid',
'duration',
'time-start',
'time-answered',
'time-end',
'reason-terminated',
'from-no',
'to-no',
'from-dn',
'to-dn',
'dial-no',
'reason-changed',
'final-number',
'final-dn',
'bill-code',
'bill-rate',
'bill-cost',
'bill-name',
'chain',
'from-type',
'to-type',
'final-type',
'from-dispname',
'to-dispname',
'final-dispname',
];
if ($_IPS['SENDER'] == "RegisterVariable") {
$data = $_IPS['VALUE'];
if ($data != '') {
$data = preg_replace('%(
)%', '', $data);
$flds = explode(',', $data);
$cdr = [];
for ($idx = 0; $idx < sizeof($flds); $idx++) {
if (isset($cols[$idx])) {
$col = $cols[$idx];
$val = $flds[$idx];
$cdr[$col] = $val;
}
}
IPS_LogMessage($scriptName, 'cdr=' . print_r($cdr, true));
$msg = 'call ' . $cdr['callid'] . ': from=' . $cdr['from-dispname'] . ', to=' . $cdr['to-dispname'] . ' => ' . $cdr['reason-terminated'];
IPS_LogMessage($scriptName, $msg);
SetValueString(47610 /*[3CX - Call-Data-Records\Record]*/, json_encode($cdr));
}
}
Script 2: „Telefonliste erstellen (HTML-Box)“
<?
function telno2name($telno)
{
if (!preg_match('/^0/', $telno, $regs)) {
$telno = '02327' . $telno;
}
$names = [ 'FirstName', 'LastName', 'Company', 'Mobile', 'Mobile2', 'Home', 'Home2', 'Business', 'Business2', 'Email', 'Other', 'BusinessFax', 'HomeFax', 'Pager' ];
$tn_names = [ 'Mobile', 'Mobile2', 'Home', 'Home2', 'Business', 'Business2', 'BusinessFax', 'HomeFax', 'Pager' ];
$data = IPS_GetMediaContent(13550 /*[Telefon: Kontakte]*/);
$data = base64_decode($data);
$rows = explode("
", $data);
$n_row = 0;
$nm = '';
foreach ($rows as $row) {
if (!$n_row++) {
continue;
}
$fields = str_getcsv($row, ',');
$line = [];
for ($i = 0; $i < sizeof($names); $i++) {
$line[$names[$i]] = isset($fields[$i]) ? $fields[$i] : '';
}
foreach ($tn_names as $tn_name) {
$tn = $line[$tn_name];
if ($tn == '')
continue;
if (!strcmp($tn, $telno)) {
$nm = $line['LastName'];
if ($line['FirstName'] != '') {
$nm = $line['FirstName'] . ($nm != '' ? ' ' : '' ). $nm;
}
if ($nm == '') {
$nm = $line['Company'];
}
break;
}
}
if ($nm != '')
break;
}
return $nm;
}
function reserve_search($telno)
{
$displayname = '';
// nationale Nummern ohne +49
$telno = preg_replace('/^\+49/', '0', $telno);
// internationale Nummern ohne +
$telno = preg_replace('/^\+/', '00', $telno);
// ggfs Ortsvorwahl dazu
if (!preg_match('/^0/', $telno, $regs)) {
$telno = '02327' . $telno;
}
// Das Örtliche
$url = 'https://www.dasoertliche.de/Controller?form_name=search_inv&la=de&ph=' . $telno;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$cdata = curl_exec($ch);
curl_close($ch);
if ($cdata) {
if (preg_match('/var handlerData = [\[][\[]([^;]*)[\]][\]];/', $cdata, $regs)) {
$fields = str_getcsv($regs[1], ',', '\'');
if (isset($fields[14])) {
$displayname = utf8_decode($fields[14]);
}
}
}
if (strlen($displayname)) {
return $displayname;
}
// Das Telefonbuch
$url = 'https://www.dastelefonbuch.de/' . rawurlencode('Rückwärts-Suche') . '/' . $telno;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$cdata = curl_exec($ch);
curl_close($ch);
if ($cdata) {
if (preg_match('/data-entry-data="([^"]*)"/', $cdata, $regs)) {
// echo 'regs=' . print_r($regs, true) . PHP_EOL;
$rr = explode('&', $regs[1]);
foreach ($rr as $r) {
$p = explode('=', $r);
if ($p[0] == 'na') {
$displayname = utf8_decode(urldecode($p[1]));
break;
}
}
}
}
if (strlen($displayname)) {
return $displayname;
}
return false;
}
function build_name($dispname, $telno, $type)
{
$name = $dispname;
if ($name == $telno) {
$s = telno2name($telno);
if ($s == '') {
$s = reserve_search($telno);
}
if ($s != '') {
$name = $s;
}
}
if ($type != 'Extension' && $telno != '' && $name != $telno) {
$name .= ' (' . $telno . ')';
}
return $name;
}
function complete_record($cdr)
{
$time_start = $cdr['time-start'];
$tm = date_create_from_format('Y.m.d H:i:s e', $time_start . ' UTC');
$cdr['timestamp'] = $tm ? $tm->format('U') : 0;
$from_type = $cdr['from-type'];
$from_no = $cdr['from-no'];
$from_dispname = $cdr['from-dispname'];
$to_type = $cdr['to-type'];
$to_no = $cdr['to-no'];
$to_dispname = $cdr['to-dispname'];
$dir = $from_type == 'Line' ? 'in' : 'out';
$cdr['direction'] = $dir;
$duration = $cdr['duration'];
$reason_terminated = $cdr['reason-terminated'];
switch ($reason_terminated) {
case 'TerminatedByDst':
case 'TerminatedBySrc':
$img = $dir == 'in' ? 'tel_call-in.gif' : 'tel_call-out.gif';
$txt = 'Gespräch normal beendet';
break;
case 'Failed':
case 'Failed_Cancelled':
case 'TerminatedByRule':
$img = $dir == 'in' ? 'tel_call-in_failed.gif' : 'tel_call-out_failed.gif';
$txt = $duration == '' ? 'Gespräch nicht zustande gekommen' : 'Gespräch abgebrochen';
break;
case 'TargetBusy':
$img = $dir == 'in' ? 'tel_call-in_failed.gif' : 'tel_call-out_failed.gif';
$txt = 'Gesprächspartner besetzt';
break;
case 'TargetNotFound':
$img = $dir == 'in' ? 'tel_call-in_failed.gif' : 'tel_call-out_failed.gif';
$txt = 'Telefonnummer nicht erreichbar';
break;
default:
$img = 'tel_error.png';
$txt = 'Unbekannter Status (' . $reason_terminated . ')';
break;
}
$cdr['status_img'] = 'user/media' . DIRECTORY_SEPARATOR . $img;
$cdr['status_txt'] = $txt;
$cdr['source'] = build_name($from_dispname, $from_no, $from_type);
$cdr['target'] = build_name($to_dispname, $to_no, $to_type);
return $cdr;
}
$from = time() - (7 * 24 * 60 * 60);;
$values = AC_GetLoggedValues(17849 /*[Archive]*/, 47610 /*[3CX - Call-Data-Records\Record]*/, $from, 0, 0);
$cdrs = [];
foreach ($values as $value) {
$cdr = json_decode($value['Value'], true);
$cdrs[] = complete_record($cdr);
}
$html = '';
$html .= '<style>' . PHP_EOL;
$html .= 'body { margin: 1; padding: 0; font-family: "Open Sans", sans-serif; font-size: 20px; }' . PHP_EOL;
$html .= 'table { border-collapse: collapse; border: 0px solid; margin: 0.5em;}' . PHP_EOL;
$html .= 'th, td { padding: 1; }' . PHP_EOL;
$html .= 'thead, tdata { text-align: left; }' . PHP_EOL;
$html .= '#spalte_icon { width: 25px; }' . PHP_EOL;
$html .= '#spalte_zeitpunkt { width: 125px; }' . PHP_EOL;
$html .= '#spalte_quelle { width: 400px; }' . PHP_EOL;
$html .= '#spalte_ziel { width: 400px; }' . PHP_EOL;
$html .= '#spalte_dauer { width: 20px; }' . PHP_EOL;
$html .= '</style>' . PHP_EOL;
$cdr_n = sizeof($cdrs);
$b = false;
if ($cdr_n) {
foreach ($cdrs as $cdr) {
$timestamp = $cdr['timestamp'];
$duration = $cdr['duration'];
$img = $cdr['status_img'];
$txt = $cdr['status_txt'];
$source = $cdr['source'];
$target = $cdr['target'];
if ($duration == '') {
$duration = '-';
}
$dt = date('d.m. H:i', $timestamp);
if (!$b) {
$html .= '<table>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_icon"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_zeitpunkt"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_quelle"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_ziel"></colgroup>' . PHP_EOL;
$html .= '<colgroup><col id="spalte_dauer"></colgroup>' . PHP_EOL;
$html .= '<colgroup></colgroup>' . PHP_EOL;
$html .= '<thead>' . PHP_EOL;
$html .= '<tr>' . PHP_EOL;
$html .= '<th> </th>' . PHP_EOL;
$html .= '<th>Zeitpunkt</th>' . PHP_EOL;
$html .= '<th>Anrufer</th>' . PHP_EOL;
$html .= '<th>Ziel</th>' . PHP_EOL;
$html .= '<th>Dauer</th>' . PHP_EOL;
$html .= '<th> </th>' . PHP_EOL;
$html .= '</tr>' . PHP_EOL;
$html .= '</thead>' . PHP_EOL;
$html .= '<tdata>' . PHP_EOL;
$b = true;
}
$html .= '<tr>' . PHP_EOL;
$html .= '<td><img src=' . $img . ' width="18" height="18" title="' . $txt . '"</td>' . PHP_EOL;
$html .= '<td>' . $dt . '</td>' . PHP_EOL;
$html .= '<td>' . $source . '</td>' . PHP_EOL;
$html .= '<td>' . $target . '</td>' . PHP_EOL;
$html .= '<td>' . $duration . '</td>' . PHP_EOL;
$html .= '</tr>' . PHP_EOL;
}
if ($b) {
$html .= '</tdata>' . PHP_EOL;
$html .= '</table>' . PHP_EOL;
} else {
$html .= '<center>keine Anrufe</center><br>' . PHP_EOL;
}
$html .= '</body>' . PHP_EOL;
$html .= '</html>' . PHP_EOL;
}
SetValueString(43833 /*[3CX - Call-Data-Records\Telefonliste]*/, $html);
- ein Media-Objekt „Telefon: Kontakte“.
Dazu habe ich einfach alle Kontakte, die ich in der 3CX habe, als CSV exportiert und diese cdv-Datein in IPS geladen.
Weil meine Daten ja ziemlich statisch sind und das mit LDAP ja eben irgendwann nicht mehr funktionierte habe ich meine Telefonnummern in 3CX gepflegt.
Wen das nicht benötigt wird, ist das Media-Objekt und die Auswertung in telefon2name in script #2 überflüssig.
Ich hoffe, es ist nicht zu verwirrend
demel
mozillaAbPersonAlpha.txt (5.14 KB)