Ergebnis 1 bis 8 von 8

Thema: Perl Skript in ein AGI Skript (ankommende SMS verarbeiten)

  1. #1
    IPPF-Einsteiger
    Registriert seit
    14.07.2011
    Ort
    Sauerland
    Beiträge
    23

    Perl Skript in ein AGI Skript (ankommende SMS verarbeiten)

    Hi,
    ich habe gestern angefagen mit perl zu experimentieren. So jetzt hab ich mir nen Perl Skript geschrieben, womit ich den Text einer ankommenden SMS in Asterisk auslesen kann.
    Aber ich hab kein Plan wie ich das Skript jetzt verändern muss, damit ich es in Asterisk als AGI Skript ausführen kann. Ich hab mir schon einiges durchgelesen, aber ich blicke da überhaupt nicht durch.

    Könnte mir einer erklären, was ich machen muss?

    Danke schonmal

    hier ist der perl code:
    Code:
    #!/usr/bin/perl -w
    
    use strict;
    
    #Verzeichnes der ankommenden SMS
    my $dir = "/var/spool/asterisk/sms/mtrx/";
    
    #Suche, nach der neusten SMS-Datei
    my $LATESTSMS = (
        map{
            $_->[0]
        }
        sort{
            $a->[1] <=> $b->[1]
        }
        map{
            [$_, -M $_]
        }
        grep {
            -f $_ and $_ =~ /Mein-SIPID/
        }
        glob(
             $dir."*"))[0];
    
    #Öffnen der SMS
    open(SMS, $LATESTSMS);
    
    #Suche und Ausgabe des SMS Textes
    for my $MSG (<SMS>){
            if($MSG =~ /ud=/){
                    $MSG =~ s/ud=//;
                    print "Der Text der SMS lautet: $MSG";
            }
    }
    close SMS;
    Geändert von oskars (16.08.2011 um 17:52 Uhr)

  2. #2
    Moderator Avatar von rentier-s
    Registriert seit
    19.10.2006
    Ort
    Niederbayern
    Beiträge
    2.331
    Da ich Dir so mehr oder weniger dazu geraten habe, sehe ich mich verpflichtet Dir jetzt soweit es geht weiterzuhelfen, obwohl ich mich mit Perl noch so gut wie nie beschäftigt habe.

    Schau mal hier, da steht die Erstellung eines AGI Skripts in Perl Schritt für Schritt.

    Was möchtest Du mit dem Skript genau erreichen, soll da nur der Test ausgewertet und zB. als Variable an Asterisk zurückgegeben werden, oder möchtest Du damit noch mehr ausführen?
    Alles schöne im Leben ist entweder verboten, zu teuer oder macht dick!

  3. #3
    IPPF-Einsteiger
    Registriert seit
    14.07.2011
    Ort
    Sauerland
    Beiträge
    23
    Hi danke ich werds mir nächste woche mal angucken. Ich bin im moment dabei noch perl besser kennen zulernen.
    Das gehört alles zu meinem Projekt im Praktikum. Ich soll einen Asteriskserver bauen, der SMS empfangen kann und dann je nach Inhalt der Nachricht und des Absenders eine vorgegebene Telefonlist abtelefoniert. Die angerunfenden müssen dies dann mit einer Taste bestätigen. Deshalb muss ich die SMS datei auslesen und wenn ich das bis jetzt alles richtig verstanden habe kann man mit einem AGI skript viele Sachen einfacher erledigen, als mit einem komplizierten Dialplan.
    Naja mal gucken ob ich alles ans laufen bekomme.


    -----------------------------
    edit(01.08.2011):

    habs zum laufen bekommen mit dem beispiel. Es hätte auch vorher funktioniert, aber ich hatte ne neuere perl version installiert und da war der pfad dann /usr/local/bin/perl und nicht mehr /usr/bin/perl. (falls einer nach dem pfad sucht, einfach "which perl" in die console)

    Wenn ich mit meinem Ergebnis zufrieden bin, werde ich es posten.

    -----------------------------
    edit(03.08.2011):

    So Hier ist erstmal mein Script zum auslesen, der SMS.
    Code:
    #!/usr/local/bin/perl -w
    
    use strict;                                                     #hilft bei der Fehlevermeidung
    use Asterisk::AGI;
    
    $|=1;
    my $MSG, my $ABS;
    
    #-----------------------------------------
    #while(<STDIN>) {
    #       chomp;
    #               last unless length($_);
    #               if (/^agi_(\w+)\:\s+(.*)$/) {
    #                       $AGI{$1} = $2;
    #               }
    #}
    #print STDERR "AGI Environment Dump:\n";
    #foreach my $i (sort keys %AGI) {
    #        print STDERR " -- $i = $AGI{$i}\n";
    #}
    #------------------------------------------------
    
    my $dir = "/var/spool/asterisk/sms/mtrx/";                      #Pfad zum SMS Ordner
    my $lastsms_pfad = (reverse(sort(glob "$dir/Meine-SIPID*")))[0];    #letzte SMS Datei mit Pfad
    
    &lastsms;                                                       #ruft die Sub-Funktion auf
    
    open(SMS, $lastsms_pfad);                                       #öffent die Datei, um damit zuarbeiten
    foreach my $line (<SMS>){                                       #kontrolliert jede Zeile in der SMS, die aktuelle Zeile wird in der Variable $line gespeichert
            if($line =~ /ud=/){                                     #sucht nach der Nachricht, bei einer SMS von Asterisk beginnt diese Zeile mit "ud=".
                    $MSG = $line;                                   #setzt die Variabel $MSG gleich der aktuellen Zeile
                    $MSG =~ s/ud=//;                                #entfernt das voran stehende "ud="
                    print "Der Text lautet: $MSG";                 #gibt die Nachricht aus
                    print "SET VARIABLE SMST \"$MSG/";        #gibt die Variable weiter an Asterisk
            }
            if($line =~ /oa=/){                                     #sucht nach der Absendernummer (s.o). --> Später soll der Absender in einer Datenbank geucht werden.
                    $ABS = $line;
                    $ABS =~ s/oa=//;
                    print "Die Absendernr. ist: $ABS";
            }
    }
    close SMS;                                                      #schließt die Datei
    
    
    #----------------------
    #****SUB-FUNKTIONEN****
    #----------------------
    
    #Entfernen des Dateipfades zur neusten SMS
    sub lastsms {                                                   #Erstellen der Sub-Funktion
            my $lastsms_name = $lastsms_pfad;                       #überträgt den Namen
            $lastsms_name =~ s/$dir\///;                            #entfernt den Pfad
            print "$lastsms_name\n";                                #gibt den Dateinamen aus
    }
    So zum Code:
    Ich hab den AGI Kram immer noch nicht so ganz gescheckt, bzw welche Angaben wirklich benötigt werden und welche nicht. Deshalb habe ich den Teil am Anfang auskommentiert, da ich ja nix einlesen will, sondern nur das Script ausführen und was zurück geben will.
    Die Suche nach der neusten Datei ist noch nicht perfekt, da hier nach dem Namen sortiert wird. Allerdings funktioniert es trotzdem, weil im Namen das Datum mit Uhrzeit enthalten ist und sonst alles andere gleich ist. Ich versuche es aber später noch zuverbessern. Im moment bin ich dabei anhand der Absendernummer, die entprechenden Daten aus einer Datenbank (MySQL) zulesen.
    Geändert von oskars (03.08.2011 um 17:43 Uhr) Grund: Update
    aja, so ist es richtig. Schwachsinn!

  4. #4
    IPPF-Einsteiger
    Registriert seit
    14.07.2011
    Ort
    Sauerland
    Beiträge
    23
    Hi, ich bin schon etwas weiter (werde mein aktuellen Stand morgen posten). Habe aber eine Frage ist es möglich meine in der Datenbank eingetragenen Telefonliste abzutelefonieren via Perl skript oder gibt es da eine besondere Funktion für den Dialplan? Meine Lösung wäre jetzt jede einzelne Nummer mit einem Perlskript aus der Datenbank auszulesen und dann an den Dialplan zusenden, den Anrufen auszuführen und dann mit dem Perlskript die nächste Nummer aus lesen. Aber das ist recht umständlich. Habe hier im Forum gesucht, aber wahrscheinlich habe ich nur nach den Falschenbegriffen gesucht.
    aja, so ist es richtig. Schwachsinn!

  5. #5
    IPPF-Tausend-VIP
    Registriert seit
    04.09.2005
    Beiträge
    1.297
    Hi oskars!
    Zitat Zitat von oskars;
    Habe hier im Forum gesucht, aber wahrscheinlich habe ich nur nach den Falschenbegriffen gesucht.
    Wo solll denn Falschenbegriffen vorkommen? In Asterisk, PHP Perl oder AGI?

  6. #6
    IPPF-Einsteiger
    Registriert seit
    14.07.2011
    Ort
    Sauerland
    Beiträge
    23
    Danach hab ich schon gesucht, hab mir auch die meinsten beiträge mal angeguckt Ich habe jetzt auch den Beitrag "Telefonterror" gefunden, aber ich bin daraus nicht schlau geworden..
    Meine Idee für die Lösung wäre jetzt, dass ich mit meinem perl skript immer eine Nummer aus der Datenbank auslese und dann an asterisk sende und dort anrufe, und danach die nächste nummer, wie oben beschrieben. Aber das kommt mir irgendwie sehr kompliziert vor, nicht das programmieren, sondern der Ablauf, der dann immer wieder ausgeführt wird. Naja ich arbeite im moment erstmal an nen Bestätigungsmenu beim Anruf, vll kennt ja einer von euch ne Lösung eine Telefonliste abzutelefonieren. Es soll kein Spam oder ähnliches sein.

    --------------------------------------
    edit(10.08.2011):
    So hier ist mein jetziger Stand.
    -> habs gelöscht da unten das gleiche nochmal ist.
    Geändert von oskars (12.08.2011 um 10:25 Uhr)
    aja, so ist es richtig. Schwachsinn!

  7. #7
    IPPF-Einsteiger
    Registriert seit
    14.07.2011
    Ort
    Sauerland
    Beiträge
    23
    Hi,

    das hier hab ich bis jetzt. Es wird die ankommende SMS ausgelesen und überprüft, ob die Absendernr. in der Datenbank vorhanden ist. Wenn dies der Fall ist wird der Text nach einem Schlüsselwort überprüft. Wird dieser gefunden wird der Name der abzuspieleden Sounddatei ausgegeben, falls nicht wird Text to Speech verwendet.
    Nun werden die Nummern der Mitarbeiter aus der Datenbank ausgelesen und in Arrays gespeichert. Diese werden dann nach einander angerufen.

    Hier habe ich noch das Probleme, wenn ein Mitarbeiter nicht direkt nach abspielen des Soundfiles auflegt, wird er mit dem nächsten verbunden, was aber nicht passieren soll. Aber das werde ich heute noch verbessern.

    Sonst bin ich recht zufrieden. Es ist bestimmt nicht die beste Lösung, aber es funktioniert erstmal alles, auch wenn es teilweise recht umständlich ist (hab erst vor ca. 2 1/2 Wochen angefangen mit Perl zuarbeiten und muss auch erst Asterisk richitg verstehen). Ein paar kleine Sachen muss ich noch verbessern, sowie ein Bestätigungsmenü einbauen.

    So hier ist das Script, vll hilft es ja irgendeinen.

    1.SMS auslesen und überprüfen.
    Code:
    #!/usr/local/bin/perl -w
    
    #****Funktionen/Module****
    use strict;                                                     #hilft bei der Fehlevermeidung
    use Asterisk::AGI;
    use DBI;
    use DBD::mysql;
    
    $|=1;
    
    #****Variablen****
    my $MSG; #Textnachricht
    my $ABS; #Absendernummer
    my $DATI; #DAte und TIme
    my $DATE; #Eingangsdatum
    my $TIME; #Eingagnszeitpunkt
    
    #----------------------------------------------------------------------
    #****************************Datei auslesen****************************
    #----------------------------------------------------------------------
    my $dir = "/var/spool/asterisk/sms/mtrx/";                      #Pfad zum SMS Ordner
    my $lastsms_pfad = (reverse(sort(glob "$dir/SIPGATEID*")))[0];    #letzte SMS Datei mit Pfad (kurze Version)
    
    open(SMS, $lastsms_pfad);                                       #öffent die Datei, um damit zuarbeiten
    foreach my $line (<SMS>){                                       #kontrolliert jede Zeile in der SMS, die aktuelle Zeile wird in der Variable $line gespeichert
            if($line =~ /oa=/){                                     #sucht nach der Absendernummer, bei einer SMS von Asterisk beginnt diese Zeile mit "oa=".
                    $ABS = $line;                                   #setzt die Variabel $ABS gleich der aktuellen Zeile
                    $ABS =~ s/oa=//;                                #entfernt das voran stehende "oa="
                    #print "Nummer: $ABS";                                  #gibt die Nummer aus
                    print "SET VARIABLE ABS \"$ABS";
                    chomp $ABS;
            }elsif($line =~ /ud=/){                                 #sucht nach dem Text  und gibt diesen aus.
                    $MSG = $line;
                    $MSG =~ s/ud=//;
                    #print "Text: $MSG";
                    print "SET VARIABLE MSG \"$MSG";
                    chomp $MSG;
            }elsif($line =~ /scts=/){                               #sucht nach dem Eingagnsdatum mit Zeit und splitet es in Datum und Zeit auf.
                    $DATI = $line;
                    $DATI =~ s/scts=//;
                    my @DATI = split /T/, $DATI;
                    $DATE = $DATI[0];
                    #print "Datum: $DATE\n";
                    print "SET VARIABLE DATE \"$DATE\n";
                    $TIME = $DATI[1];
                    #print "Zeit: $TIME\n";
                    print "SET VARIABLE TIME \"$TIME\n";
    
            }
    }
    close SMS;                                                      #schließt die Datei
    
    #---------------------------------------------------------------------
    #********************Verbindung mit der Datenbank*********************
    #---------------------------------------------------------------------
    
    #Verbindung mit der Datenbank
    my $host = 'localhost';                                         #host
    my $database = 'asterisk';                                      #Tabellenname
    my $user = 'user';                                              #benutzer
    my $pw = 'password';                                           #passwort
    my $dsn = "dbi:mysql:$database:localhost:3306";                 #adresse
    my $dbh = DBI->connect($dsn, $user, $pw) or die DBI::errstr;    #Verbindung herstellen
    
    #--->1.Suche nach dem Absender
    #Datensatz auslesen
    my $title = $dbh->prepare("SELECT * FROM Anrufer WHERE Handy = $ABS");#Normaler SQL Befehl
    my $control = $title->execute();
    
    #Überprüfen, ob die NUmmer in der Datenbank eingetragen ist, wenn nicht wird das Skript abgebrochen
    if($control == undef){
            print "SET VARIABLE vorhanden no\n";
            die DBI::errstr;
    }else{
            print "SET VARIABLE vorhanden yes\n";
    }
    
    while (my $anrufer = $title->fetchrow_hashref){
            #print $anrufer->{Name};
    };
    
    #
    #--->2.Suche nach der Nachricht
    #Datensatz auslesen (Text für Text to Speech oder Soundfile)
    my $problem = $dbh->prepare("SELECT * FROM Probleme WHERE Schluessel = '$MSG'");
    $control = $problem->execute();
    
    #Überprüfen, ob der Text in der Datenbank vorhanden ist, wenn ja wird der Name der Sounddatei ausgegeben sonst wird Text to Speech verwendet.
    if ($control ne undef){
            #Datensatz in einem Hash speichern
            while (my $probleme = $problem->fetchrow_hashref) {
                    my $sound2 = $probleme->{Soundname};
                    print "SET VARIABLE sound \"$sound2\n";
                    print "SET VARIABLE tts no\n";
                    }
    }else{
            print "SET VARIABLE tts yes\n";
    }
    
    $dbh->disconnect();#trennt die Verbindung zur Datenbank
    2.Nummern auslesen und in Arrays speichern
    Code:
    #!/usr/local/bin/perl
    
    #use strict;
    use DBI;
    use DBD::mysql;
    
    
    #---------------------------------------------------------------
    #******************Auslesen aus der Datenbank*******************
    #---------------------------------------------------------------
    my $host = 'localhost';                                         #host
    my $database = 'asterisk';                                      #Tabellenname
    my $user = 'root';                                              #benutzer
    my $pw = '18usc795+';                                           #passwort
    my $dsn = "dbi:mysql:$database:localhost:3306";                 #adresse
    my $dbh = DBI->connect($dsn, $user, $pw) or die DBI::errstr;    #Verbindung herstellen
    
    my $mitarbeiter = $dbh->prepare("SELECT * FROM Mitarbeiter");
    $mitarbeiter->execute;
    
    my $anzahl = $mitarbeiter->execute;
    
    while (my $anrufer = $mitarbeiter->fetchrow_hashref){
    };
    
    my $telnum = $dbh->prepare("SELECT m.MID, m.Name, t.Nummer FROM Mitarbeiter AS m INNER JOIN Telefonnummer AS t ON m.MID = t.MID");
    $telnum->execute();
    
    my %hash;
    my @nummern;
    my $l1 = 1;
    my $l2 = 1;
    
    while ($l1 <= $anzahl){
            print "Mitarbeiter Nr.$l1\n";
            $telnum->execute();
            while (my $row = $telnum->fetchrow_arrayref){
                    if($row->[0] eq "$l1"){
                            foreach my $nummer ($row->[2]){
                                    #my @nummern =($row->[2]);
                                    #print "$nummern[$zah2]\n";
                                    print "$l2. Nummer => $nummer\n";
                                    push @{"mitnummer_$l1"}, $nummer;
                            }
                    }
            }
            $l1 += 1;#Hochzählen der Mitarbeiternummer
            $l2 += 1;#Hochzähler der Nummer für die Telefonummern
    }
    $dbh->disconnect();#trennt die Verbindung zur Datenbank
    
    #---------------------------------------------------------------
    #*****************Übertragung an Asterisk***********************
    #---------------------------------------------------------------
    
    my $mid = $ARGV[0];#gibt die Mitarbeiternummer an
    my $numid = $ARGV[1];
    my $control;
    
    #Anzahl der Nummern je Mitarbeiter
    my $numanzahl = (@{"mitnummer_$mid"}-1);
    print "$numanzahl \n";
    
    if($mid <= $anzahl){
            $control = "no";
            print "SET VARIABLE CONTROL \"$control\n";
    }else{
            $control = "done";
    }       print "SET VARIABLE CONTROL \"$control\n";
    
    if($control ne "done"){
            my $NUM = ${"mitnummer_$mid"}[$numid];
            print "SET VARIABLE NUM \"$NUM\n";
            print "SET VARIABLE NUMANZAHL \"$numanzahl\n";
            print "SET VARIABLE CONTROL \"$control\n";
            $mid += 1;
            $numid += 1;
    }else{
            print "SET VARIABLE end ende\n";
    };
    3.Hier meine extensions.ael
    Code:
    context eingang {
            1000 => {
                    Answer();
                    AGI(SMS-Eingang);
                    SET(GLOBAL(sound)=${sound});
                    SET(GLOBAL(TextToSpeech)=${MSG});
                    SET(GLOBAL(tts)=${tts});
                    SET(GLOBAL(vorhanden)=${vorhanden});
                    NoOp(${vorhanden});
                    if(${vorhanden} = yes){
                            jump 2003@spass;
                    }else{
                            NoOp("Der Absender ist nicht in der Datenbank vorhanden!");
                    }
            }
    }
    
    
    context spass   {
            2003 => {
                    SET(GLOBAL(MID)=1);
                    SET(GLOBAL(NUMID)=0);
                    SET(GLOBAL(CONTROL)="no");
                    SET(GLOBAL(NUMANZAHL)=0);
                    jump 2002;
            }
            2002 => {
                    AGI(Liste,${MID},${NUMID});
                    SET(GLOBAL(NUM)=${NUM});
                    SET(GLOBAL(NUMANZAHL)=${NUMANZAHL});
                    NoOp(${NUMANZAHL});
                    SET(GLOBAL(CONTROL)=${CONTROL});
                    if(${CONTROL} =done){
                            jump 2007;
                    }
                    NoOp(${NUM});
                    NoOp(${NUMID});
                    jump 2004;
            }
            2006 => {
                    if(${NUMID}<${NUMANZAHL}){
                            SET(GLOBAL(NUMID)=${MATH(${NUMID}+1,int)});
                            jump 2002;
                    }else{
                            SET(GLOBAL(MID)=${MATH(${MID}+1,int)});
                            SET(GLOBAL(NUMID)=0);
                            NoOp(${MID});
                            jump 2002;
                    }
            }
    
            2004 => {
                    DIAL(SIP/${NUM},5,G(spass^2005^1));
                    if(${DIALSTATUS}=NOANSWER OR CONGESTION OR BUSY){
                            jump 2006;
                    }
            }
    
            2005 => {
                    Wait(3);
                    if(${tts}=yes){
                            System(rm -rf /tmp/test.wav);
                            System(/opt/swift/bin/swift -o /tmp/test.wav -p audio/sampling-rate=8000,audio/channels=1 "${TextToSpeech}");
                            Playback(/tmp/test);
                    }else{
                            Playback(${sound});
                    }
                    Wait(5);
                    Hangup();
                    jump 2006;
            }
    
            2007 => {
                    NoOp("FERTIG !!!!!!!!!!!!");
            }
    }
    So werde nächste Woche oder so noch ne verbesserte Version posten.

    ps: teilweise sind überflüssige Codezeilen im Script. Diese haben meistens als Test gedient oder ich weiß nicht dass diese überflüssig sind.
    Geändert von oskars (12.08.2011 um 10:28 Uhr)
    aja, so ist es richtig. Schwachsinn!

  8. #8
    IPPF-Einsteiger
    Registriert seit
    14.07.2011
    Ort
    Sauerland
    Beiträge
    23
    So, hab jetzt fast alles vollständig. Muss nur noch die einzelnen Skripte usw. zusammenfügen und noch nen paar kleinere Verbesserungen machen und Funktionen einfügen. Und dann nochmal alles testen. Falls Interesse besteht werde ich es dann komplett posten.
    aja, so ist es richtig. Schwachsinn!

Ähnliche Themen

  1. getfbcalls.pl, Perl-Skript zur automat. Anrufabfrage
    Von prodigy7 im Forum andere Software
    Antworten: 44
    Letzter Beitrag: 20.02.2010, 19:38
  2. perl verbindungs-skript
    Von prolongado im Forum Asterisk Skripte
    Antworten: 2
    Letzter Beitrag: 06.09.2006, 11:10
  3. keine ausgabe im perl-agi-skript möglich
    Von prolongado im Forum Asterisk Skripte
    Antworten: 1
    Letzter Beitrag: 16.08.2006, 20:20
  4. Antworten: 15
    Letzter Beitrag: 06.07.2006, 17:45
  5. getfbcalls.pl, Perl-Skript zur automat. Anrufabfrage
    Von prodigy7 im Forum FRITZ!Box Fon: Telefonie
    Antworten: 17
    Letzter Beitrag: 02.01.1970, 13:46

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •