1. Chrome to Cisco Phone Add-On

In diesem Beitrag Chrome to Cisco Phone möchte ich zeigen, wie ich mir eine Erweiterung (Add-on) für den Chrome Browser erstellt habe, um eine markierte Telefonnummer von einer Webseite an mein Cisco IP Telefon zu senden.

Ich nehme es vorweg, dass es solche Add-Ons schon gibt. Das ist aber nicht der Anspruch dieses Artikels, über etwas vollkommen Neues zu berichten. Vielmehr möchte ich den Programmcode meiner Erweiterung öffentlich zugänglich machen, welche Schritte für ein solches Add-On notwendig sind. Es ist natürlich auch möglich, die Erweiterung, das Add-On noch weiter auszubauen. Icons hinzuzufügen, die Optionen einstellbar zu machen oder spezielle Validierungen durchzuführen, die die Telefonnummer weiter prüfen.

Prinzip Chrome to Cisco Phone

Ich möchte mit dieser Erweiterung erreichen, dass ich eine Telefonnummer auf einer beliebigen Internetseite markieren kann und über einen Button im Kontextmenü diese Telefonnummer dann direkt an mein Cisco IP Telefon übertragen kann. Dort wird die Nummer direkt gewählt. Dazu möchte ich eine Browser-Erweiterung erstellen, die eine XML-Datei generiert. Diese XML-Datei sende ich dann direkt an das Telefon.

Send to Cisco Phone
Auszug Kontextmenü Chrone to Cisco IP Phone

Beginnen wir mit der Erweiterung (Add-on), die wir für den Browser benötigen. Ich habe in einem Ordner zwei Dokumente angelegt:

  • manifest.json
  • sentNumberToCisco.js

Chrome Add-On manifest.json

In der manifest.json Datei werden die Add-on benötigten Einstellungen, Deklarationen, Berechtigungen sowie Name und Beschreibung eingetragen. Ich habe mich hierbei an die von Chrome veröffentlichte Vorgabe Manifest File Format gehalten.

Hier der Auszug aus meiner „manifest.json“ Datei :

{
	"name": "Send Number to Cisco IP Phone",
	"version": "0.1",
	"description": "Mark a phone number on a website and press the button in context menü.",
	"author": "ChrisBue Blog",
	"permissions": [ 
		"contextMenus",
		"http://*/*" ],
	"background": {
		"persistent": false,
		"scripts": ["sendNumberToCisco.js"]
	},
	"manifest_version": 2	
}

Anmerkungen:

„permissions“: Ich benötige die „contextMenus“ Berechtigung, um einen Button dem Kontextmenü hinzuzufügen. Die „http://*/*“ Berechtigung ermöglicht mir das Senden der XML-Datei an das Telefon. Ohne diese Berechtigung kann keine Übertragung nach außen erfolgen. Die „storage“ Berechtigung ist optional. Ich verwende den Browserspeicher „storage“ um meine Optionen abzulegen.

„background“: Hier lege ich fest, welches Script ich ausführen möchte. In diesem Fall verwende ich das „sendNumberToCisco.js“ Skript. Darin werde ich die notwendigen Funktionen unterbringen, um die Nummer direkt zu senden und den Button im Kontextmenü zu verankern.

Browser Erweiterung sendNumberToCisco.js

In der Javascript-Datei „sendNumberToCisco.js“ für das Chrome to Cisco IP Phone Projekt werden alle Funktionen erstellt, die den zusätzlichen Eintrag im Kontextmenü erzeugen, die XML-Datei mit der Telefonnummer erstellen und die Verbindung zum Telefon herstellen. Als Erstes erstellen wir den Button im Kontextmenü.

chrome.runtime.onInstalled.addListener(function() {
	// Create an item for a selected text in the menu
	var id = chrome.contextMenus.create({"title": "Send to Cisco IP Phone", "contexts":["selection"], "id": "numberToCiscoPhoneSelection"});
});

Anmerkungen:

Ich erstelle einen Listener, der dem Kontextmenü einen Eintrag mit dem Namen „Send to Cisco IP Phone“ hinzufügt. Die Option „contexts“: [„section“] ermöglicht es mir, dass der Eintrag im Kontextmenü nur angezeigt wird, wenn auch tatsächlich etwas markiert ist. Natürlich bekommt der Button auch eine „id“: „numberToCiscoPhoneSelection“.

Jetzt erstelle ich einen weiteren Listener, der auf den Klick im Kontextmenü reagiert und die entsprechenden Funktionen ausführt, die es ermöglichen, die Daten an das Telefon zu senden. Vorher validiere ich noch notdürftig die Telefonnummer. Dies lässt sich bestimmt noch weiter ausbauen, genügt aber für meine Zwecke.

// The onClicked callback function.
function onClickHandler(info, tab) {

	// Check if the correct button is clicked
	if(info.menuItemId == "numberToCiscoPhoneSelection"){

		var ip = "000.000.000.000";
		var uid = "XXXX";
		var pwd = "XXXX";
	
		if(info.selectionText == undefined){
			alert("nothing marked!");
			exit;
		} 

		// Replace '+' to '00'
		var number = info.selectionText.replace('+', '00')
		// Only numbers
		number = number.replace(/\D+/g,"");

		// Check if there is a number to call
		if(number == ""){
			alert("nothing marked!");
			exit;
		}

		// Build XML
		var xml = '<?xml version="1.0"? encoding="UTF-8">\r\n' +
		'<CiscoIPPhoneExecute>' +
		'<ExecuteItem Priority="0" URL="Dial:' + number + ':1:Cisco/Dialer"/>\r\n'+
		'</CiscoIPPhoneExecute>\r\n';

		// XML request
		var xhttp = new XMLHttpRequest();
		xhttp.open("POST", "http://"+ip+"/CGI/Execute", true);
		xhttp.setRequestHeader ("Authorization", "Basic " + btoa(uid + ":" + pwd));
		xhttp.setRequestHeader ("Content-type", "application/x-www-form-urlencoded");
		xhttp.onreadystatechange = function(){

			// Log response from phone for connection debug
			console.log( this.responseText );
		}
		xhttp.send("XML="+xml);		
	}
};

chrome.contextMenus.onClicked.addListener(onClickHandler);

Anmerkungen:

Ich erstelle einen „chrome.contextMenus.onClicked.addListener“ der den „onClickHandler“ aufruft. Ich prüfe ab, ob das geklickte Objekt die selbe ID hat wie der Eintrag, den ich dem Kontextmenü hinzugefügt habe („numberToCiscoPhoneSelection“).

Die Variablen „ip“, „uid“ und „pwd“ sollten hier nicht hart codiert eingetragen werden. Es gibt eine schönere Möglichkeit diese Daten z. B. im Speicher des Browsers abzulegen.

In den nächsten Schritten prüfe ich, ob auch Daten an die Funktion übergeben wurde. Ich ändere das „+“ in „00“ um, da oft „+49“ in den Telefonnummern angegeben ist. Danach entferne ich alles, was keine Zahl ist aus der Telefonnummer, z. B. – / oder Leerzeichen.

Jetzt das Wichtigste. Ich erstelle die XML-Datei, die ich übertragen möchte. Ich habe den genauen Aufbau der XML-Datei der Cisco-Dokumentation entnommen.
Ich erstelle nun ein Objekt um XML Daten zu senden „new XMLHttpRequest();“, füge die Zieladresse ein „http://“+ip+“/CGI/Execute“ und melde mich am Telefon an „Authorization“, „Basic “ + btoa(uid + „:“ + pwd)“.

Zum Schluss kann ich die Daten senden „xhttp.send(„XML=“+xml);“. Als Hilfe lasse ich mir die Antwort des Telefons in der Debug-Konsole des Browsers anzeigen.

Um nun die Erweiterung (Add-on) im Browser zu laden, muss ich zuerst in den Einstellungen die Erweiterungen aufrufen. Hier den Haken für den „Entwicklermodus“ setzten und über den Dialog hinter „Entpackte Erweiterung laden …“ den Ordner mit den zwei Dateien auswählen.

Chrome-Addon
Browser Erweiterung