A trending theme: more work related stuff.

The Problem:

We moved from a real efficient system (3cx) that was always visible, always one click and even auto answered, to another one that was hidden away in a browser tab, required many clicks to answer/hold/mute/etc


The Solution:

I created some extensions for chrome that were always visible, always one away, and even hotkeyed to get back to having a usable workflow.


Features/Benefits:

  • I can be mid email, ALT+A and answer a call without stopping my typing or slowing down at all! or a quick ALT+S+2 to go to busy so I don't need to answer next call if I'm still doing something
  • bindable: anywhere inside chrome use key to answer/hangup, mute, etc
  • always visible, one click away if you don't like hotkeys
  • status icons, that mostly work!
  • adds context menu to quick look up orders, search tracking etc, anywhere from chrome ie from emails, from salesforce
  • does not interfere with anything, just looks for a particular element and clicks it if possible

Answering calls: ignore the class name



class HandleHold {
	constructor() {
		this.onPhone = false;
		this.phoneNumber = null;
		this.omniButton = null;
		this.omniBar = null;
	}

	async handlePhoneCall() {
		this.phoneNumber = null;

		await this.handleOpenMenu();

		this.onPhone = this.answerCall();

		if(!this.onPhone){
			this.endCall();
		}

		await this.handleCloseMenu();
	}

	answerCall() {
		if (this.getOmniBar() != null) {

			let answerButton = this.omniBar.querySelector('[title^="Accept Voice Call"]');

			if (answerButton != null) {
				answerButton.click();
				return true;
			}
		}
		return false;
	}

	endCall() {
		if (this.getOmniBar() == null)
			return;

		let endButton = this.omniBar.querySelector('[title="End Call"]');

		if (endButton != null) {
			endButton.click();
		}
	}

	isOmniOpen() {

		if (this.getOmniBar() != null) {
			if (this.omniBar.classList.contains('MINIMIZED')) {
				return false;
			}
		}

		return true;
	}

	getOmniBar() {

		if (this.omniBar != null)
			return this.omniBar;

		//is closed
		let bar = document.querySelectorAll('.MINIMIZED');
		for (let i = 0; i < bar.length; i++) {
			if (bar[i].textContent.search('Omni-Channel') > -1) {
				this.omniBar = bar[i];
				return bar[i];
			}
		}

		//is open
		bar = document.querySelectorAll('.DOCKED');
		for (let i = 0; i < bar.length; i++) {
			if (bar[i].textContent.search('Omni-Channel') > -1) {
				this.omniBar = bar[i];
				return bar[i];
			}
		}

		//cannot find
		return null;
	}

	getOmniButton() {
		return this.getQuerySelectorByInnerHtml('button', 'Omni-Channel');
	}

	async handleOpenMenu() {
		if (!this.isOmniOpen()) {
			this.toggleOmniPopUp();	//open pop up if we need
			await this.sleep(100);	//rest
		}
	}

	async handleCloseMenu() {
		if (this.isOmniOpen()) {
			this.toggleOmniPopUp();	//open pop up if we need
		}
	}

	toggleOmniPopUp() {

		if (this.omniButton == null) {
			this.omniButton = this.getOmniButton();
		}

		if (this.omniButton != null) {
			this.omniButton.click();
		}
	}

	getQuerySelectorByInnerHtml(type, innerHTML) {
		let types = document.querySelectorAll(type);
		let ret = null;

		//backward loop as most buttons are later in the list
		for (let i = types.length - 1; i >= 0; i--) {
			if (types[i].innerHTML.search(innerHTML) > -1) {
				ret = types[i];
				break;
			}
		}
		return ret;
	}

	getQuerySelectorByInnerText(type, innerText) {
		let types = document.querySelectorAll(type);
		let ret = null;

		//backward loop as most buttons are later in the list
		for (let i = types.length - 1; i >= 0; i--) {
			if (types[i].innerText == innerText) {
				ret = types[i];
				break;
			}
		}
		return ret;
	}

	sleep(ms) {
		return new Promise(resolve => setTimeout(resolve, ms));
	}
}

let answerCall = new HandleHold();

chrome.runtime.onMessage.addListener(
	function (request, sender, sendResponse) {

		if (request.method === 'handlePhoneCall') {
			answerCall.handlePhoneCall();
		}

		sendResponse({ answered: answerCall.onPhone, phone: answerCall.phoneNumber });
	});

	

Context Menus:


const keys = {
	"^1234\\d{5}$":   "https://www.....com/?externalSearchQuery={}",
  "^(\\d[a-zA-Z]{3}|[a-zA-Z]\\d[a-zA-Z]{2})\\d{8}$" : "https://....com/?id={}",
  .........
}

const trackID = chrome.contextMenus.create({
        "id": "trackID",
        "title": "search: " + "%s",
        "contexts": ["selection"]
});

//function genericOnClick(info, tab) {
chrome.contextMenus.onClicked.addListener((info, tab)=>{
    if(info.menuItemId == trackID){
        track(info.selectionText.trim());
    }
});

function track(con){
    for (var key in keys) {
        const found = con.match(new RegExp(key));
        if(found){
                if(key === '^\\+?614\\d{7}|^04\\d{8}$'){
                    const regex = /^\+614|^614/i;
                    con = con.replace(regex, '04');                
                }
                else if(key === '^(\\d{1,2}-[oO0]-\\d{8}|\\d{10,13})$' || key === '^125-[oO0]-\\d{8}$'){
                    con = con.replace('-0-', '-O-');
                }
                chrome.tabs.create({ url: keys[key].replace("{}", con) });
                break;
        }
    }
}
	

Changing Status:


const tabURL = 'https://x.xxxx.com/*';
const queryOptions = {pinned : true, url: tabURL};

document.onkeydown = function(e){
	if(e.key === '1'){
		document.getElementById("status-available").click();
		window.close();
	}
	else if(e.key === '2'){
		document.getElementById("status-busy").click();
		window.close();
	}
	else if(e.key === '3'){
		document.getElementById("status-busy-lunch").click();
		window.close();
	}
	else if(e.key === '4'){
		document.getElementById("status-offline").click();
		window.close();
	}
}

document.querySelector('#status-available').onclick = () => {
	chrome.tabs.query(queryOptions, function (tabs) {
		if (tabs && tabs[0] != null) {
			chrome.tabs.sendMessage(tabs[0].id, { method: "changeOmniStatus", status: "Available" }, function (response) { });
		}
	});
	window.close();
};

document.querySelector('#status-busy').onclick = () => {
	chrome.tabs.query(queryOptions, function (tabs) {
		if (tabs && tabs[0] != null) {
			chrome.tabs.sendMessage(tabs[0].id, { method: "changeOmniStatus", status: "Busy" }, function (response) { });
		}
	});
	window.close();
};

document.querySelector('#status-busy-lunch').onclick = () => {
	chrome.tabs.query(queryOptions, function (tabs) {
		if (tabs && tabs[0] != null) {
			chrome.tabs.sendMessage(tabs[0].id, { method: "changeOmniStatus", status: "Busy - Lunch" }, function (response) { });
		}
	});
	window.close();
};

document.querySelector('#status-offline').onclick = () => {
	chrome.tabs.query(queryOptions, function (tabs) {
		if (tabs && tabs[0] != null) {
			chrome.tabs.sendMessage(tabs[0].id, { method: "changeOmniStatus", status: "Offline" }, function (response) { });
		}
	});
	window.close();
};