AVM-Fritzbox meldet Anrufe über Alexa

Alexa macht’s möglich: Sprachunterstützung bei der Telefonie mit der Fritzbox

Update am Dienstag, 30. April 2019

Gesperrte Rufnummern nicht ansagen

In der Fritzbox können Anrufer auf drei Arten gesperrt werden:

  1. Sperre der Anrufer, die keine Rufnummer mitteilen
  2. Sperre aller Anrufer, die in einem anzugebenden Fritzbox-Telefonbuch gelistet sind
  3. Sperre der Anrufer, deren Rufnummer mit einer der angegebenen Zifferfolgen beginnt

Fall 1: Sperre der Anrufer, die keine Rufnummer mitteilen

Die Rufnummer ist im Feld caller. Wenn also die Anrufernummer fehlt, können wir die Anrufe filtern mit:

        var caller = jsonObj.caller;
if (caller === "") {
return;
}

Fall 2: Sperre aller Anrufer, die in einem anzugebenden Fritzbox-Telefonbuch gelistet sind

Hier würde ich pragmatisch vorgehen und eine Kennung am Namen anbringen, zum Beispiel: ein Sternchen * vor dem Namen. Die Anrufernamen lassen sich nun leicht herausfiltern.

        if (callerName.startsWith("*")) {
return;
}

Fall 3: Sperre der Anrufer, deren Rufnummer mit einer der angegebenen Zifferfolgen beginnt

Hier muss eine Liste bei jedem Anruf durchsucht werden. Wenn es viele gesperrte Rufnummern gibt, sollte man erwägen, wie in Fall 2 ein spezielles Telefonbuch zu verwenden (oder ein besseres Verfahren zum Durchsuchen der Liste).

Die Sperrliste befindet sich im Objekt tr-064.0.callForwarding. Die einzelnen Elemente sind einfach durchnummeriert: tr-064.0.callForwarding.0, tr-064.0.callForwarding.1, tr-064.0.callForwarding.2 und so weiter.

In der Sperrliste beginnen die Rufnummernbereiche mit „fromNumber„.

Vorschlag für eine Funktion zum Feststellen, ob die Rufnummer gesperrt ist oder nicht:

function isInBlacklist(caller) {
var obj;
var i = 0;
do {
obj = getObject('tr-064.0.callForwarding.' + i++);
if (obj != null) {
var arr = obj.common.name.split(" ");
if (arr[0] == "fromNumber") {
if (caller.startsWith(arr[1])) {
return true; // ist gesperrt
}
}
}
}
while (obj != null)
return false; // nicht gesperrt
}

Nun können auch die Rufnummern der Blacklist herausgefiltert werden:

        var caller = jsonObj.caller;
if (isInBlacklist(caller)) {
return;
}

Hinweis: Der ioBroker-Adapter tr-064 aktualisiert nach einer Löschung oder Änderung einer gesperrten Rufnummer in der Fritzbox die Einträge im Objekt tr-064.0.callForwarding nicht immer korrekt. Am besten ist es, das Objekt zu löschen und die Liste durch einen Neustart der Instanz komplett neu generieren zu lassen.

Ergebnis

Jetzt brauchen nur noch die jeweils gewünschten Sperren in die eigene Subkriptions-Funktion eingesetzt zu werden. Bei mir sieht es etwa so aus:

/************* Anruf ansagen ***************/
var callerName = "";
var counter = 0;

on({id: 'tr-064.0.callmonitor.inbound.json'/*json*/, change : "any"}, function(obj) {
var jsonObj = JSON.parse(obj.state.val);
if (jsonObj.callee.endsWith("9876543")) {
var callerName = jsonObj.callerName;
var caller = jsonObj.caller;

//Anrufer teilt keine Rufnummer mit
//if (caller === "") {
// return;
//}

// Rufnummer aus Sperr-Telefonbuch
if (callerName.startsWith("*")) {
return;
}

// Rufnummer aus Liste gesperrter Nummern
if (isInBlacklist(caller)) {
return;
}

//Anrufer nicht in meinem Telefonbuch, Rufnummer ist gesperrt
//if (callerName === "") {
// return;
//}

//Anrufer nicht in meinem Telefonbuch, Ansage der Rufnummer
if (callerName === "") {
callerName = caller;
}

anruferAnsagen() ;
}
});

function anruferAnsagen() {
if (getState('tr-064.0.callmonitor.ringing'/*ringing*/).val && counter++ < 3) {
setState(
"alexa2.0.Echo-Devices.<alexaId>.Commands.speak",
"Anruf von " + callerName
);
setTimeout(anruferAnsagen, 4000);
}
}

function isInBlacklist(caller) {
var obj;
var i = 0;
do {
obj = getObject('tr-064.0.callForwarding'/*Call forwarding*/ + "." + i++);
if (obj != null) {
var arr = obj.common.name.split(" ");
if (arr[0] == "fromNumber" && arr[2] == "->") {
if (caller.startsWith(arr[1])) {
return true;
}
}
}
}
while (obj != null)
return false;
}

Autor: Rai

jahrelanger Homematic-Benutzer, öffnet sich mit Hilfe von Raspberry Pi und ioBroker für Neues im Internet of Things

14 Gedanken zu „AVM-Fritzbox meldet Anrufe über Alexa“

  1. Hallo, vielen Dank für das tolle Skript und vor allem für die Ausfühliche Erläuterung. Leider erhalte ich im Log folgende Fehlermeldung und es kommt nicht zu einer Sprachausgabe beim ausgewählten Echo-Gerät. Ich habe im Skript die ID des Gerätes anepasst.
    [39m: javascript.0 (18793) script.js.common.Alexa.Ausgabe_von_Name_wenn_Anruf_auf_Festnetz: setForeignState(id=alexa2.0.Echo-Devices.XXXX.Commands.speak, state=“Anruf von XXX XXXX“) – wurde nicht ausgeführt, während der Debug-Modus aktiv ist

    Woran kann das liegen?

  2. Script No.1 läuft auf Anhieb, aber Script No. 2 und No. 3 wird die Variable CallerName nicht mehr modifiziert, sodass die Ausgabe auf der Alexa lediglich als „Anruf von“ ertönt . Ich suche mir einen Wolf, aber finde den Fehler nicht. Bitte um Hilfe.

  3. Hallo,
    damit Alexa wieder den Anrufernamen ansagt, musste ich bei dem Script auf der zweite Seite folgendes ändern.

    Alt: var callerName = jsonObj.callerName;
    Neu: callerName = jsonObj.callerName;

    Wenn man möchte das bei übetragener, aber unbekannter Nummer, die Nummer angesagt wird.
    Kann man noch folgende Änderung durchführen.

    if (callerName === „“) {
    callerName = jsonObj.caller;
    }

    Danke für den tollen Artikel hat prima funktioniert.

    Gruß Sven

  4. Ich habe es auch ausprobiert und es ist easy in das System einzupflegen – vielen Dank dafür.

    Was cool wäre, wenn es Zeitgesteuert wäre, oder die Ansage nur kommt, wenn jemand zuhause wäre, oder die Ansage nur bei bestimmten Anrufern kommt, also nicht bei jedem Anruf.

  5. Hallo,
    ich habe das Programm etwas auf meine Ansprüche angepasst. Vielleicht hilft es dem einem oder anderem weiter. hier mein Code:
    (Bereiche mit ********* müssen mit den eigenen Werten ersetzt werden.)

    /* Anruf ansagen */
    var callerName = „“;
    var caller = „“;
    var counter = 0;

    on({id: ‚tr-064.0.callmonitor.inbound.json’/*json*/, change : „any“}, function(obj) {
    var jsonObj = JSON.parse(obj.state.val);
    if (jsonObj.callee.endsWith(„*******“)) { //nur Anrufe, die Aufdiese nummer eingehen werden angesagt
    callerName = jsonObj.callerName;
    if (callerName === „“) { //Hat ein Anrufer keinen „Namen“, dann ist er nicht im Telefonbuch
    callerName = „unbekannter Nummer“; //also wird der Name mit „unbekannter Nummer“ ersetzt
    }
    caller = jsonObj.caller; //Telefonnumer laden
    counter = 0; //counter vorm Aufruf der Funktion auf 0 setzen, damit der counter nicht „überläuft“
    setState( „alexa2.0.Echo-Devices..*****************..Commands.speak-volume“, 50 ); //Lautstärke von Alexa auf 5 setzen
    anruferAnsagen() ; //Aufruf der Funktion
    }
    });

    function anruferAnsagen() {
    if (getState(‚tr-064.0.callmonitor.ringing’/*ringing*/).val && counter++ < 3) {

    if (caller === "") { //Hat der Anrufer keinen Name, dann ist es ein unterdrückter Anrufer
    setState(
    "alexa2.0.Echo-Devices.*****************.Commands.speak",
    "Unterdrückter Anruf" );
    }
    else{ //Hat der Anrufer einen Namen, so wird dieser vorgelesen
    setState(
    "alexa2.0.Echo-Devices..*****************..Commands.speak",
    "Anruf von " + callerName );
    }

    setTimeout(anruferAnsagen, 6000); //Timeout aufrufen
    }
    }

    1. Hallo Maik, die AlexaID findet du am einfachsten in der ioBroker-Objektansicht der Alexa2-Instanz, wenn du die Liste der Echo-Devices aufgeklappst. Ich habe den Text oben etwas angepassst. Ist dann hoffentlich verständlicher. Grüße Rai

      1. Danke für die schnelle Antwort und das gute Programm. Damit hast du mir echt viel „try and error – Arbeit“ erspart. Danke! 🙂
        Ich musste allerdings noch eine paar Änderungen vornehmen, da es bei mir nicht direkt lief.
        Der Counter für die wiederholte Ansage wird nur bei Skript neustart zurück gesetzt. Wenn ich zwei mal nacheinander mit der selben Nummer angerufen hatte und die drei Ansagen vom Counter durchgelaufen waren, schwieg meine Alexa beim nächsten Anruf. Hierfür habe ich den Counter vorm Funktionsaufruf zurückgesetzt.
        Zudem kam mein ioBroker mit dem zweiten mal „var“ vor der Variable „callerName“ nicht zurecht. Das habe ich raus genommen.

        Als kleine Erweiterung habe ich die Lautstärke des Echos für die Ansage auf 60% festgesetzt. So hört man die Ansage auch wenn zuvor die Lautstärke auf einem kleinem Level eingestellt war.

        Hier der abgeänderte Code:

        /************* Anruf ansagen ***************/
        var callerName = „“;
        var counter = 0;

        on({id: ‚tr-064.0.callmonitor.inbound.json’/*json*/, change : „any“}, function(obj) {
        var jsonObj = JSON.parse(obj.state.val);
        if (jsonObj.callee.endsWith(„9876543“)) {
        callerName = jsonObj.callerName;
        if (callerName === „“) {
        callerName = „Unbekannt“;
        }
        counter = 0;
        setState( „alexa2.0.Echo-Devices.ABCDEFG123456.Commands.speak-volume“, 60 );
        anruferAnsagen() ;
        }
        });

        function anruferAnsagen() {
        if (getState(‚tr-064.0.callmonitor.ringing’/*ringing*/).val && counter++ < 3) {
        setState(
        "alexa2.0.Echo-Devices.ABCDEFG123456.Commands.speak",
        "Anruf von " + callerName
        );
        setTimeout(anruferAnsagen, 6000);
        }
        }

    1. Hallo Sven, schön, dass dir der Artikel gefällt. Wenn du das umgesetzt hast, bitte schreib mal, wie es war, ob Probleme aufgetreten sind usw. Gruß Rai

  6. Hallo, die Idee ist nicht schlecht. Funktioniert wie beschrieben.
    Prob bei mir: In der Fritze gesperrte Anrufer werden auch angesagt. Kann man da was machen???

    1. Danke für den Hinweis. Ich habe den Artikel ergänzt. Jetzt können gesperrte Anrufer herausgefiltert werden. Bin gespannt auf deine Rückmeldung!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.