Tarifabfrage mittels PHP?

draellme

Neuer User
Mitglied seit
19 Nov 2005
Beiträge
96
Punkte für Reaktionen
0
Punkte
6
Hallo

Hat jemand ein PHP-Skript, dem ich einen Betamax-Provider sowie eine Telefonnummer geben kann und das Skript checkt, wieviel ein Anruf pro Minute auf diese Nummer beim angegebenen Betamaxler kostet?


Danke
Draellme
 
Das eigentliche Problem ist hier nicht der Preisabruf, vielmehr hast Du ein Problem mit dem Mapping Rufnummer -> Zone (z.B.: germany (landline)) von Betamax. Hinzu kommt, dass die verschiedenen Betamaxe die Zonen einmal groß und einmal klein schreiben.
Da ich aber was ähnliches schon in perl hatte, hier mal ein Ansatz in php mit mysql-Datenunterstützumng für das Mapping:

PHP:
#!/usr/bin/php -q
<?php
include('HTTP/Request.php');    // requires php5-pear-http_request
include('tableExtractor.class.php');

// (c) 2008 Olaf Winkler ([email protected])
// Preisabfrage zu Rufnummer bei übergebenem BM-Provider
// Ergebnis: Preis unter Berücksichtigung von Freedays und wahlfähige Rufnummer

//Variablendeklarationen

// argv[1] zu tarifierende Rufnummer
// argv[2] mit Freedays (1=ja, 0=nein)
// argv[3] Domäne des BM-Clones
// Beispiel: bmpreis.php 001540123456 1 voipcheap.com -> Ergebnis 0|001540123456

$myiac='00';            // eigener Code für internationale Anrufe
$mynac='0';             // eigener Code für nationale Ferngespräche
$mycc=49;               // eigener Ländercode
$myndc=30;              // eigene Vorwahl ohne 0

$dbhost="localhost";    // MYSQL-Host
$dbuser="asterisk";     // MYSQL-User
$dbpass="asterisk";     // MYSQL Passwort
$dbschema="asterisk";   // MYSQL DB

// Ende der Variablendeklaration
// Beginn Code

function usage($prob) {
        echo "bmpreis.php 2008 by Olaf Winkler <[email protected])\n\n";
        switch ($prob) {
                case 0: echo "Fehlerhafte Anzahl Parameter\n";
                        break;
                case 1: echo "Fehlerhafte Rufnummer, nur Ziffern und + erlaubt\n";
                        break;
                case 2: echo "Fehlerhafter Freedays-Parameter, nur 0 (ohne Freedays) oder 1 (mit Freedays) erlaubt\n";
                        break;
                case 3: echo "Fehlerhafte betamax-Domäne. Angabe immer in Form der Domäne, also z.B.: voipcheap.com oder nonoh.net\n";
                        break;
                }
        echo "Aufruf: bmpreis.php <Rufnummer> <Freedays> <domain>\n";
        echo "Beispiel: bmpreis.php 001540123456 1 voipcheap.com\n";
        exit(0);
}
function error($line,$file,$str,$mysql_err="") {
        $str = "Fehler in Zeile ".$line." in ".$file.": ".$str;
        if($mysql_err) $str .= " - MySQL meldet: ".$mysql_err;
        print $str."\n";
        connmysql(1);
        exit;
}


function connmysql($mode,$host="",$user="",$pass="",$schema="") {

        global $db, $dbhost, $dbuser, $dbpass, $dbschema;

        if ($mode == 0 ) {
                // connect to mysql
                $db = @mysql_pconnect($host,$user,$pass) or error(__LINE__,__FILE__,"Verbindung zur Datenbank fehlgeschlagen: ".$user."@".$host);
                mysql_query('SET CHARACTER SET utf8;');
                mysql_select_db($schema,$db) or error(__LINE__,__FILE__,"Konnte Datenbank nicht auswählen: ".$schema);
        } else {
                mysql_close($db);
                unset($db);unset($dbhost);unset($dbuser);unset($dbpass);unset($dbschema);
        }
}
function betamax_number($anum) {

        global $myiac,$mynac,$mycc,$myndc;

        $result='';

        if ( preg_match('/^\+/',"$anum") ) {
                # International +-Format
                $result=preg_replace('/^\+/','00',$anum);
        } elseif ( preg_match('/^'.$myiac.'/',$anum) ) {
                # international IAC-Format
                $result=preg_replace('/^'.$myiac.'/','00',$anum);
        } elseif ( preg_match('/^'.$mynac.'/',$anum) ) {
                # national calls long diatance
                $result=preg_replace('/^'.$mynac.'/','00'.$mycc,$anum);
        } else {
                # local call
                $result =       '00'.$mycc.$myndc.$anum;
        }
        return $result;
}


function check_params($argv,$argc) {
        if ($argc != 4) {
                usage(0);
        }
        if (preg_replace('/[0-9+]/','',$argv[1]) != '') {
                usage(1);
        } else {
                $number=betamax_number($argv[1]);
        }
        if (( $argv[2] != 0 ) && ( $argv[2] != 1 )) {
                usage(2);
        }
        if (! (preg_match('/^[0-9a-zA-Z]*\.[a-zA-Z]{3}$/',$argv[3]))) {
                usage(3);
        } else {
                $url='http://www.'.$argv[3].'/en/calling-rates.html';
        }
        return array($number,$argv[2],$url);
}

function get_zones($number) {

        global $db;

        $found=false;
        for ($j=10;$j>=4;$j--) {
                $check=substr($number,0,$j);
                $result = mysql_query("select zone,alt_zone from bm_zones where exten='".$check."'") or error(__LINE__,__FILE__,"Konnte nicht nach Rufnummer suchen",mysql_error());
                if(mysql_num_rows($result) != 0) {
                        $z1     =       mysql_result($result,0,0);
                        $z2     =       mysql_result($result,0,1);
                        $found=true;
                        break;
                }
        }
        if ($found) {
                if ($z1 == "not reachable") {
                        return array('','');
                } else {
                        return array($z1,$z2);
                }
        } else {
                return array('','');
        }
}

function get_rate($number,$mode,$url,$zone,$zonec,$anchor="id=\"ratestableL\"",$site=0){

        global $foundrate;

        if ($site == 0) {
                $body = &new HTTP_Request($url);
                $body->sendRequest();
                $site=$body->getResponseBody();
        }
        $tx = new tableExtractor;
        $tx->source=$site;
        $tx->anchor=$anchor;
        $tx->anchorWithin=true;
        $tx->headerRow=false;
        $tx->stripTags=true;
        $ta=$tx->extractTable();
        $foundrate=false;
        foreach ($ta as $dest) {
                if ( preg_match('/[\(\[]/',$dest[1])) {
                        $rate=0;
                        $zon=strtolower(preg_replace('/\ \ /',' ',preg_replace('/\ SuperDeal.*/i','',preg_replace('/\&amp\;/','&',preg_replace('/\(/',' (',$dest[1])))));
                        if ( ($zon == $zone) || ($zon == $zonec) ) {
                                $rate=$dest[2];
                                if (preg_match('/FREE.*/i',$rate)) {
                                        $rate=0;
                                        if ($mode == '0' ) {
                                                // check rate without freedays
                                                $rate=get_rate($number,2,str_replace('calling-rates.html','freetrial.html',$url),$zone,$zonec);
                                                if ($rate == "0" ) { $rate=get_rate($number,2,str_replace('calling-rates.html','freetrial.html',$url),$zone,$zonec,"id=\"ratestableR\"",$site);}
                                        }
                                }
                                $foundrate=true;
                                break;
                        }
                }
        }
        if ($mode != 2) {$rate=$rate*100;}
        return $rate;
}

#Check params
list($number,$mode,$url)=check_params($argv,$argc);

#Connectierung
connmysql(0,$dbhost,$dbuser,$dbpass,$dbschema);

#Programlogik
$foundrate=false;
list($zone,$zonec)=get_zones($number);
if ( $zone != '' ) {
        $rate=get_rate($number,$mode,$url,$zone,$zonec);
        if ($foundrate) {
                print $number." -> ".$zone." Kosten: ".$rate." EURC/min\n";
        } else {
                print $number." -> ist über diesen Anbieter nicht erreichbar\n";
        }
} else {
        print $number." -> ist über diesen Anbieter nicht erreichbar\n";
}

#Disconnects
connmysql(1);

#End
exit(0);
?>

Das Skript ist bezüglich der Benutzung selbsterklärend (Siehe function usage).
Damit es funktioniert muß die PEAR-Klasse HTTP_Request installiert sein (siehe entsprechendes include).
Desweiteren wird tableExtractor.class.php benötigt, diese liegt im Archiv bei, ebenso die notwendigen mysql-Daten als Dump.

Innerhalb des Skriptes können die Angaben zum eigenen Standort ($myiac,$mynac,$mycc,$myndc) entsprechend angepasst werden, gleiches gilt für die Verbindungsparameter zu mysql. Sind die Parameter richtig eingestellt, kann man dem Skript die Rufnummer im lokalen Format übergeben. Eine lokale Rufnummer oder auch eine nationale (Ferngesprächs)nummer werden dann in das von Betamax erwartete und auch zur Zonenfindung benutzte Format umgesetzt.

Technisch noch interessant: Die function get_rate arbeitet rekursiv für den Fall, dass eine kostenlose Zone getroffen wurde und das Skript bei Aufruf mitgeteilt bekam, dass man keine Freedays hat (Parameter 2 = 0). Dann wird statt des kostenlosen Preises der entsprechende "Normalpreis" gezogen und ausgegeben.

Ein letzter Hinweis: Die MYSQL-Daten werden zwar auch von mir produktiv benutzt, jedoch besteht immer die Möglichkeit, dass sie in Teilen unrichtig sind. Ich kann mich hier nicht für alle enthaltenen Länder verbürgen, Hinweise zu eventuellen Fehlern nehme ich aber natürlich gerne entgegen ;)

Und nun viel Spaß beim Ausprobieren !
 

Anhänge

  • bmpreis.tar.gz
    22.1 KB · Aufrufe: 5
Das eigentliche Problem ist hier nicht der Preisabruf, vielmehr hast Du ein Problem mit dem Mapping Rufnummer -> Zone (z.B.: germany (landline)) von Betamax.

Rufnummer zu Zone zu mappen ist nicht so schwierig. Es gibt ja genug Tabellen, wie zB http://www.platinplus.com/deutsch/vorwahlen.html , bei Voicetrading hast du auch Zugriff zu dessen Mapping-Tabelle nachdem du dich einloggst, wird ja wohl die selbe sein wie bei anderen Betamax Clones.
Oder habe ich dich falsch verstanden?
 
Rufnummer zu Zone zu mappen ist nicht so schwierig.

Jein :rolleyes:. Festnetz und Mobilfunk - da gibt es beliebig viele Quellen (Deine kannte ich noch nicht, danke dafür:)).

Spannender sind Sonderrufnummern und die Frage, inwieweit die ggf. von Betamax geroutet werden und wenn ja - zu welchem Preis.
Die MYSQL-Daten berücksichtigen - soweit mir bekannt - solche Sonderrufnummern und weisen sie als nicht wählbar aus.
Was Betamax z.B. mit FreePhone (z.B.: 0049800 00180X etc.) macht oder aber mit VoIP (z.B.: 004932, 0043720, 0043780 etc.) oder SharedCostServices (004918X etc.) ist mir nicht klar (für UK ist es zumindest für 004487X explizit angegeben), hat da jemand Erfahrungen zur Tarifierung/Erreichbarkeit ?

Im übrigen kommt hinzu, dass unterschiedliche Klone unterschiedliche Verzonungen vornehmen, beispielsweise landline/mobile getrennt oder zusammen. Dies ist bei meinem Skript noch berücksichtigt worden.

Außerdem wirds in bestimmten Ländern schwierig, die keine Gassentrennung Mobil/Fest haben, wie wir das aus DE gewohnt sind. Skandinavien ist da ein gutes Beispiel, aber auch die Dominikanische Republik. Insoweit ist das dann doch schon ein weites Feld ...

Meine Aussage bezog sich jedoch grundsätzlich vor allem auf die Fragestellung des Originalposters zu einer RN-basierten Preisabfrage, für die der eigentlich spannende Teil m.E. tatsächlich das Mapping ist, das - auch daran sollte man denken - leider nicht in jedem Land so statisch ist, wie in DE. (RN-Block-Änderungen sind weltwit gar nicht so selten ...)
 
Jein :rolleyes:. Festnetz und Mobilfunk - da gibt es beliebig viele Quellen (Deine kannte ich noch nicht, danke dafür:)).

Spannender sind Sonderrufnummern und die Frage, inwieweit die ggf. von Betamax geroutet werden und wenn ja - zu welchem Preis.

Meine Erfahrung nach maptBetamax genau nach seine Mapping-Tabelle die frei zum Download steht (must dich bei Voicetrading anmelden). Derzeit trage ich die Kosten händisch in meine Tabelle die ich dann nutze die Kosten dem Anrufen anzusagen, die Preisliste zum downloaden kann man nur bei Voicetrading.

Das mit Sonderrufnummern verstehe ich nicht ganz was du meinst, glaube die die nicht in der Mapping-Tabelle sind kannst du sowieso gar nicht erreichen.
 
Also 0800er-Nummern kann man (* mit eingeschalteter Rufnr.-Übermittlung) auch über BM kostenlos anrufen.
BM-eigene 032-Nummern auch, wie es mit anderen 032-Nummern aussieht, weiss ich leider nicht.
0180-, 0900-, 013- geht nicht.

(*: Hatte 0800-3301000 versucht, geht aber nur mit Rufnr.-Übermittlung)
 
Wo genau? Ich finde kein eintsprechende Menüpunkt.

Im Voicetrading einloggen, springt ein Popup-Fenster, auf "Ratelist" klicken, auf Excel-File klicken, im Excel aufmachen -> da hast du dann die Preislisten samt "Ratelist" und "Numberplan" (2-tes Sheet).
Aber wie gesagt, das ist nur beim Voicetrading, andere BM Clones werden es wohl nicht haben.
 
Danke, ich habe niemals an das zweite Sheet geschaut. Übrigens nicht sehr genau. Ungarn hatte niemals 003650 als Mobilnetz, und Netz 003660 ist seit mindestens 5 Jahren außer Betrieb (früheres NMT).
 
Danke, ich habe niemals an das zweite Sheet geschaut. Übrigens nicht sehr genau. Ungarn hatte niemals 003650 als Mobilnetz, und Netz 003660 ist seit mindestens 5 Jahren außer Betrieb (früheres NMT).

Ist nicht unüblich das da Daten stehen die nicht relevant sind (3650, 3660). Für mich ist das wichtigste daß VT nach diesem Numplan abrechnet (und es scheint so zu sein).

http://www.nhh.hu/dokumentum.php?cid=8880 behauptet 50 und 60 seien nicht vergeben (so wie du behauptet hast).

Der Beste Numplan ist der von http://www.numberingplans.com/, ist laufend gepflegt, kostet aber.
 

Zurzeit aktive Besucher

Keine Mitglieder online.

Statistik des Forums

Themen
246,382
Beiträge
2,251,164
Mitglieder
374,040
Neuestes Mitglied
nady
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
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.