Zendesk — Add link to Azure DevOps work item in header v1.0.1
Adds a button to the ticket header that links to the Azure DevOps work item.
Script Content
// ==UserScript==
// @name Zendesk — Add link to Azure DevOps work item in header
// @namespace http://tampermonkey.net/
// @version 1.0.1
// @description Adds a button to the ticket header that links to the Azure DevOps work item.
// @author tjhleeds using Jules
// @match https://*.zendesk.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const LOG_PREFIX = '[Zendesk to Azure DevOps Userscript]';
console.log(`${LOG_PREFIX} Script initialized`);
const AZURE_DEVOPS_SVG = `
`;
const addLink = () => {
console.log(`${LOG_PREFIX} addLink() called`);
const devopsLinkField = Array.from(document.querySelectorAll('label')).find(label => label.textContent === 'DevOps Link');
if (!devopsLinkField) {
console.log(`${LOG_PREFIX} ❌ DevOps Link field not found`);
return;
}
console.log(`${LOG_PREFIX} ✅ DevOps Link field found`);
const devopsLinkInput = devopsLinkField.nextElementSibling;
if (!devopsLinkInput || !devopsLinkInput.value) {
console.log(`${LOG_PREFIX} ❌ DevOps Link input not found or empty`, devopsLinkInput);
return;
}
console.log(`${LOG_PREFIX} ✅ DevOps Link value: ${devopsLinkInput.value}`);
const header = document.querySelector('div[data-ticket-id]');
if (!header) {
console.log(`${LOG_PREFIX} ❌ Header not found`);
return;
}
if (document.querySelector('.azure-devops-link')) {
console.log(`${LOG_PREFIX} ⏭️ Link already exists, skipping`);
return;
}
console.log(`${LOG_PREFIX} ✅ Header found, data-ticket-id: ${header.getAttribute('data-ticket-id')}`);
const firstChildOfHeader = header.firstChild;
if (!firstChildOfHeader) {
console.log(`${LOG_PREFIX} ❌ Header has no first child`);
return;
}
const targetElement = firstChildOfHeader.firstChild;
if (!targetElement) {
console.log(`${LOG_PREFIX} ❌ First child has no first child`);
return;
}
const link = document.createElement('a');
link.href = devopsLinkInput.value;
link.target = '_blank';
link.classList.add('azure-devops-link');
link.innerHTML = AZURE_DEVOPS_SVG;
firstChildOfHeader.insertBefore(link, targetElement);
firstChildOfHeader.style.display = 'flex';
firstChildOfHeader.style.alignItems = 'center';
targetElement.style.marginLeft = '10px';
console.log(`${LOG_PREFIX} 🎉 Link successfully added to header!`);
};
let mutationCount = 0;
const observer = new MutationObserver(() => {
mutationCount++;
console.log(`${LOG_PREFIX} Mutation #${mutationCount} detected, calling addLink()`);
addLink();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
console.log(`${LOG_PREFIX} MutationObserver started, watching document.body`);
})();