Telegram-Benachrichtigung bei neuer Nachricht auf dem FritzBox-Anrufbeantworter

Ich habe mich heute mal mit dem Telegram-BOT auseinandergesetzt und finde den richitg cool. Man kann damit relativ einfach Nachrichten generieren und an einen gewählten Verteiler verschicken. Ich weiß, dass es dazu auch ein Modul gibt. Ich bin allerdings ein Freund von kleinen übersichtlichen Skripten.

Hier also ein Skript, das von der Fritzbox die Sprachnachrichten zieht und diese zu Telegram weiterleitet.

Das Skript sieht wie folgt aus:

<?
#----------------------------------------------------------------
#		Nachrichten auf dem AB aus der Fritzbox auslesen
#        und über Telegramm-Bot versenden
#		von Silberstreifen
#		V1.0 vom 02.02.2019
#
#----------------------------------------------------------------

#----------------------------------------------------------------
#		Basis-Daten
#----------------------------------------------------------------

    $fritzbox_ip = 'fritz.box'; # muss ggf. angepasst werden
	$password    = 'ganzGeheim'; # muss angepasst werden

	$SID_ID = 12345;  # muss angelegt und angepasst werden
	$SID = GetValue($SID_ID);

    $url        = 'https://api.telegram.org';
    $bot        = '23123123mmmm234sfodis3o422pop-34';  # muss erzeugt und angepasst werden
    $chat_IDs   = array(
        123456789,                                                                    # muss angepasst werden
        987654321                                                                     # muss angepasst werden
    );
    $wav_file    = '/var/lib/symcon/webfront/user/rec.wav';

    $last_EX = IPS_GetScript($_IPS['SELF'])['ScriptExecuted']*2 - time();

#----------------------------------------------------------------
#		Doppelausführung verhindern
#----------------------------------------------------------------

    $Thread = 0;
    foreach (IPS_GetScriptThreadList () as $lfdNr => $Nr) {
        if (IPS_GetScriptThread ($Nr)['ScriptID']==$_IPS['SELF'])$Thread++; 
    }  
    if($Thread>2) return;

#----------------------------------------------------------------
#		In FritzBox einloggen und Daten holen
#----------------------------------------------------------------

    if ($SID == ""){
        $ch = curl_init($fritzbox_ip.'/login_sid.lua');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $login = curl_exec($ch);
        $session_status_simplexml = simplexml_load_string($login);
        if ($session_status_simplexml->SID != '0000000000000000'){
            $SID = $session_status_simplexml->SID;
        }else{
            $challenge = $session_status_simplexml->Challenge;
            $response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $password, "UCS-2LE", "UTF-8"));
            
            curl_setopt($ch, CURLOPT_POSTFIELDS, "response={$response}&page=/login_sid.lua");
            $sendlogin = curl_exec($ch);
            $session_status_simplexml = simplexml_load_string($sendlogin);
            
            if ($session_status_simplexml->SID != '0000000000000000'){
                $SID = $session_status_simplexml->SID;
            }else{
                echo "Fehler: Login fehlgeschlagen";
                return;
            }
        }
        curl_close($ch);
        SetValue($SID_ID, (string)$SID);
    }

#----------------------------------------------------------------
#		Daten holen
#----------------------------------------------------------------

    $ch = curl_init($fritzbox_ip.':49000/tamcalllist.lua');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        
    curl_setopt($ch, CURLOPT_POSTFIELDS, "sid=$SID&tamindex=0"); 
    $daten = curl_exec($ch);
    curl_close($ch);

#----------------------------------------------------------------
#		SID noch gültig?
#----------------------------------------------------------------

	if ($daten == ""){
		SetValue($SID_ID, "");
		IPS_RunScript($_IPS['SELF']);
		return;
	}

#----------------------------------------------------------------
#		Daten auswerten
#----------------------------------------------------------------

	$anrufe = simplexml_load_string($daten)->Message;
    foreach($anrufe as $anruf){
        $date = DateTime::createFromFormat('d.m.y H:i', $anruf->Date)->getTimestamp();
        if($date - $last_EX < 0)continue;
        $title   = "Nachricht von ".$anruf->Name;
        if($anruf->Name == "")$title .="?";
        $caption = "Telefon-Nr: ".$anruf->Number." - Anrufzeit: ".$anruf->Date;

#----------------------------------------------------------------
#		wav-Datei holen und temporär speichern
#----------------------------------------------------------------

        $ch_wav = curl_init($fritzbox_ip.':49000/'.$anruf->Path);
        curl_setopt($ch_wav, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch_wav, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
        curl_setopt($ch_wav, CURLOPT_RETURNTRANSFER, 1);
            
        curl_setopt($ch_wav, CURLOPT_POSTFIELDS, "sid=$SID"); 
        $wav = curl_exec($ch_wav);
        file_put_contents ($wav_file, $wav);
        curl_close($ch_wav);

#----------------------------------------------------------------
#		Nachricht in Telegram senden
#----------------------------------------------------------------

        foreach($chat_IDs as $chat_ID){
            $message = $url.'/bot'.$bot.'/sendaudio -F chat_id='.$chat_ID.' -F caption="'.$caption.'" -F audio="@'.$wav_file.'" -F title="'.$title.'" -F parse_mode="HTML"';
            exec("curl ".$message);
        }

#----------------------------------------------------------------
#		wav-Datei löschen
#----------------------------------------------------------------

        exec('rm '.$wav_file);
    }

?>

Das ganze in ein Skriptfile kopieren. Einen Skripttimer auf eine Minute einstellen und eine Stringvariable für die SID anlegen.

Einen Telegram-BOT anzulegen ist sehr einfach. Dazu gibt es reichlich Video-Tutorials (auch auf deutsch) im Netz.

Nach Anlegen des BOTs einfach die BOT-ID hier reinkopieren. Dann dem BOT eine Nachricht senden und die Chat-ID hier ebenfalls anpassen…

…und fertig.

Viel Spaß damit
Jürgen

Hi!

Cooles progrämmchen, läuft bei mir leider nicht :-/

Fehlen da Funktionen? Bei mir spuckt er entsprechende Fehler:

PHP Fatal error: Uncaught Error: Call to undefined function GetValue() in /var/www/html/fritz/f3.php:19

usw…

Ist die SID nicht dynamisch erzeugt? Warum ist die hardcoded?

LG,

Thomas

Fehlt dir eventuell IP-Symcon?

Die Scripte hier im Forum funktionieren normalerweise nicht in anderen Umgebungen.

Ah Danke für den Hinweis, dann muss ich wohl etwas basteln :slight_smile:

LG,

Thomas

Hallo Jürgen,

geniales Script!

Kann es sein, dass die erstellte „WAV-Datei“ jedes mal um die Nachricht erweitert wird?

Beste Grüße
Kai

Edit:
Scheint an Telegram zu liegen.
Es werden anscheinend alle vorhandenen Nachrichten abgespielt.

genauso ist es. Lässt sich aber umgehen, indem man alle alten Nachrichten vom Bot auf dem Handy löscht.
Viele Grüße
Jürgen

Hallo Jürgen,

prima Teil, hat auf Anhieb super geklappt.

eine kleines Problem hab ich noch. Ich habe zwei Anrufbeantworter in der FB eingerichtet (geht ja bis zu 5 Stück). Wenn eine Sprachnachricht an den zweiten geht, kriege ich kein telegram. Was müsste ich da umstellen?

Gruß

Oliver

Du musst nur die Zeile

    curl_setopt($ch, CURLOPT_POSTFIELDS, "sid=$SID&tamindex=0"); 

umstellen auf

    curl_setopt($ch, CURLOPT_POSTFIELDS, "sid=$SID&tamindex=1"); 

Dann bekommst Du die Nachrichten vom 2. Anrufbeantworter. Wenn Du dann beide abfragen willst, musst Du nur eine Schleife über beide Abfragen programmieren. Alternativ kannst Du auch 2 Skripte laufen lassen. Je eines pro Anrufbeantworter. Ist dann nur nicht ganz so elegant…

Viele Grüße
Jürgen

super, danke,

Gruß

Oliver

doppelt…

Hallo,

bekomme im Skript den Fehler:
Notice: Trying to get property ‚SID‘ of non-object in /var/lib/symcon/scripts/50330.ips.php on line 52

Notice: Trying to get property ‚SID‘ of non-object in /var/lib/symcon/scripts/50330.ips.php on line 53

In den Zeilen 52 und 53 gibt es in meinem Skript kein „SID“. Da musst Du etwas modifiziert haben…

Hallo,

hab oben noch etwas Doku :slight_smile:
sind die Zeilen 49 und 50 in deinem originalskript

Ergänze bei den Basisdaten den User

#----------------------------------------------------------------
#		Basis-Daten
#----------------------------------------------------------------

	$fritzbox_ip = 'fritz.box'; # muss ggf. angepasst werden
	$user        = 'Fritzbox-User'; # muss angepasst werden
	$password    = 'ganzGeheim'; # muss angepasst werden

und ersetzte den Bereich

#----------------------------------------------------------------
#		In FritzBox einloggen und Daten holen
#----------------------------------------------------------------
.
.
.
#----------------------------------------------------------------
#		Daten holen
#----------------------------------------------------------------

durch

#----------------------------------------------------------------
#		In FritzBox einloggen und Daten holen
#----------------------------------------------------------------

   $client = new SoapClient(
        null,
        array(
            'location'   => "http://$fritzbox_ip:49000/upnp/control/x_tam",
            'uri'        => "urn:dslforum-org:service:X_AVM-DE_TAM:1",
            'noroot'     => true,
            'login'      => $user,
            'password'   => $password
        )
    );
    $result = $client->GetMessageList(new SoapParam(0, 'NewIndex'));

#----------------------------------------------------------------
#		SID ermitteln
#----------------------------------------------------------------

    $SID = explode("sid=", $result)[1];
    $SID = explode("&", $SID)[0];

#----------------------------------------------------------------
#		Daten holen
#----------------------------------------------------------------

Dann sollte das Einloggen klappen.

Skript läuft durch, kriege aber auf Telegram keine Nachricht / wav Datei

dann probiere das mal:

<?php
#----------------------------------------------------------------
#		Nachrichten auf dem AB aus der Fritzbox auslesen
#		und über Telegramm-Bot versenden
#		von Silberstreifen
#       baut auf VPN-V2.1 auf
#
#----------------------------------------------------------------

#----------------------------------------------------------------
#		Basis-Daten
#----------------------------------------------------------------

    $fritzbox   = 'fritz.box'; # muss ggf. angepasst werden
	$user       = 'Fritzbox-User'; # muss angepasst werden
	$password   = 'ganzGeheim'; # muss angepasst werden

    $url        = 'https://api.telegram.org';
    $bot        = '23123123mmmm234sfodis3o422pop-34';  # muss erzeugt und angepasst werden
    $chat_IDs   = array(
        123456789,                                                                    # muss angepasst werden
        987654321                                                                     # muss angepasst werden
    );
    $wav_file   = '/var/lib/symcon/webfront/user/rec.wav';

#----------------------------------------------------------------
#		Doppelausführung verhindern
#----------------------------------------------------------------

    $Thread = 0;
    foreach (IPS_GetScriptThreadList () as $lfdNr => $Nr) {
        if (IPS_GetScriptThread ($Nr)['ScriptID']==$_IPS['SELF'])$Thread++; 
    }  
    if($Thread>2) return;

#----------------------------------------------------------------
#		Anrufbeantworterliste abrufen und auswerten
#----------------------------------------------------------------

    $client = new SoapClient(
        null,
        array(
            'location'   => "http://$fritzbox:49000/upnp/control/x_tam",
            'uri'        => "urn:dslforum-org:service:X_AVM-DE_TAM:1",
            'noroot'     => true,
            'login'      => $user,
            'password'   => $password
        )
    );
    $result = $client->GetMessageList(new SoapParam(0, 'NewIndex'));

#----------------------------------------------------------------
#		SID ermitteln
#----------------------------------------------------------------

    $SID = explode("sid=", $result)[1];
    $SID = explode("&", $SID)[0];

#----------------------------------------------------------------
#		Daten holen
#----------------------------------------------------------------

	$anrufe = @simplexml_load_file($result)->Message;

#----------------------------------------------------------------
#		Daten auswerten
#----------------------------------------------------------------

    foreach($anrufe as $anruf){
        if($anruf->New == 0)continue;
        $title   = "Nachricht von ".$anruf->Name;
        if($anruf->Name == "")$title .=$anruf->Number;
        $caption = "Telefon-Nr: ".$anruf->Number." - Anrufzeit: ".$anruf->Date;

#----------------------------------------------------------------
#		Nachricht als gehört markieren
#----------------------------------------------------------------

        $result = $client->MarkMessage(new SoapParam((int)$anruf->Tam, 'NewIndex'), new SoapParam((int)$anruf->Index, 'NewMessageIndex'), new SoapParam(1, 'NewMarkedAsRead'));

#----------------------------------------------------------------
#		wav-Datei holen und temporär speichern
#----------------------------------------------------------------

        $ch_wav = curl_init($fritzbox.':49000/'.$anruf->Path);
        curl_setopt($ch_wav, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch_wav, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
        curl_setopt($ch_wav, CURLOPT_RETURNTRANSFER, 1);
            
        curl_setopt($ch_wav, CURLOPT_POSTFIELDS, "sid=$SID"); 

        $wav = curl_exec($ch_wav);
        file_put_contents ($wav_file, $wav);
        curl_close($ch_wav);

#----------------------------------------------------------------
#		Nachricht in Telegram senden
#----------------------------------------------------------------

        foreach($chat_IDs as $chat_ID){
            $website="https://api.telegram.org/bot".$bot;
            $params=[
                'chat_id'=>$chat_ID,
                'caption'=>$caption,
                'audio'=>new CURLFile($wav_file),
                'title'=>$title,
                'parse_mode'=>'HTML'
            ];
            $ch = curl_init($website . '/sendAudio');
            curl_setopt($ch, CURLOPT_HEADER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, ($params));
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            $result = curl_exec($ch);
            curl_close($ch); 
 
        }

#----------------------------------------------------------------
#		wav-Datei löschen und neues Datum speichern
#----------------------------------------------------------------

        exec('rm '.$wav_file);

    }

hat leider keinen Unterschied gemacht

Dann füge mal nach

echo $SID.chr(10);

ein. Was ist das Ergebnis?

Und dann nach

	$anrufe = @simplexml_load_file($result)->Message;

folgendes

    print_r(simplexml_load_file($result));
    return;

Was kommt dabei heraus?

b5d9c9e53e310053

und

SimpleXMLElement Object
(
    [comment] => Array
        (
            [0] => SimpleXMLElement Object
                (
                )

            [1] => SimpleXMLElement Object
                (
                )

            [2] => SimpleXMLElement Object
                (
                )

        )

    [Message] => Array
        (
            [0] => SimpleXMLElement Object
                (
                    [Index] => 1
                    [Tam] => 0
                    [Called] => 7382529
                    [Date] => 15.09.21 13:11
                    [Duration] => 0:01
                    [Inbook] => 1
                    [Name] => Oliver mobil
                    [New] => 0
                    [Number] => 01723229382
                    [Path] => /download.lua?path=/var/media/ftp/CRUZER_16GB/FRITZ/voicebox/rec/rec.0.001
                )

            [1] => SimpleXMLElement Object
                (
                    [Index] => 0
                    [Tam] => 0
                    [Called] => 7382529
                    [Date] => 14.09.21 10:47
                    [Duration] => 0:01
                    [Inbook] => 1
                    [Name] => Oliver mobil
                    [New] => 0
                    [Number] => 01723229382
                    [Path] => /download.lua?path=/var/media/ftp/CRUZER_16GB/FRITZ/voicebox/rec/rec.0.000
                )

        )

)

Dann ist doch alles gut. Du hast gar keine neuen Nachrichten auf dem AB. Dann soll auch keine Nachricht kommen….