Skip to content

Instantly share code, notes, and snippets.

@WrathOfZombies
Created May 25, 2021 22:04
Show Gist options
  • Save WrathOfZombies/cb28d0f978650baa7786f331f902955a to your computer and use it in GitHub Desktop.
Save WrathOfZombies/cb28d0f978650baa7786f331f902955a to your computer and use it in GitHub Desktop.
Google Docs script for Jira linking
const JIRA_URL = "https://outreach-io.atlassian.net/browse/";
// Helper to Format JIRA Tickets
function formatJira() {
// Get the current document that is being edited.
const doc = DocumentApp.getActiveDocument();
if (!doc) {
throw error("Needs an active document.");
}
const searchSpace = [];
// If you provide a selection, we'll only do the work within
// Else we are going to search everywhere.
const selection = doc.getSelection();
if (!selection) {
// Find the body and get the refrence to the text element
// Put that into our search space
const body = doc.getBody();
const textElement = body.editAsText();
const text = textElement.getText();
searchSpace.push([textElement, text]);
} else {
// Find all the ranges in our selection and add that to the
// search space with references to the textElement in each range
const ranges = selection.getRangeElements();
ranges.map((range) => {
const element = range.getElement();
const textElement = element.asText();
const text = textElement.getText();
searchSpace.push([textElement, text]);
});
}
// Process the search space
for (const [textElement, text] of searchSpace) {
// Find all matching patterns in the body
// Matches JIRA-XXXX. Creating it inline cause it's marked as global
const JIRA_TICKET_REGEX = /\[.*?-(?:\d{4,4})\]/gi;
// Depending upon the search strategy used, this is going to be
// Either one big search across the entire body - GG on large docs?
// or tiny searches across your selection - GG on Select All?
const matches = text.matchAll(JIRA_TICKET_REGEX);
for (const match of matches) {
const ticket = match[0];
const start = match.index;
const end = match.index + ticket.length - 1;
console.info(
`Found ticket: ${ticket} between start: ${start} and end: ${end}`
);
const isAlreadyLinked = textElement.getLinkUrl(start);
if (isAlreadyLinked) {
console.info(`Ticket: ${ticket} is already linked`);
continue;
}
// Create a link to the JIRA Ticket
const ticketID = ticket.replace("[", "").replace("]", "");
const url = `${JIRA_URL}${ticketID}`;
console.info(`Linking to ticket: ${ticket} to url: ${url}`);
textElement.setLinkUrl(start, end, url);
}
}
}
// Error message helper
// TODO: Prettify errors
function error(message) {
return new Error(`OTR: ${message}`);
}
function onOpen() {
const ui = DocumentApp.getUi();
ui.createMenu('OTR')
.addItem('Format JIRA', 'formatJira')
.addToUi();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment