NEWS
[Anleitung]Sipgate Anrufe über ioBroker-Cloud anzeigen lassen
-
Hallo zusammen,
ich stelle hier meine Lösung vor, mit dem SIP Anbieter Sipgate alle eingehenden und ausgehenden Anrufe über dessen API und den iobroker-Cloud-Adapter anzeigen zu lassen.
Sipgate bietet einen kostenlosen SIP-Telefon-Anschluss. Ebenso kostenlos ist der Zusatzdienst, https://www.sipgatebasic.de/feature-store/sipgate.io-s. Neben einer umfangreicher Server-Lösung (Server läuft beim Teilnehmer, Software wird in verschiedenen Programmiersprachen angeboten - auch nodejs, viele Dienste wie Weiterleitungen, Mailbox, etc möglich, https://developer.sipgate.io/v2.0/reference#dial) gibt es eine sehr einfache Variante der Benachrichtigung: Webhooks mit POST-Request. Dazu wird im Sipgate Einstellungsmenü einfach unter sipgate.io jeweils für ein- und ausgehende Anrufe ein URL eingetragen, an den die Information zum Ereignis geschickt werden sollen. Für uns bietet sich da als Empfänger natürlich der Cloud-Adapter an, denn über den ist ioBroker aus dem Internet geschützt erreichbar.
Damit der Cloud Adapter mit dem ankommenden Request etwas anfangen kann, muss er zu erst konfiguriert werden. https://github.com/ioBroker/ioBroker.cloud#services.
Ich setze einen vorhandenen Cloud-Zugang voraus.
Cloud-Adapter
-
Adapter Einstellungen öffnen und Reiter Services öffnen
-
jeweils für ein- und ausgehende Anrufe einen Datenpunkt erstellen, der von sipgate später befüllt wird.
Ich schlage vor sipgate.out und sipgate.in. Wenn du andere Namen verwendest, passe unbedingt später das Skript an.
-
kopiere den "Link für den eigenen Service" bis auf die letzten sieben Zeichen "/<data>" in die Zwischenablage
https://iobroker.pro/service/custom_<name>/@pro_email@email.com_123456-1243-1234-1234-123456789012</name> ````</data>
-
Speichere und schließe das Einstellungsfenster
-
Im Reiter Objekte findest nun die Datenpunkte cloud.0.services.custom_sipgate.in und cloud.0.services.custom_sipgate.out
Hinweis für Entwickler Bluefox
An dieser Stelle wünschte ich mir statt des Unterstrichs einen Punkt als Trennung, also statt custom_sipgate.in lieber custom.sipgate.out. Für die Ordnerstruktur
Nun öffne Sipgate.de
Sipgate
-
Sipgate Konto erstellen (Basic reicht) oder einloggen
-
im Feature Store auf sipgate.io S klicken und aktivieren
-
wechsele zu "mein basic" und scrolle nach unten zu sipgate.io
-
öffne jeweils die Einstellungen für ein- und ausgehende Anrufe
-
füge den "Link für den eigenen Service" aus den ioBroker Cloud-Adapter Einstellungen/Services (sollte noch in der Zwischenablage sein) in das Feld ein und passe ihn an. * ersetze __<name></name>__durch sipgate.in
-
speichere und führe das gleiche analog für ausgehende Anrufe aus.
Das war's! Wenn du nun mit dem Konto einen Anruf tätigst oder einen Anruf erhältst, wird ein POST Request auf das jeweilige Objekt geschickt. Und das passiert meistens schon, bevor das Telefon überhaupt klingelt.
–------------------------------------------
Jetzt muss das Objekt noch ausgewertet werden. Denn ich will ja wissen, wer anruft.
Dazu lege ich im Javascript Adapter folgendes Skript an:
Das Skript braucht keine Login-Daten. Es wertet nur den String aus den Cloud-Datenpunkten aus. Dabei verarbeitet es nur die Nummer des Anrufers und des Angerufenen. Andere Daten werden nur in den lokalen Variablen zwischengespeichert.
Und natürlich ist das Telefonbuch hier anonymisiert. Also bitte anpassen.
Ich habe es nicht getestet, aber evtl. werden die Anrufer Namen übertragen, wenn sie im Sipgate-Telefonbuch auf der Webseite hinterlegt sind.
Ich empfehle, wie immer bei neuen Skripts, eine Test-Instanz des Javascript-Adapters zu nutzen.
Es werden Datenpunkte angelegt (bei mir unter Instanz javascript.2):
/* Sipgate Post Skript überwacht cloud.0 custom_sipgate Datenpunkte auf Änderung Sipgate API schreibt via cloud-Adapter bei Aktionen (anrufe, etc.) Nur Anrufe todo: Übersetzungen? Sipgate Telefonbuch checken 12.01.2018 erstellt von pix 13.01.2018 Datenpunkt Time zugefügt */ const fC = false; const logging = true; const path = "javascript." + instance + ".Sipgate."; const unknown = 'Rufnummer nicht im Telefonbuch'; const phonebook = { "4930555568": {"name": "Anton", // name zur Rufnummer "bemerkung": "zu Hause" }, // optional "491515555533": {"name": "Bernhard", "bemerkung": "mobil" }, "491715552255": {"name": "Carsten", "bemerkung": "mobil"}, "496955562222": {"name": "Dirk", "bemerkung": "zu Hause"}, "491715552525": {"name": "Emil", "bemerkung": "mobil"}, "4921155521": {"name": "Franz", "bemerkung": "zu Hause" }, "4917655542555": {"name": "Gustav", "bemerkung": "mobil" }, "496955522211": {"name": "Hannah", "bemerkung": "zu Hause"}, "491735558888": {"name": "Ingrid", "bemerkung": "mobil"}, "491725557777": {"name": "Jan", "bemerkung": "mobil"} }; function checkPhonebook (number) { var name = ""; var note = ""; if (!phonebook[number]) { name = unknown; note = "---"; // no device } else { name = phonebook[number].name; note = phonebook[number].bemerkung; } return { 'name' : name, 'note' : note }; } // Auswertung Anrufe // States erstellen // Objekt const idObj = path + "call.object"; createState(idObj, " ", fC, { name: "Sipgate Anrufdaten als Objekt", type: "string", role: "json" }); function createStates (dir) { var text = (dir == "in") ? "eingehender" : "ausgehender"; // Deutsche Beschreibung createState(path + "call." + dir + "bound.from.number", " ", fC, { name: "Sipgate " + text + " Anruf von Nummer", type: "string" }); createState(path + "call." + dir + "bound.from.name", " ", fC, { name: "Sipgate " + text + " Anruf von Teilnehmer", type: "string" }); createState(path + "call." + dir + "bound.to.number", " ", fC, { name: "Sipgate " + text + " Anruf an Nummer", type: "string" }); createState(path + "call." + dir + "bound.to.name", " ", fC, { name: "Sipgate " + text + " Anruf an Teilnehmer", type: "string" }); createState(path + "call." + dir + "bound.time", " ", fC, { name: "Sipgate " + text + " Anruf Zeit", type: "string" }); } // initial createStates("in"); createStates("out"); // Cloud-Datenpunkte überwachen on({ id: /cloud\.0\.services\.custom_sipgate\.*/, change: 'ne' // sollte mann ggf. noch ändern, falls mehrere Anruf vom gleichen Anschluss kommen }, function(obj) { var obj_post = obj.state.val; var obj_post_arr = obj_post.split("&"); // Post aufteilen bei Ampersand var obj_event = (obj_post_arr[0].split("="))[1]; // einzelne Werte separiert speichern var obj_direction = (obj_post_arr[1].split("="))[1]; // in oder out var obj_from = (obj_post_arr[2].split("="))[1]; // ggf. Telefonbuch abgleichen var obj_to = (obj_post_arr[3].split("="))[1]; // ggf. Telefonbuch abgleichen var obj_callId = (obj_post_arr[4].split("="))[1]; // wird nicht weiter genutzt var obj_user = (obj_post_arr[5].split("="))[1]; // wird nicht weiter genutzt // Erkennung, ob eingehend oder ausgehend (abhängig vom Cloud-Datenpunkt) var objpath = (obj.id).split('.'); var dir = objpath[objpath.length-1]; if (logging) log(dir); // States erstellen (zur Sicherheit) createStates(dir); // Objekt schreiben (zB für VIS Json Viewer Widget var webhook = { "post": [ { "event": obj_event, "direction": obj_direction, "from": obj_from, "to": obj_to, "callId": obj_callId, "user": obj_user } ] // Ende Post }; setState(idObj, JSON.stringify(webhook)); // Objekt schreiben var t = new Date(); setState(path + "call." + dir + "bound.time", formatDate(t, "TT.MM.JJJJ SS:mm:ss")); setState(path + "call." + dir + "bound.from.number", "+" + obj_from); if (logging) log("Test: " + "+" + obj_from); setState(path + "call." + dir + "bound.from.name", checkPhonebook(obj_from).name + " (" + checkPhonebook(obj_from).note + ")"); if (logging) log("Test: " + checkPhonebook(obj_from).name + " (" + checkPhonebook(obj_from).note + ")"); setState(path + "call." + dir + "bound.to.number", "+" + obj_to); if (logging) log("Test: " + "+" + obj_to); setState(path + "call." + dir + "bound.to.name", checkPhonebook(obj_to).name + " (" + checkPhonebook(obj_to).note + ")"); if (logging) log("Test: " + checkPhonebook(obj_to).name + " (" + checkPhonebook(obj_to).note + ")"); // Logging if (dir == "out") { log("Ausgehender Anruf von " + checkPhonebook(obj_from).name + " (" + checkPhonebook(obj_from).note + ")"); } else if (dir == "in") { log("Eingehender Anruf von " + checkPhonebook(obj_from).name + " (" + checkPhonebook(obj_from).note + ")") } if (logging) log('RegEx ### ' + webhook.post[0].event + ' ' + webhook.post[0].direction + ': +' + webhook.post[0].from + ' -> +' + webhook.post[0].to); });
Auch die erzeugten Datenpunkte kann man natürlich beobachten und zB per telegram weiterleiten, VIS nutzen oder ähnliches. Für solche Verwendung würde ich immer ein weiteres Skript nutzen.
Da ich zu Hause keine Festnetzleitung verwende, kann ich auf diese Weise Anrufe auch ohne die Fritzbox (meine DECT-Basis) erkennen, direkt beim Anbieter. So kann man natürlich auch "inaktive" Sip-Konten überwachen (Ferienhaus, etc.). Ich habe noch einen alten Account mit anderer Ortsvorwahl aus meiner Zeit im Rheinland. So kann ich nun prüfen, ob dort angerufen wurde, obwohl ich kein Endgerät mit der Nummer betreibe.
Daraus ergeben sich natürlich auch wieder neue Anwendungen. So könnte man ohne Internet und nur per Anruf eine Aktion auslösen (abhängig von der Anrufernummer).
Detailliertere Information, wie Anrufdauer, Besetztzeichen etc. sind wohl nur über die umfangreiche Servervariante verfügbar.
Bevor jemand nach einem Adapter ruft :lol: : Für einen Adapter muss man auch den Cloud-Zugang haben, die Daten aus dem Cloud-Zugang auf sipgate.de eintragen und die Daten in VIS o.ä. auswerten. Wer das kann, der kann auch mein Skript verwenden und braucht keinen Adapter 8-) .
Ein Adapter sollte dann schon die Servervariante mitbringen (eigener Webserver). Soweit bin ich noch nicht :roll:
Viel Spass beim Testen!
Gruß
Pix
-