Why does my Teams userscript have no effect?
When I paste URLs pointing to my ticketing system into other systems, I want them to look nice without a lot of manual reformatting. I have a userscript that works in GitHub taking <rootURL>/ticket/1234
and pasting it in GitHub as [#1234](<rootURL>/ticket/1234)
which GitHub renders nicely.
I want to do the same thing for Teams. The Teams app for Windows has some programmability but I can't find what I need there so I've resorted to using Teams on the web and writing another userscript. (By all means, I'm happy to hear, "The way to do that in Teams is ...." but this is the best I've come up with so far.)
Whereas GitHub messages are composed in a textarea
, Teams has a div
that it updates as you type. I have a paste handler that creates what seem to be the right DOM elements but when my function is done, I see the original, unformatted URL in the Teams message.
My userscript is below. The logging tells me its doing the right thing but my new DOM elements don't show up in the UI. Any thoughts?
// ==UserScript==
// @name Teams Trac link
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Reformat pasted link to Trac ticket to look pretty in Teams
// @author Chris Nelson, PE
// @match https://teams.microsoft.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=microsoft.com
// @grant none
// ==/UserScript==
// Handle paste event by making custom link, when appropriate.
// If handled, suppress the browser handling of the event.
function handlePaste(event) {
console.log("Handling paste");
var target = event.target;
// Get the text that the user is trying to paste
var text = (event.clipboardData || window.clipboardData).getData('text');
try {
var url = new URL(text);
if (url.pathname.startsWith('/trac/ticket')) {
console.log("Pasting a Trac ticket link: " + text);
var parts = url.pathname.split('/');
var ticketNumber = parts[3];
// Don't let the browser also paste
event.preventDefault();
// Create a link
var link = document.createElement('a');
link.innerHTML = '#' + ticketNumber;
link.href = text;
link.title = 'Trac ticket #' + ticketNumber;
// FIXME - nothing from here on works to insert the link
// Get all divs
var divs = Array.from(document.querySelectorAll('div'));
// Filter to those with an ID that starts 'new-message-'
divs = divs.filter(d => d.id.startsWith('new-message-'));
var parent = divs[0];
console.log('Before adding, div has ' + parent.childNodes.length + ' children');
parent.appendChild(link);
console.log('After adding, div has ' + parent.childNodes.length + ' children');
}
}
catch (error) {
// Nothing, just let the browser do its thing.
}
}
(function() {
console.log("Attaching paste handler");
// Intercept a paste event anywhere on the page but
// only handle it if pasting into a new message.
document.body.addEventListener('paste', (event) => {
var target = event.target;
console.log("Got paste event for " + target);
if (target.tagName.toLowerCase() == 'br'
&& target.dataset.ckeFiller == 'true') {
handlePaste(event);
}
}, false);
})();