Namen des Anrufers aus der Datenbank

rethus

Neuer User
Mitglied seit
7 Jul 2007
Beiträge
137
Punkte für Reaktionen
0
Punkte
16
Jeder Nutzer, der keine Rufnummernübermittlung eingeschaltet hat, soll die Gelegenheit bekommen seine persönliche Pin einzugeben.
* soll dann in der DB (mysql) nachschauen, ob die Pin existiert, und wenn ja den Namen der zu dieser Pin gehört zurückgeben.
Existiert die pin, darf er in die Konferenz, existiert er nicht, wird er abgewiesen.

Wie könnte ich sowas realisieren? MIt Authenticate() gehts leider nicht, da ich ja dort die Pin vorher schon wissen müsste.

Hat jemand eine Idee?
 
Hi rethus!
Man könnte den Eindruck gewinnen, dass es ein stressiger Tag für dich war...

rethus schrieb:
Jeder Nutzer, der keine Rufnummernübermittlung eingeschaltet hat, soll die Gelegenheit bekommen seine persönliche Pin einzugeben.
Das klingt nach meiner Meinung irgendwie nach Seminaraufgabe für Mathematik/Informatikstudenten
rethus schrieb:
* soll dann in der DB (mysql) nachschauen, ob die Pin existiert, und wenn ja den Namen der zu dieser Pin gehört zurückgeben.
Bring mit dieser Idee Bitte nicht Verwalter von sensiblen Daten auf die falsche Spur.
rethus schrieb:
Existiert die pin, darf er in die Konferenz, existiert er nicht, wird er abgewiesen.
???
rethus schrieb:
Hat jemand eine Idee?
Spassecke oder ggf. die Aufgabenstellung verändern.
 
AGI hilft

Hallo rethus,

das lässt sich grundsätzlich schon machen über den Dialplan, immerhin spricht Asterisk auch MySQL. Ich persönlich würde das aber über ein AGI machen, damit bekommt man das sicher hin. (AGI+PHP Fan!)

Die einzige Hürde, die ich darin sehe, ist das mit dem Namen vorlesen. Ich habe mit Text2Speech on-the-fly bisher nur schlechte Erfahrungen gemacht. Entweder nimmst Du die ganzen Namen vorher auf, oder begnügst Dich mit einer (alpha)numerischen Benutzer-ID, die kannst dann problemlos von Asterisk vorlesen lassen.

Eine sinnvolle Zeile kann ich ilmtuelps Beitrag auch entnehmen, nämlich die Sache mit sensiblen Daten. Soll heißen, mach die PIN vielleicht etwas länger als drei Ziffern. Aber ich glaube, so viel Vernunft hat jeder.

Rentier
 
hallo rentier-s,

ja die Pin ist derzeit 5 Stellen lang, wobei ich von ca. 100 hinterlegten Pins ausgehe

Im Grunde ist die Pin auch kein Zugangsschutz (nur als einfache Zugangshürde gedacht), sondern soll mir hinterher für die Personen den Namen in meiner Webapplikation anzeigen, welche Rufnummerübermittlung abgeschaltet haben.

Damit ich dann weiß, wen ich sprechend schalten kann usw.

Mit AGI hab ich auch schon gebastelt, komme abernicht so recht weiter.
txt2wav will ich eigentlich nicht unbedingt nutzen (wenn nicht nötig) aber ich vermute dass ich ja irgendwie mitteilen muss wann der Teilnehmer seine Pin eingeben muss, usw.

Hast du da n ansatz, der mich gedanklich in die richtige Richtung lenkt?
 
Ich sag ja, an sichere PINs denkt man eigentlich selber.

Die Ansagen von wegen "Bitte geben Sie jetzt Ihre PIN ein" und so Zeug kann man sich einmal von einer Kollegin mit netter Stimme aufsprechen lassen. Das ist kein Thema. Ich hatte das so verstanden, dass der Herr Mustermann anruft, seine PIN eingibt und Asterisk dann sagen soll, "Sie sind Herr Mustermann und betreten jetzt die Konferenz". Das meinte ich mit schwierig.

Ansatz, ja das kommt halt ganz darauf an, wie Du das nun machen willst. Wie schon gesagt bin ich ein absoluter Fan von PHP Skripts als AGI, und mache fast alles damit. Das macht aber nur Sinn, wenn Du Dich in PHP ein wenig auskennst. Ansonsten müssten wir einen Dialplan mit MySQL Anbindung basteln.

Rentier
 
Hier ein Vorschlag als PHP AGI

Das ganze ist vollkommen ungetestet und nur aus dem Kopf heraus geschrieben!

Code:
#!/usr/bin/php -q
<?php

ob_implicit_flush(true);
set_time_limit(10);
error_reporting(0);

$in = fopen("php://stdin","r");

function read() {
  global $in;
  $input = str_replace("\n", "", fgets($in, 4096));
  return $input;
}

function write($line) {
  echo $line."\n";
}

while ($env=read()) {
  $s = split(": ",$env);
  $agi[str_replace("agi_","",$s[0])] = trim($s[1]);
  if (($env == "") || ($env == "\n")) {
    break;
  }
}

function fragePIN() {
  write('EXEC READ pin,pin_eingabe,5'); # braucht pin_eingabe.gsm
  read();
  write('GET VARIABLE pin');
  return substr(strrchr(read(),"("),1,-1);
}

$sql_con = mysql_connect ("localhost", "user", "password");
mysql_select_db ("asterisk", $sql_con);

$mysql_query = mysql_query ("SELECT benutzerid FROM benutzer WHERE rufnummer=" . $agi['callerid'] . ";", $sql_con);
if ($mysql_result = mysql_fetch_object ($mysql_query) ) { # CallerID erkannt, zur Konferenz
  write ("GOTO konferenz,1,1");
  read();
} else { # CallerID nicht erkannt, frage nach PIN
  $mysql_query = mysql_query ("SELECT benutzerid FROM benutzer WHERE pin=" . fragePIN() . ";", $sql_con);
  if ($mysql_result = mysql_fetch_object ($mysql_query) ) { # PIN gefunden
    write ("SAYDIGITS " . $mysql_result->benutzerid);
    read();
    write ("GOTO konferenz,1,1");
    read();
  } else {
    write ("HANGUP"); # falsche PIN, leg auf
    read();
  }
}

mysql_close ($sql_con);
fclose($in);

exit;
?>
 
Hier noch ein Versuch als Dialplan

Ebenfalls ungetestet und mehr oder weniger geraten in Anlehnung an http://www.voip-info.org/wiki/view/Asterisk+cmd+MYSQL

Code:
exten => _X.,1,MYSQL(Connect connid localhost dbuser dbpass asterisk)
exten => _X.,2,MYSQL(Query resultid ${connid} SELECT\ benutzerid\ from\ benutzer\ WHERE\ rufnummer=${CALLERID(number)})
exten => _X.,3,MYSQL(Fetch fetchid ${resultid} benutzerid)
exten => _X.,4,MYSQL(Clear ${resultid})
exten => _X.,5,MYSQL(Disconnect ${connid})
exten => _X.,6,GotoIf($[${fetchid}]?7:konferenz,1,1)
exten => _X.,7,Read(pin_eingabe,pin,5)
exten => _X.,8,MYSQL(Connect connid localhost dbuser dbpass asterisk)
exten => _X.,9,MYSQL(Query resultid ${connid} SELECT\ benutzerid\ from\ benutzer\ WHERE\ pin=${pin})
exten => _X.,10,MYSQL(Fetch fetchid ${resultid} benutzerid)
exten => _X.,11,MYSQL(Clear ${resultid})
exten => _X.,12,MYSQL(Disconnect ${connid})
exten => _X.,13,GotoIf($[${fetchid}]?16:14)
exten => _X.,14,SayDigits(${benutzerid})
exten => _X.,15,Goto(konferenz,1,1)
exten => _X.,16,HangUp
 
Dialplan

Es ist am einfachsten den privacy manager zu benutzen und dann die auswertung über db cidname zu machen.
Dann kannst du denjenigen die auch ihre rufnummer übermittel auch einen Namen zum aneigen geben.
 
rentier-s:
Danke für dein Ausführliches Script.
Ich hab es jetzt mal für meine Bedürfnisse umgesetzt. An der ein oder anderen Stelle harkt es allerdings noch.

Beispielsweise wenn ich eine Pin eingebe (12345), dann nimmt er nicht immer alle Zahlen (bzw. nimmt nie alle Zahlen... Ausgegeben wird im AGI-Debug dann sowas wie:

Code:
<SIP/sipgate.de-b5acb440>AGI Rx << EXEC READ pin,conf-getpin,5
    -- AGI Script Executing Application: (READ) Options: (pin,conf-getpin,5)
    -- Accepting a maximum of 5 digits.
    -- <SIP/sipgate.de-b5acb440> Playing 'conf-getpin.gsm' (language 'en')
    -- User entered '235'
<SIP/sipgate.de-b5acb440>AGI Tx >> 200 result=0
<SIP/sipgate.de-b5acb440>AGI Rx << GET VARIABLE pin
<SIP/sipgate.de-b5acb440>AGI Tx >> 200 result=1 (235)
und dass obwohl ich 1 2 3 4 5 schön langsam eingegeben habe. Gibt es hier vielleicht eine Möglichkeit, die Pinabfrage Fehlerresistenter zu machen? Dass keine digits verloren gehen, und bis zu 3 Fehlversuche möglich sind? Übrigens, klicke ich die # nach meinen 5 Stellen, wird sogar gar keine Pin übernommen.

Zudem würde mich interessieren, wie ich regulär einfach ein gsm-file abspielen kann.. z.B. wenn die 3 Abfragen falsch waren, das goodbye. Hab es mit
Code:
write ("STREAM FILE vm-sorry");
versucht, aber da kommen nur fehler.
 
Hallo rethus,

ich verwende selbst den read Befehl mal im Context und mal im AGI. Dabei habe ich festgestellt, dass bei einer schlechten SIP Verbindung manchmal Ziffern doppelt erkannt werden, aber unabhängig vom AGI.

Hast Du den read Befehl mal in einem normalen Context, also ohne AGI, ausprobiert? Er sagt nämlich vorher schon, dass er nur 235 verstanden hat, bevor die Variable wieder vom AGI eingelesen wird. Im Zweifel müsstes Du das AGI beenden, den Anruf zur PIN-Eingabe zurück in den Context schicken und dann das AGI wieder mit der PIN als Parameter aufrufen.

Zur Not könntest Du auch jede Ziffer einzeln abfragen und direkt wiedergeben, bis es fünf hintereinander sind. Auf ähnliche Weise lassen sich auch mehrere Versuche realisieren. Wie fit bist Du in PHP?

Sound-Files kannst Du ganz normal mit playback einspielen, im AGI also
Code:
write('EXEC PLAYBACK goodbye');

Ah übrigens, in dem MySQL Beispiel sind im Query String die Leerzeichen noch escaped, das braucht man in 1.6 nicht mehr machen, 1.4 weiß ich nicht.

Rentier
 
Ok, also vorweg, ich arbeite seit über 10 Jahren mit php (du hast danach gefragt wie fit ich bin)

Und zu der geschichte mit AGI. Ich verwende die PHPAGI-Klassen, wo diese Funktionen auch bereit in handliche Funktionen mit Kontrollstrukturen gekapselt sind.

geht auch ganz sauber, sogar etwas besser als bei deinem read(). aber auch hier habe ich das Problem, dass die Pin-Zahlen langsam eingegeben werden müssen und nicht immer entsprechend erkannt werden.

Hier müsste unbedingt noch eine regelung her, welche die eingegebenen Zahlen schneller einließt.

Ggf. mach ich es mal so wie du sagst, dass ich ihn in einen anderen Context zurückschicke, der seine Eingabe einließt, und diese in ner Asterisk-Variable speichert und dann zurück ans AGI-Script gibt... wobei man dann ja mind. 2 Agi-Scripte haben muss, oder ein schleifenkonstrukt, welches den Status der Variable abfragt und da weitermacht, wo zuvo aufgehört wurde.
 
Ok, also vorweg, ich arbeite seit über 10 Jahren mit php (du hast danach gefragt wie fit ich bin)

Und zu der geschichte mit AGI. Ich verwende die PHPAGI-Klassen, wo diese Funktionen auch bereit in handliche Funktionen mit Kontrollstrukturen gekapselt sind.

Na das wenn ich gewusst hätte, ich texte da extra ein schön übersichtliches AGI hin ;)

Wie gesagt, probier mal den read in einem einfachen Context. Wenns da klappt, dann wird das der beste Weg sein.

Vielleicht so:
Code:
exten => s,1,AGI(meinagi,${pin})
exten => s,n,Read(fragnachpin,__pin,5)
exten => s,n,Goto(1)
exten => s,n(dreimal),Playback(goodbye)
exten => s,n,HangUp

Dann brauchst Du nur das AGI zu beenden, damit die PIN abgefragt wird. Sollte vorher schon die callerid, oder nachher dann die PIN passen, springst Du sowieso mit Goto aus dem AGI zu Deiner Konferenz. Gegen Bruteforce kannst Du noch eine Variable mitlaufen lassen und den Anrufer ggf. mit Goto(dreimal) rauswerfen.

Rentier
 
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.